summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStephen D. Huston <shuston@apache.org>2009-03-25 23:44:30 +0000
committerStephen D. Huston <shuston@apache.org>2009-03-25 23:44:30 +0000
commit67d330f235362bf622b95f8c4d14321272a44ba7 (patch)
tree82153e6fd6c1c77e9defc80cb2e6b34d23de25cf
parentb51fd45a4ed81bee144c22c2a57fc0e882d44149 (diff)
downloadqpid-python-67d330f235362bf622b95f8c4d14321272a44ba7.tar.gz
Merge from trunk tag to-cmake-25mar09 (r758432)
git-svn-id: https://svn.apache.org/repos/asf/qpid/branches/cmake@758465 13f79535-47bb-0310-9956-ffa450edef68
-rw-r--r--qpid/cpp/configure.ac61
-rw-r--r--qpid/cpp/docs/api/developer.doxygen.in6
-rw-r--r--qpid/cpp/docs/api/user.doxygen.in2
-rw-r--r--qpid/cpp/etc/sasl2/qpidd.conf4
-rw-r--r--qpid/cpp/examples/Makefile.am13
-rw-r--r--qpid/cpp/examples/direct/Makefile.am1
-rw-r--r--qpid/cpp/examples/direct/direct_declare_queues.vcproj374
-rw-r--r--qpid/cpp/examples/direct/direct_direct_producer.vcproj374
-rw-r--r--qpid/cpp/examples/direct/direct_listener.vcproj374
-rw-r--r--qpid/cpp/examples/direct/direct_producer.cpp1
-rw-r--r--qpid/cpp/examples/direct/listener.cpp1
-rw-r--r--qpid/cpp/examples/examples.sln213
-rw-r--r--qpid/cpp/examples/failover/Makefile.am1
-rw-r--r--qpid/cpp/examples/failover/failover_declare_queues.vcproj374
-rw-r--r--qpid/cpp/examples/failover/failover_replaying_sender.vcproj374
-rw-r--r--qpid/cpp/examples/failover/failover_resuming_receiver.vcproj374
-rw-r--r--qpid/cpp/examples/fanout/Makefile.am1
-rw-r--r--qpid/cpp/examples/fanout/fanout_fanout_producer.vcproj374
-rw-r--r--qpid/cpp/examples/fanout/fanout_listener.vcproj374
-rw-r--r--qpid/cpp/examples/fanout/fanout_producer.cpp1
-rw-r--r--qpid/cpp/examples/fanout/listener.cpp1
-rw-r--r--qpid/cpp/examples/makedist.mk21
-rw-r--r--qpid/cpp/examples/pub-sub/Makefile.am1
-rw-r--r--qpid/cpp/examples/pub-sub/pub_sub_topic_listener.vcproj374
-rw-r--r--qpid/cpp/examples/pub-sub/pub_sub_topic_publisher.vcproj374
-rw-r--r--qpid/cpp/examples/pub-sub/topic_listener.cpp1
-rw-r--r--qpid/cpp/examples/pub-sub/topic_publisher.cpp1
-rw-r--r--qpid/cpp/examples/qmf-console/Makefile.am2
-rw-r--r--qpid/cpp/examples/qmf-console/ping.cpp3
-rw-r--r--qpid/cpp/examples/qmf-console/printevents.cpp2
-rw-r--r--qpid/cpp/examples/qmf-console/qmf_console_console.vcproj374
-rw-r--r--qpid/cpp/examples/qmf-console/qmf_console_ping.vcproj374
-rw-r--r--qpid/cpp/examples/qmf-console/qmf_console_printevents.vcproj374
-rw-r--r--qpid/cpp/examples/qmf-console/qmf_console_queuestats.vcproj374
-rw-r--r--qpid/cpp/examples/qmf-console/queuestats.cpp3
-rw-r--r--qpid/cpp/examples/request-response/Makefile.am1
-rw-r--r--qpid/cpp/examples/request-response/client.cpp1
-rw-r--r--qpid/cpp/examples/request-response/request_response_client.vcproj374
-rw-r--r--qpid/cpp/examples/request-response/request_response_server.vcproj374
-rw-r--r--qpid/cpp/examples/request-response/server.cpp1
-rw-r--r--qpid/cpp/examples/tradedemo/Makefile.am1
-rw-r--r--qpid/cpp/examples/tradedemo/topic_listener.cpp1
-rw-r--r--qpid/cpp/examples/tradedemo/topic_publisher.cpp2
-rw-r--r--qpid/cpp/examples/tradedemo/tradedemo_declare_queues.vcproj374
-rw-r--r--qpid/cpp/examples/tradedemo/tradedemo_topic_listener.vcproj374
-rw-r--r--qpid/cpp/examples/tradedemo/tradedemo_topic_publisher.vcproj374
-rw-r--r--qpid/cpp/examples/xml-exchange/Makefile.am1
-rwxr-xr-xqpid/cpp/managementgen/qmf-gen8
-rwxr-xr-xqpid/cpp/managementgen/qmfgen/generate.py95
-rwxr-xr-xqpid/cpp/rubygen/framing.0-10/MethodBodyDefaultVisitor.rb3
-rwxr-xr-xqpid/cpp/rubygen/framing.0-10/OperationsInvoker.rb3
-rwxr-xr-xqpid/cpp/rubygen/framing.0-10/Proxy.rb6
-rw-r--r--qpid/cpp/rubygen/framing.0-10/Session.rb10
-rwxr-xr-xqpid/cpp/rubygen/framing.0-10/constants.rb3
-rw-r--r--qpid/cpp/rubygen/framing.0-10/structs.rb27
-rwxr-xr-xqpid/cpp/rubygen/generate18
-rw-r--r--qpid/cpp/src/Makefile.am18
-rw-r--r--qpid/cpp/src/acl.mk4
-rw-r--r--qpid/cpp/src/broker.vcproj89
-rw-r--r--qpid/cpp/src/client.vcproj104
-rw-r--r--qpid/cpp/src/cluster.mk11
-rw-r--r--qpid/cpp/src/common.vcproj107
-rw-r--r--qpid/cpp/src/qmfc.mk2
-rw-r--r--qpid/cpp/src/qmfconsole.vcproj98
-rw-r--r--qpid/cpp/src/qpid.sln16
-rwxr-xr-xqpid/cpp/src/qpid/Address.h6
-rw-r--r--qpid/cpp/src/qpid/CommonImportExport.h33
-rw-r--r--qpid/cpp/src/qpid/DataDir.h5
-rw-r--r--qpid/cpp/src/qpid/Exception.h16
-rw-r--r--qpid/cpp/src/qpid/Modules.h7
-rw-r--r--qpid/cpp/src/qpid/Options.h26
-rw-r--r--qpid/cpp/src/qpid/Plugin.h19
-rw-r--r--qpid/cpp/src/qpid/SessionId.cpp2
-rw-r--r--qpid/cpp/src/qpid/SessionId.h11
-rw-r--r--qpid/cpp/src/qpid/SessionState.cpp14
-rw-r--r--qpid/cpp/src/qpid/SessionState.h76
-rw-r--r--qpid/cpp/src/qpid/StringUtils.h6
-rw-r--r--qpid/cpp/src/qpid/Url.h17
-rwxr-xr-xqpid/cpp/src/qpid/Version.h2
-rw-r--r--qpid/cpp/src/qpid/acl/AclPlugin.cpp13
-rw-r--r--qpid/cpp/src/qpid/agent/ManagementAgentImpl.cpp8
-rw-r--r--qpid/cpp/src/qpid/amqp_0_10/Connection.h5
-rw-r--r--qpid/cpp/src/qpid/amqp_0_10/SessionHandler.cpp1
-rw-r--r--qpid/cpp/src/qpid/amqp_0_10/SessionHandler.h55
-rw-r--r--qpid/cpp/src/qpid/assert.cpp2
-rw-r--r--qpid/cpp/src/qpid/broker/Bridge.cpp50
-rw-r--r--qpid/cpp/src/qpid/broker/Bridge.h5
-rw-r--r--qpid/cpp/src/qpid/broker/Broker.cpp5
-rw-r--r--qpid/cpp/src/qpid/broker/Broker.h18
-rw-r--r--qpid/cpp/src/qpid/broker/BrokerImportExport.h33
-rw-r--r--qpid/cpp/src/qpid/broker/BrokerSingleton.h3
-rw-r--r--qpid/cpp/src/qpid/broker/Connection.cpp14
-rw-r--r--qpid/cpp/src/qpid/broker/Connection.h7
-rw-r--r--qpid/cpp/src/qpid/broker/ConnectionHandler.cpp56
-rw-r--r--qpid/cpp/src/qpid/broker/ConnectionHandler.h12
-rw-r--r--qpid/cpp/src/qpid/broker/ConnectionState.h22
-rw-r--r--qpid/cpp/src/qpid/broker/Daemon.h4
-rw-r--r--qpid/cpp/src/qpid/broker/DeliverableMessage.h9
-rw-r--r--qpid/cpp/src/qpid/broker/DeliveryRecord.h20
-rw-r--r--qpid/cpp/src/qpid/broker/DirectExchange.h24
-rw-r--r--qpid/cpp/src/qpid/broker/DtxBuffer.h7
-rw-r--r--qpid/cpp/src/qpid/broker/DtxWorkRecord.h14
-rw-r--r--qpid/cpp/src/qpid/broker/Exchange.cpp8
-rw-r--r--qpid/cpp/src/qpid/broker/Exchange.h12
-rw-r--r--qpid/cpp/src/qpid/broker/ExchangeRegistry.h17
-rw-r--r--qpid/cpp/src/qpid/broker/ExpiryPolicy.h7
-rw-r--r--qpid/cpp/src/qpid/broker/FanOutExchange.h25
-rw-r--r--qpid/cpp/src/qpid/broker/HeadersExchange.cpp45
-rw-r--r--qpid/cpp/src/qpid/broker/HeadersExchange.h27
-rw-r--r--qpid/cpp/src/qpid/broker/IncompleteMessageList.h9
-rw-r--r--qpid/cpp/src/qpid/broker/Link.cpp43
-rw-r--r--qpid/cpp/src/qpid/broker/Link.h1
-rw-r--r--qpid/cpp/src/qpid/broker/LinkRegistry.cpp63
-rw-r--r--qpid/cpp/src/qpid/broker/LinkRegistry.h2
-rw-r--r--qpid/cpp/src/qpid/broker/Message.cpp6
-rw-r--r--qpid/cpp/src/qpid/broker/Message.h24
-rw-r--r--qpid/cpp/src/qpid/broker/MessageBuilder.h8
-rw-r--r--qpid/cpp/src/qpid/broker/NullMessageStore.h79
-rw-r--r--qpid/cpp/src/qpid/broker/PersistableMessage.h19
-rw-r--r--qpid/cpp/src/qpid/broker/Queue.cpp48
-rw-r--r--qpid/cpp/src/qpid/broker/Queue.h58
-rw-r--r--qpid/cpp/src/qpid/broker/QueueCleaner.h5
-rw-r--r--qpid/cpp/src/qpid/broker/QueueEvents.cpp19
-rw-r--r--qpid/cpp/src/qpid/broker/QueueEvents.h21
-rw-r--r--qpid/cpp/src/qpid/broker/QueuePolicy.cpp28
-rw-r--r--qpid/cpp/src/qpid/broker/QueuePolicy.h26
-rw-r--r--qpid/cpp/src/qpid/broker/QueueRegistry.cpp10
-rw-r--r--qpid/cpp/src/qpid/broker/QueueRegistry.h23
-rw-r--r--qpid/cpp/src/qpid/broker/RecoveryManagerImpl.cpp3
-rw-r--r--qpid/cpp/src/qpid/broker/RetryList.h7
-rw-r--r--qpid/cpp/src/qpid/broker/SaslAuthenticator.cpp28
-rw-r--r--qpid/cpp/src/qpid/broker/SemanticState.cpp22
-rw-r--r--qpid/cpp/src/qpid/broker/SessionAdapter.cpp4
-rw-r--r--qpid/cpp/src/qpid/broker/SessionHandler.cpp25
-rw-r--r--qpid/cpp/src/qpid/broker/SessionHandler.h23
-rw-r--r--qpid/cpp/src/qpid/broker/SessionState.cpp30
-rw-r--r--qpid/cpp/src/qpid/broker/SessionState.h13
-rw-r--r--qpid/cpp/src/qpid/broker/Timer.h11
-rw-r--r--qpid/cpp/src/qpid/broker/TopicExchange.h30
-rw-r--r--qpid/cpp/src/qpid/broker/TxAccept.cpp4
-rw-r--r--qpid/cpp/src/qpid/broker/TxBuffer.h11
-rw-r--r--qpid/cpp/src/qpid/broker/TxPublish.h13
-rw-r--r--qpid/cpp/src/qpid/client/ClientImportExport.h33
-rw-r--r--qpid/cpp/src/qpid/client/Connection.h27
-rw-r--r--qpid/cpp/src/qpid/client/ConnectionHandler.cpp7
-rw-r--r--qpid/cpp/src/qpid/client/ConnectionImpl.cpp3
-rw-r--r--qpid/cpp/src/qpid/client/ConnectionSettings.h7
-rw-r--r--qpid/cpp/src/qpid/client/Connector.cpp51
-rw-r--r--qpid/cpp/src/qpid/client/Dispatcher.cpp3
-rw-r--r--qpid/cpp/src/qpid/client/FailoverManager.cpp11
-rw-r--r--qpid/cpp/src/qpid/client/FailoverManager.h11
-rw-r--r--qpid/cpp/src/qpid/client/Future.h7
-rw-r--r--qpid/cpp/src/qpid/client/FutureResult.h4
-rw-r--r--qpid/cpp/src/qpid/client/Handle.h20
-rw-r--r--qpid/cpp/src/qpid/client/LocalQueue.h15
-rw-r--r--qpid/cpp/src/qpid/client/Message.h19
-rw-r--r--qpid/cpp/src/qpid/client/MessageListener.h3
-rw-r--r--qpid/cpp/src/qpid/client/MessageReplayTracker.h16
-rw-r--r--qpid/cpp/src/qpid/client/QueueOptions.h46
-rw-r--r--qpid/cpp/src/qpid/client/SessionBase_0_10.h31
-rw-r--r--qpid/cpp/src/qpid/client/SessionImpl.cpp4
-rw-r--r--qpid/cpp/src/qpid/client/SslConnector.cpp2
-rw-r--r--qpid/cpp/src/qpid/client/Subscription.h41
-rw-r--r--qpid/cpp/src/qpid/client/SubscriptionImpl.h37
-rw-r--r--qpid/cpp/src/qpid/client/SubscriptionManager.h49
-rw-r--r--qpid/cpp/src/qpid/client/windows/SaslFactory.cpp139
-rw-r--r--qpid/cpp/src/qpid/cluster/Cluster.cpp235
-rw-r--r--qpid/cpp/src/qpid/cluster/Cluster.h123
-rw-r--r--qpid/cpp/src/qpid/cluster/ClusterPlugin.cpp1
-rw-r--r--qpid/cpp/src/qpid/cluster/ClusterSettings.h2
-rw-r--r--qpid/cpp/src/qpid/cluster/Connection.cpp67
-rw-r--r--qpid/cpp/src/qpid/cluster/Connection.h26
-rw-r--r--qpid/cpp/src/qpid/cluster/ConnectionCodec.cpp15
-rw-r--r--qpid/cpp/src/qpid/cluster/ConnectionCodec.h4
-rw-r--r--qpid/cpp/src/qpid/cluster/ConnectionDecoder.cpp57
-rw-r--r--qpid/cpp/src/qpid/cluster/ConnectionMap.cpp96
-rw-r--r--qpid/cpp/src/qpid/cluster/ConnectionMap.h88
-rw-r--r--qpid/cpp/src/qpid/cluster/Cpg.cpp39
-rw-r--r--qpid/cpp/src/qpid/cluster/Cpg.h2
-rw-r--r--qpid/cpp/src/qpid/cluster/Decoder.cpp47
-rw-r--r--qpid/cpp/src/qpid/cluster/Decoder.h32
-rw-r--r--qpid/cpp/src/qpid/cluster/Event.cpp31
-rw-r--r--qpid/cpp/src/qpid/cluster/Event.h19
-rw-r--r--qpid/cpp/src/qpid/cluster/EventFrame.cpp10
-rw-r--r--qpid/cpp/src/qpid/cluster/EventFrame.h15
-rw-r--r--qpid/cpp/src/qpid/cluster/ExpiryPolicy.cpp50
-rw-r--r--qpid/cpp/src/qpid/cluster/ExpiryPolicy.h24
-rw-r--r--qpid/cpp/src/qpid/cluster/LockedConnectionMap.h (renamed from qpid/cpp/src/qpid/cluster/ConnectionDecoder.h)53
-rw-r--r--qpid/cpp/src/qpid/cluster/McastFrameHandler.h (renamed from qpid/cpp/src/qpid/sys/posix/PollableCondition.h)40
-rw-r--r--qpid/cpp/src/qpid/cluster/Multicaster.cpp6
-rw-r--r--qpid/cpp/src/qpid/cluster/Multicaster.h1
-rw-r--r--qpid/cpp/src/qpid/cluster/OutputInterceptor.cpp11
-rw-r--r--qpid/cpp/src/qpid/cluster/PollableQueue.h2
-rw-r--r--qpid/cpp/src/qpid/cluster/UpdateClient.cpp93
-rw-r--r--qpid/cpp/src/qpid/cluster/UpdateClient.h11
-rw-r--r--qpid/cpp/src/qpid/cluster/UpdateExchange.h45
-rw-r--r--qpid/cpp/src/qpid/cluster/types.h11
-rw-r--r--qpid/cpp/src/qpid/console/Agent.h5
-rw-r--r--qpid/cpp/src/qpid/console/Broker.h12
-rw-r--r--qpid/cpp/src/qpid/console/ClassKey.cpp1
-rw-r--r--qpid/cpp/src/qpid/console/ClassKey.h5
-rw-r--r--qpid/cpp/src/qpid/console/ConsoleImportExport.h33
-rw-r--r--qpid/cpp/src/qpid/console/ConsoleListener.h3
-rw-r--r--qpid/cpp/src/qpid/console/Event.h33
-rw-r--r--qpid/cpp/src/qpid/console/Object.h64
-rw-r--r--qpid/cpp/src/qpid/console/ObjectId.h5
-rw-r--r--qpid/cpp/src/qpid/console/Package.h1
-rw-r--r--qpid/cpp/src/qpid/console/SequenceManager.h5
-rw-r--r--qpid/cpp/src/qpid/console/SessionManager.h32
-rw-r--r--qpid/cpp/src/qpid/framing/AMQBody.h5
-rw-r--r--qpid/cpp/src/qpid/framing/AMQContentBody.h23
-rw-r--r--qpid/cpp/src/qpid/framing/AMQFrame.cpp2
-rw-r--r--qpid/cpp/src/qpid/framing/AMQFrame.h25
-rw-r--r--qpid/cpp/src/qpid/framing/AMQHeaderBody.h13
-rw-r--r--qpid/cpp/src/qpid/framing/AMQHeartbeatBody.h5
-rw-r--r--qpid/cpp/src/qpid/framing/AMQMethodBody.h4
-rw-r--r--qpid/cpp/src/qpid/framing/AccumulatedAck.h17
-rw-r--r--qpid/cpp/src/qpid/framing/Array.h51
-rw-r--r--qpid/cpp/src/qpid/framing/Buffer.h91
-rw-r--r--qpid/cpp/src/qpid/framing/FieldTable.h67
-rw-r--r--qpid/cpp/src/qpid/framing/FieldValue.h27
-rw-r--r--qpid/cpp/src/qpid/framing/FrameDecoder.cpp12
-rw-r--r--qpid/cpp/src/qpid/framing/FrameDecoder.h9
-rw-r--r--qpid/cpp/src/qpid/framing/FrameSet.h19
-rw-r--r--qpid/cpp/src/qpid/framing/ProtocolInitiation.h15
-rw-r--r--qpid/cpp/src/qpid/framing/ProtocolVersion.h17
-rw-r--r--qpid/cpp/src/qpid/framing/Proxy.h18
-rw-r--r--qpid/cpp/src/qpid/framing/SendContent.h5
-rw-r--r--qpid/cpp/src/qpid/framing/SequenceNumber.h27
-rw-r--r--qpid/cpp/src/qpid/framing/SequenceNumberSet.h7
-rw-r--r--qpid/cpp/src/qpid/framing/SequenceSet.h17
-rw-r--r--qpid/cpp/src/qpid/framing/StructHelper.h1
-rw-r--r--qpid/cpp/src/qpid/framing/TransferContent.h27
-rw-r--r--qpid/cpp/src/qpid/framing/Uuid.h14
-rw-r--r--qpid/cpp/src/qpid/log/Logger.h31
-rw-r--r--qpid/cpp/src/qpid/log/Options.h7
-rw-r--r--qpid/cpp/src/qpid/log/OstreamOutput.h4
-rw-r--r--qpid/cpp/src/qpid/log/Selector.cpp1
-rw-r--r--qpid/cpp/src/qpid/log/Selector.h7
-rw-r--r--qpid/cpp/src/qpid/log/Statement.h6
-rw-r--r--qpid/cpp/src/qpid/log/posix/SinkOptions.cpp6
-rw-r--r--qpid/cpp/src/qpid/log/windows/SinkOptions.h8
-rw-r--r--qpid/cpp/src/qpid/management/Manageable.h3
-rw-r--r--qpid/cpp/src/qpid/management/ManagementBroker.cpp12
-rw-r--r--qpid/cpp/src/qpid/management/ManagementBroker.h1
-rw-r--r--qpid/cpp/src/qpid/management/ManagementObject.h31
-rw-r--r--qpid/cpp/src/qpid/replication/ReplicatingEventListener.cpp77
-rw-r--r--qpid/cpp/src/qpid/replication/ReplicatingEventListener.h7
-rw-r--r--qpid/cpp/src/qpid/replication/ReplicationExchange.cpp45
-rw-r--r--qpid/cpp/src/qpid/replication/ReplicationExchange.h2
-rw-r--r--qpid/cpp/src/qpid/sys/AggregateOutput.h15
-rw-r--r--qpid/cpp/src/qpid/sys/AsynchIO.h12
-rw-r--r--qpid/cpp/src/qpid/sys/AsynchIOHandler.cpp12
-rw-r--r--qpid/cpp/src/qpid/sys/AsynchIOHandler.h27
-rw-r--r--qpid/cpp/src/qpid/sys/Codec.h4
-rw-r--r--qpid/cpp/src/qpid/sys/ConnectionOutputHandlerPtr.h2
-rw-r--r--qpid/cpp/src/qpid/sys/CopyOnWriteArray.h2
-rw-r--r--qpid/cpp/src/qpid/sys/DispatchHandle.cpp129
-rw-r--r--qpid/cpp/src/qpid/sys/DispatchHandle.h29
-rw-r--r--qpid/cpp/src/qpid/sys/Dispatcher.h7
-rw-r--r--qpid/cpp/src/qpid/sys/IOHandle.h6
-rw-r--r--qpid/cpp/src/qpid/sys/PollableCondition.h55
-rw-r--r--qpid/cpp/src/qpid/sys/PollableQueue.h48
-rw-r--r--qpid/cpp/src/qpid/sys/Poller.h33
-rw-r--r--qpid/cpp/src/qpid/sys/Runnable.h3
-rw-r--r--qpid/cpp/src/qpid/sys/Shlib.h11
-rw-r--r--qpid/cpp/src/qpid/sys/Socket.h26
-rw-r--r--qpid/cpp/src/qpid/sys/StrError.h3
-rw-r--r--qpid/cpp/src/qpid/sys/SystemInfo.h18
-rw-r--r--qpid/cpp/src/qpid/sys/Thread.h15
-rw-r--r--qpid/cpp/src/qpid/sys/Time.h24
-rw-r--r--qpid/cpp/src/qpid/sys/Timer.h28
-rw-r--r--qpid/cpp/src/qpid/sys/alloca.h39
-rw-r--r--qpid/cpp/src/qpid/sys/epoll/EpollPoller.cpp111
-rw-r--r--qpid/cpp/src/qpid/sys/posix/AsynchIO.cpp4
-rw-r--r--qpid/cpp/src/qpid/sys/posix/PollableCondition.cpp119
-rw-r--r--qpid/cpp/src/qpid/sys/posix/Socket.cpp43
-rwxr-xr-xqpid/cpp/src/qpid/sys/posix/SystemInfo.cpp24
-rw-r--r--qpid/cpp/src/qpid/sys/solaris/ECFPoller.cpp244
-rwxr-xr-xqpid/cpp/src/qpid/sys/solaris/SystemInfo.cpp123
-rw-r--r--qpid/cpp/src/qpid/sys/ssl/SslIo.cpp2
-rw-r--r--qpid/cpp/src/qpid/sys/ssl/SslSocket.cpp4
-rw-r--r--qpid/cpp/src/qpid/sys/ssl/SslSocket.h2
-rw-r--r--qpid/cpp/src/qpid/sys/windows/AsynchIO.cpp22
-rwxr-xr-xqpid/cpp/src/qpid/sys/windows/IntegerTypes.h2
-rw-r--r--qpid/cpp/src/qpid/sys/windows/PollableCondition.cpp125
-rwxr-xr-xqpid/cpp/src/qpid/sys/windows/Socket.cpp4
-rwxr-xr-xqpid/cpp/src/qpid/sys/windows/SystemInfo.cpp38
-rw-r--r--qpid/cpp/src/qpid/sys/windows/uuid.h13
-rw-r--r--qpid/cpp/src/qpid/xml/XmlExchange.cpp128
-rw-r--r--qpid/cpp/src/qpid/xml/XmlExchange.h5
-rw-r--r--qpid/cpp/src/replication.mk6
-rw-r--r--qpid/cpp/src/tests/ClientSessionTest.cpp22
-rw-r--r--qpid/cpp/src/tests/ClusterFixture.cpp2
-rw-r--r--qpid/cpp/src/tests/DispatcherTest.cpp79
-rw-r--r--qpid/cpp/src/tests/FieldTable.cpp2
-rw-r--r--qpid/cpp/src/tests/ForkedBroker.cpp7
-rw-r--r--qpid/cpp/src/tests/FrameDecoder.cpp73
-rw-r--r--qpid/cpp/src/tests/Makefile.am16
-rw-r--r--qpid/cpp/src/tests/MessageTest.cpp5
-rw-r--r--qpid/cpp/src/tests/MessageUtils.h2
-rw-r--r--qpid/cpp/src/tests/PollerTest.cpp2
-rw-r--r--qpid/cpp/src/tests/ProxyTest.cpp1
-rw-r--r--qpid/cpp/src/tests/QueueEvents.cpp7
-rw-r--r--qpid/cpp/src/tests/QueuePolicyTest.cpp9
-rw-r--r--qpid/cpp/src/tests/ReplicationTest.cpp129
-rw-r--r--qpid/cpp/src/tests/SocketProxy.h2
-rw-r--r--qpid/cpp/src/tests/TimerTest.cpp4
-rw-r--r--qpid/cpp/src/tests/Uuid.cpp2
-rw-r--r--qpid/cpp/src/tests/client_test.vcproj34
-rw-r--r--qpid/cpp/src/tests/cluster.mk5
-rw-r--r--qpid/cpp/src/tests/cluster_test.cpp191
-rwxr-xr-xqpid/cpp/src/tests/clustered_replication_test127
-rw-r--r--qpid/cpp/src/tests/consume.vcproj34
-rw-r--r--qpid/cpp/src/tests/echotest.vcproj34
-rw-r--r--qpid/cpp/src/tests/failover_soak.cpp338
-rwxr-xr-xqpid/cpp/src/tests/federated_cluster_test47
-rwxr-xr-xqpid/cpp/src/tests/federated_cluster_test_with_node_failure23
-rw-r--r--qpid/cpp/src/tests/header_test.vcproj34
-rw-r--r--qpid/cpp/src/tests/latencytest.vcproj34
-rw-r--r--qpid/cpp/src/tests/logging.cpp16
-rw-r--r--qpid/cpp/src/tests/perftest.cpp13
-rw-r--r--qpid/cpp/src/tests/perftest.vcproj34
-rw-r--r--qpid/cpp/src/tests/publish.vcproj34
-rw-r--r--qpid/cpp/src/tests/receiver.cpp18
-rw-r--r--qpid/cpp/src/tests/receiver.vcproj34
-rw-r--r--qpid/cpp/src/tests/replaying_sender.cpp4
-rwxr-xr-xqpid/cpp/src/tests/replication_test40
-rw-r--r--qpid/cpp/src/tests/resuming_receiver.cpp19
-rwxr-xr-xqpid/cpp/src/tests/run_failover_soak12
-rwxr-xr-xqpid/cpp/src/tests/run_header_test3
-rw-r--r--qpid/cpp/src/tests/sender.cpp28
-rw-r--r--qpid/cpp/src/tests/sender.vcproj34
-rw-r--r--qpid/cpp/src/tests/shlibtest.vcproj91
-rwxr-xr-xqpid/cpp/src/tests/ssl_test3
-rwxr-xr-xqpid/cpp/src/tests/start_cluster3
-rw-r--r--qpid/cpp/src/tests/tests.sln290
-rw-r--r--qpid/cpp/src/tests/topic_listener.cpp3
-rw-r--r--qpid/cpp/src/tests/topic_listener.vcproj34
-rw-r--r--qpid/cpp/src/tests/topic_publisher.vcproj34
-rw-r--r--qpid/cpp/src/tests/txjob.vcproj34
-rw-r--r--qpid/cpp/src/tests/txshift.cpp5
-rw-r--r--qpid/cpp/src/tests/txshift.vcproj34
-rw-r--r--qpid/cpp/src/tests/txtest.vcproj34
-rw-r--r--qpid/cpp/src/tests/unit_test.h9
-rw-r--r--qpid/cpp/src/tests/unit_test.vcproj112
-rw-r--r--qpid/cpp/xml/cluster.xml7
-rw-r--r--qpid/dotnet/client-010/default.build2
-rw-r--r--qpid/dotnet/default.build2
-rw-r--r--qpid/java/010ExcludeList2
-rw-r--r--qpid/java/08ExcludeList1
-rw-r--r--qpid/java/08ExcludeList-nonvm1
-rw-r--r--qpid/java/ExcludeList12
-rw-r--r--qpid/java/broker/bin/create-example-ssl-stores.bat36
-rw-r--r--qpid/java/broker/bin/create-example-ssl-stores.sh38
-rw-r--r--qpid/java/broker/etc/config.xml1
-rw-r--r--qpid/java/broker/etc/debug.log4j.xml26
-rw-r--r--qpid/java/broker/etc/log4j.xml24
-rw-r--r--qpid/java/broker/etc/persistent_config.xml1
-rw-r--r--qpid/java/broker/etc/transient_config.xml1
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/AMQBrokerManagerMBean.java4
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/AMQChannel.java40
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/ExtractResendAndRequeue.java4
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/Main.java213
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/RequiredDeliveryException.java9
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/ack/TxAck.java23
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/ack/UnacknowledgedMessageMapImpl.java12
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/Configurator.java118
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/ExchangeConfiguration.java (renamed from qpid/java/broker/src/test/java/org/apache/qpid/server/store/TestMemoryMessageStore.java)47
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/QueueConfiguration.java124
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/SecurityConfiguration.java41
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/ServerConfiguration.java514
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/VirtualHostConfiguration.java320
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/management/ConfigurationManagement.java43
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/management/ConfigurationManagementMBean.java (renamed from qpid/java/broker/src/main/java/org/apache/qpid/server/queue/AsyncDeliveryConfig.java)39
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/exchange/AbstractExchange.java8
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/exchange/DefaultExchangeFactory.java7
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/exchange/DirectExchange.java6
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/exchange/ExchangeFactory.java3
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/exchange/ManagedExchange.java1
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/flow/BytesOnlyCreditManager.java6
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/flow/FlowCreditManager.java3
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/flow/LimitlessCreditManager.java4
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/flow/MessageAndBytesCreditManager.java6
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/flow/MessageOnlyCreditManager.java4
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/flow/Pre0_10CreditManager.java12
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/handler/BasicGetMethodHandler.java6
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/handler/BasicRejectMethodHandler.java22
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/handler/ConnectionSecureOkMethodHandler.java12
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/handler/ConnectionStartOkMethodHandler.java21
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/handler/QueueDeclareHandler.java26
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/logging/management/LoggingManagement.java129
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/logging/management/LoggingManagementMBean.java667
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/management/AMQManagedObject.java4
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/management/DefaultManagedObject.java11
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/management/JMXManagedObjectRegistry.java302
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/management/MBeanInvocationHandlerImpl.java44
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/management/ManagedBroker.java4
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/plugins/PluginManager.java4
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/protocol/AMQMinaProtocolSession.java2
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/protocol/AMQPFastProtocolHandler.java60
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/protocol/AMQProtocolSessionMBean.java4
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/protocol/HeartbeatConfig.java67
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/protocol/ManagedConnection.java1
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/queue/AMQMessage.java47
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/queue/AMQMessageHandle.java75
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/queue/AMQPriorityQueue.java10
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/queue/AMQQueue.java25
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/queue/AMQQueueFactory.java116
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/queue/AMQQueueMBean.java50
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/queue/FileQueueBackingStore.java380
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/queue/FileQueueBackingStoreFactory.java166
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/queue/FlowableBaseQueueEntryList.java485
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/queue/IncomingMessage.java20
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/queue/ManagedQueue.java73
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/queue/MessageFactory.java10
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/queue/NotificationCheck.java16
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/queue/PersistentAMQMessage.java17
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/queue/PriorityQueueEntryList.java466
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/queue/PriorityQueueList.java160
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/queue/QueueBackingStore.java64
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/queue/QueueBackingStoreFactory.java32
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/queue/QueueEntry.java74
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/queue/QueueEntryImpl.java322
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/queue/QueueEntryList.java70
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/queue/SimpleAMQQueue.java234
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/queue/SimpleQueueEntryList.java17
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/queue/TransientAMQMessage.java239
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/queue/UnableToFlowMessageException.java29
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/queue/UnableToRecoverMessageException.java29
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/registry/ApplicationRegistry.java57
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/registry/ConfigurationFileApplicationRegistry.java75
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/registry/IApplicationRegistry.java18
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/routing/RoutingTable.java3
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/security/access/ACLManager.java15
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/security/access/ACLPlugin.java3
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/security/access/ACLPluginFactory.java3
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/security/access/management/AMQUserManagementMBean.java170
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/security/access/management/UserManagement.java3
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/security/access/plugins/LegacyAccessPlugin.java71
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/security/access/plugins/network/FirewallFactory.java3
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/security/access/plugins/network/FirewallPlugin.java102
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/Base64MD5PasswordFilePrincipalDatabase.java49
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/ConfigurationFilePrincipalDatabaseManager.java33
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/HashedUser.java43
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/PlainPasswordFilePrincipalDatabase.java334
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/PlainUser.java106
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/PrincipalDatabaseManager.java3
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/PropertiesPrincipalDatabaseManager.java6
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/PrincipalDatabaseAuthenticationManager.java15
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/rmi/RMIPasswordAuthenticator.java81
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/store/DerbyMessageStore.java8
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/store/MemoryMessageStore.java57
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/subscription/SubscriptionImpl.java15
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/transactionlog/TransactionLog.java15
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/transport/ConnectorConfiguration.java118
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/txn/LocalTransactionalContext.java8
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/txn/NonTransactionalContext.java36
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/util/NullApplicationRegistry.java18
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/virtualhost/ManagedVirtualHost.java1
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/virtualhost/VirtualHost.java349
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/tools/messagestore/commands/Move.java2
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/tools/messagestore/commands/Show.java2
-rw-r--r--qpid/java/broker/src/test/java/org/apache/qpid/server/ExtractResendAndRequeueTest.java9
-rw-r--r--qpid/java/broker/src/test/java/org/apache/qpid/server/ack/TxAckTest.java77
-rw-r--r--qpid/java/broker/src/test/java/org/apache/qpid/server/configuration/ServerConfigurationTest.java849
-rw-r--r--qpid/java/broker/src/test/java/org/apache/qpid/server/configuration/VirtualHostConfigurationTest.java84
-rw-r--r--qpid/java/broker/src/test/java/org/apache/qpid/server/exchange/AbstractHeadersExchangeTestBase.java36
-rw-r--r--qpid/java/broker/src/test/java/org/apache/qpid/server/exchange/DestWildExchangeTest.java26
-rw-r--r--qpid/java/broker/src/test/java/org/apache/qpid/server/filter/PropertyExpressionTest.java8
-rw-r--r--qpid/java/broker/src/test/java/org/apache/qpid/server/logging/management/LoggingManagementMBeanTest.java413
-rw-r--r--qpid/java/broker/src/test/java/org/apache/qpid/server/queue/AMQPriorityQueueTest.java121
-rw-r--r--qpid/java/broker/src/test/java/org/apache/qpid/server/queue/AMQQueueAlertTest.java23
-rw-r--r--qpid/java/broker/src/test/java/org/apache/qpid/server/queue/AMQQueueFactoryPriorityTest.java70
-rw-r--r--qpid/java/broker/src/test/java/org/apache/qpid/server/queue/AMQQueueFactoryTest.java40
-rw-r--r--qpid/java/broker/src/test/java/org/apache/qpid/server/queue/AMQQueueMBeanTest.java6
-rw-r--r--qpid/java/broker/src/test/java/org/apache/qpid/server/queue/AMQQueueThreadPoolTest.java98
-rw-r--r--qpid/java/broker/src/test/java/org/apache/qpid/server/queue/AckTest.java17
-rw-r--r--qpid/java/broker/src/test/java/org/apache/qpid/server/queue/FileQueueBackingStoreTest.java223
-rw-r--r--qpid/java/broker/src/test/java/org/apache/qpid/server/queue/MessageFactoryRecoveryTest.java15
-rw-r--r--qpid/java/broker/src/test/java/org/apache/qpid/server/queue/MockAMQMessage.java18
-rw-r--r--qpid/java/broker/src/test/java/org/apache/qpid/server/queue/MockAMQQueue.java65
-rw-r--r--qpid/java/broker/src/test/java/org/apache/qpid/server/queue/MockQueueEntry.java186
-rw-r--r--qpid/java/broker/src/test/java/org/apache/qpid/server/queue/PersistentMessageTest.java124
-rw-r--r--qpid/java/broker/src/test/java/org/apache/qpid/server/queue/QueueEntryImplTest.java195
-rw-r--r--qpid/java/broker/src/test/java/org/apache/qpid/server/queue/SimpleAMQQueueTest.java212
-rw-r--r--qpid/java/broker/src/test/java/org/apache/qpid/server/queue/SimpleAMQQueueThreadPoolTest.java60
-rw-r--r--qpid/java/broker/src/test/java/org/apache/qpid/server/queue/TransientMessageTest.java177
-rw-r--r--qpid/java/broker/src/test/java/org/apache/qpid/server/registry/ApplicationRegistryShutdownTest.java2
-rw-r--r--qpid/java/broker/src/test/java/org/apache/qpid/server/security/access/ACLManagerTest.java25
-rw-r--r--qpid/java/broker/src/test/java/org/apache/qpid/server/security/access/PrincipalPermissionsTest.java6
-rw-r--r--qpid/java/broker/src/test/java/org/apache/qpid/server/security/access/management/AMQUserManagementMBeanTest.java229
-rw-r--r--qpid/java/broker/src/test/java/org/apache/qpid/server/security/access/plugins/network/FirewallPluginTest.java5
-rw-r--r--qpid/java/broker/src/test/java/org/apache/qpid/server/security/auth/database/Base64MD5PasswordFilePrincipalDatabaseTest.java156
-rw-r--r--qpid/java/broker/src/test/java/org/apache/qpid/server/security/auth/database/HashedUserTest.java6
-rw-r--r--qpid/java/broker/src/test/java/org/apache/qpid/server/security/auth/database/PlainPasswordFilePrincipalDatabaseTest.java396
-rw-r--r--qpid/java/broker/src/test/java/org/apache/qpid/server/security/auth/database/PlainUserTest.java78
-rw-r--r--qpid/java/broker/src/test/java/org/apache/qpid/server/store/MessageStoreTest.java4
-rw-r--r--qpid/java/broker/src/test/java/org/apache/qpid/server/store/SkeletonMessageStore.java3
-rw-r--r--qpid/java/broker/src/test/java/org/apache/qpid/server/store/TestReferenceCounting.java20
-rw-r--r--qpid/java/broker/src/test/java/org/apache/qpid/server/store/TestTransactionLog.java (renamed from qpid/java/broker/src/main/java/org/apache/qpid/server/management/ManagementConfiguration.java)17
-rw-r--r--qpid/java/broker/src/test/java/org/apache/qpid/server/store/TestableMemoryMessageStore.java139
-rw-r--r--qpid/java/broker/src/test/java/org/apache/qpid/server/subscription/MockSubscription.java29
-rw-r--r--qpid/java/broker/src/test/java/org/apache/qpid/server/txn/TxnBufferTest.java4
-rw-r--r--qpid/java/broker/src/test/java/org/apache/qpid/server/util/InternalBrokerBaseCase.java7
-rw-r--r--qpid/java/broker/src/test/java/org/apache/qpid/server/util/TestApplicationRegistry.java23
-rw-r--r--qpid/java/broker/src/test/java/org/apache/qpid/server/virtualhost/VirtualhostInitRoutingTableFromTransactionLogTest.java3
-rw-r--r--qpid/java/build.deps22
-rw-r--r--qpid/java/client/example/bin/verify_all6
-rw-r--r--qpid/java/client/example/src/main/java/README.txt2
-rwxr-xr-xqpid/java/client/example/src/main/java/org/apache/qpid/example/amqpexample/direct/Listener.java2
-rwxr-xr-xqpid/java/client/example/src/main/java/org/apache/qpid/example/amqpexample/fanout/Listener.java2
-rw-r--r--qpid/java/client/example/src/main/java/org/apache/qpid/example/amqpexample/headers/Listener.java2
-rw-r--r--qpid/java/client/example/src/main/java/org/apache/qpid/example/amqpexample/lvq/Listener.java2
-rwxr-xr-xqpid/java/client/example/src/main/java/org/apache/qpid/example/amqpexample/pubsub/TopicListener.java2
-rw-r--r--qpid/java/client/example/src/main/java/org/apache/qpid/example/jmsexample/direct/verify4
-rw-r--r--qpid/java/client/example/src/main/java/org/apache/qpid/example/jmsexample/direct/verify_cpp_java2
-rw-r--r--qpid/java/client/example/src/main/java/org/apache/qpid/example/jmsexample/direct/verify_java_cpp2
-rw-r--r--qpid/java/client/example/src/main/java/org/apache/qpid/example/jmsexample/direct/verify_java_python4
-rw-r--r--qpid/java/client/example/src/main/java/org/apache/qpid/example/jmsexample/direct/verify_python_java4
-rw-r--r--qpid/java/client/example/src/main/java/org/apache/qpid/example/jmsexample/fanout/verify4
-rw-r--r--qpid/java/client/example/src/main/java/org/apache/qpid/example/jmsexample/fanout/verify_cpp_java2
-rw-r--r--qpid/java/client/example/src/main/java/org/apache/qpid/example/jmsexample/fanout/verify_java_cpp2
-rw-r--r--qpid/java/client/example/src/main/java/org/apache/qpid/example/jmsexample/fanout/verify_java_python4
-rw-r--r--qpid/java/client/example/src/main/java/org/apache/qpid/example/jmsexample/fanout/verify_python_java4
-rw-r--r--qpid/java/client/example/src/main/java/org/apache/qpid/example/jmsexample/pubsub/verify4
-rw-r--r--qpid/java/client/example/src/main/java/org/apache/qpid/example/jmsexample/pubsub/verify_cpp_java2
-rw-r--r--qpid/java/client/example/src/main/java/org/apache/qpid/example/jmsexample/pubsub/verify_java_cpp2
-rw-r--r--qpid/java/client/example/src/main/java/org/apache/qpid/example/jmsexample/pubsub/verify_java_python4
-rw-r--r--qpid/java/client/example/src/main/java/org/apache/qpid/example/jmsexample/pubsub/verify_python_java4
-rw-r--r--qpid/java/client/example/src/main/java/org/apache/qpid/example/jmsexample/requestResponse/verify4
-rw-r--r--qpid/java/client/example/src/main/java/org/apache/qpid/example/jmsexample/requestResponse/verify_cpp_java2
-rw-r--r--qpid/java/client/example/src/main/java/org/apache/qpid/example/jmsexample/requestResponse/verify_java_cpp2
-rw-r--r--qpid/java/client/example/src/main/java/org/apache/qpid/example/jmsexample/requestResponse/verify_java_python4
-rw-r--r--qpid/java/client/example/src/main/java/org/apache/qpid/example/jmsexample/requestResponse/verify_python_java4
-rwxr-xr-xqpid/java/client/example/src/main/java/runSample.sh2
-rw-r--r--qpid/java/client/src/main/java/org/apache/qpid/client/AMQConnection.java58
-rw-r--r--qpid/java/client/src/main/java/org/apache/qpid/client/AMQConnectionDelegate_0_10.java6
-rw-r--r--qpid/java/client/src/main/java/org/apache/qpid/client/AMQQueueBrowser.java68
-rw-r--r--qpid/java/client/src/main/java/org/apache/qpid/client/AMQSession.java57
-rw-r--r--qpid/java/client/src/main/java/org/apache/qpid/client/AMQSession_0_10.java178
-rw-r--r--qpid/java/client/src/main/java/org/apache/qpid/client/AMQSession_0_8.java8
-rw-r--r--qpid/java/client/src/main/java/org/apache/qpid/client/BasicMessageConsumer.java26
-rw-r--r--qpid/java/client/src/main/java/org/apache/qpid/client/BasicMessageConsumer_0_10.java74
-rw-r--r--qpid/java/client/src/main/java/org/apache/qpid/client/BasicMessageConsumer_0_8.java20
-rw-r--r--qpid/java/client/src/main/java/org/apache/qpid/client/BasicMessageProducer.java24
-rw-r--r--qpid/java/client/src/main/java/org/apache/qpid/client/BasicMessageProducer_0_10.java8
-rw-r--r--qpid/java/client/src/main/java/org/apache/qpid/client/configuration/ClientProperties.java13
-rw-r--r--qpid/java/client/src/main/java/org/apache/qpid/client/message/AbstractBytesMessage.java43
-rw-r--r--qpid/java/client/src/main/java/org/apache/qpid/client/message/AbstractJMSMessage.java9
-rw-r--r--qpid/java/client/src/main/java/org/apache/qpid/client/message/JMSBytesMessage.java6
-rw-r--r--qpid/java/client/src/main/java/org/apache/qpid/client/message/JMSObjectMessage.java6
-rw-r--r--qpid/java/client/src/main/java/org/apache/qpid/client/message/JMSTextMessage.java1
-rw-r--r--qpid/java/client/src/main/java/org/apache/qpid/client/message/MessageFactoryRegistry.java43
-rw-r--r--qpid/java/client/src/main/java/org/apache/qpid/client/url/URLParser.java23
-rw-r--r--qpid/java/client/src/main/java/org/apache/qpid/jms/ConnectionURL.java6
-rw-r--r--qpid/java/client/src/main/java/org/apache/qpid/jms/failover/FailoverExchangeMethod.java158
-rw-r--r--qpid/java/client/src/main/java/org/apache/qpid/jms/failover/FailoverRoundRobinServers.java10
-rw-r--r--qpid/java/client/src/main/java/org/apache/qpid/nclient/JMSTestCase.java135
-rw-r--r--qpid/java/client/src/test/java/org/apache/qpid/test/unit/client/connectionurl/ConnectionURLTest.java13
-rw-r--r--qpid/java/client/src/test/java/org/apache/qpid/test/unit/client/message/BytesMessageTest.java2
-rw-r--r--qpid/java/client/src/test/java/org/apache/qpid/test/unit/client/message/StreamMessageTest.java2
-rw-r--r--qpid/java/client/src/test/java/org/apache/qpid/test/unit/message/TestAMQSession.java7
-rw-r--r--qpid/java/common.xml2
-rw-r--r--qpid/java/common/Composite.tpl1
-rw-r--r--qpid/java/common/Option.tpl1
-rw-r--r--qpid/java/common/src/main/java/org/apache/qpid/ToyClient.java2
-rw-r--r--qpid/java/common/src/main/java/org/apache/qpid/transport/Connection.java4
-rw-r--r--qpid/java/common/src/main/java/org/apache/qpid/transport/Echo.java2
-rw-r--r--qpid/java/common/src/main/java/org/apache/qpid/transport/Method.java11
-rw-r--r--qpid/java/common/src/main/java/org/apache/qpid/transport/Session.java90
-rw-r--r--qpid/java/common/src/main/java/org/apache/qpid/transport/SessionListener.java2
-rw-r--r--qpid/java/common/src/main/java/org/apache/qpid/transport/Sink.java2
-rw-r--r--qpid/java/common/src/main/java/org/apache/qpid/transport/codec/BBEncoder.java11
-rw-r--r--qpid/java/common/src/main/java/org/apache/qpid/util/FileUtils.java6
-rw-r--r--qpid/java/common/src/main/java/org/apache/qpid/util/PropertiesUtils.java200
-rw-r--r--qpid/java/common/src/test/java/org/apache/qpid/transport/ConnectionTest.java54
-rw-r--r--qpid/java/common/src/test/java/org/apache/qpid/transport/codec/BBEncoderTest.java47
-rw-r--r--qpid/java/common/src/test/java/org/apache/qpid/util/FileUtilsTest.java24
-rw-r--r--qpid/java/cpp.cluster.testprofile3
-rw-r--r--qpid/java/lib/commons-beanutils-core-1.8.0.jarbin0 -> 206035 bytes
-rw-r--r--qpid/java/lib/commons-configuration-1.2.jarbin163822 -> 0 bytes
-rw-r--r--qpid/java/lib/commons-configuration-1.6.jarbin0 -> 298829 bytes
-rw-r--r--qpid/java/lib/commons-digester-1.8.1.jarbin0 -> 146108 bytes
-rw-r--r--qpid/java/lib/org.apache.commons.codec_1.3.0.v20080530-1600.jarbin0 -> 53757 bytes
-rw-r--r--qpid/java/lib/org.eclipse.equinox.launcher.gtk.linux.x86_64_1.0.101.R34x_v20080731/META-INF/ECLIPSE.RSAbin0 -> 3487 bytes
-rw-r--r--qpid/java/lib/org.eclipse.equinox.launcher.gtk.linux.x86_64_1.0.101.R34x_v20080731/META-INF/ECLIPSE.SF17
-rw-r--r--qpid/java/lib/org.eclipse.equinox.launcher.gtk.linux.x86_64_1.0.101.R34x_v20080731/META-INF/MANIFEST.MF25
-rw-r--r--qpid/java/lib/org.eclipse.equinox.launcher.gtk.linux.x86_64_1.0.101.R34x_v20080731/META-INF/eclipse.inf3
-rw-r--r--qpid/java/lib/org.eclipse.equinox.launcher.gtk.linux.x86_64_1.0.101.R34x_v20080731/about.html28
-rw-r--r--qpid/java/lib/org.eclipse.equinox.launcher.gtk.linux.x86_64_1.0.101.R34x_v20080731/eclipse_1115.sobin0 -> 169725 bytes
-rw-r--r--qpid/java/lib/org.eclipse.equinox.launcher.gtk.linux.x86_64_1.0.101.R34x_v20080731/launcher.gtk.linux.x86_64.properties12
-rw-r--r--qpid/java/lib/org.eclipse.equinox.launcher.gtk.solaris.sparc_1.0.101.R34x_v20080731/META-INF/ECLIPSE.RSAbin0 -> 3487 bytes
-rw-r--r--qpid/java/lib/org.eclipse.equinox.launcher.gtk.solaris.sparc_1.0.101.R34x_v20080731/META-INF/ECLIPSE.SF17
-rw-r--r--qpid/java/lib/org.eclipse.equinox.launcher.gtk.solaris.sparc_1.0.101.R34x_v20080731/META-INF/MANIFEST.MF25
-rw-r--r--qpid/java/lib/org.eclipse.equinox.launcher.gtk.solaris.sparc_1.0.101.R34x_v20080731/META-INF/eclipse.inf3
-rw-r--r--qpid/java/lib/org.eclipse.equinox.launcher.gtk.solaris.sparc_1.0.101.R34x_v20080731/about.html28
-rw-r--r--qpid/java/lib/org.eclipse.equinox.launcher.gtk.solaris.sparc_1.0.101.R34x_v20080731/eclipse_1115.sobin0 -> 76500 bytes
-rw-r--r--qpid/java/lib/org.eclipse.equinox.launcher.gtk.solaris.sparc_1.0.101.R34x_v20080731/launcher.gtk.solaris.sparc.properties12
-rw-r--r--qpid/java/lib/org.eclipse.swt.gtk.linux.x86_64_3.4.1.v3449c.jarbin0 -> 2123120 bytes
-rw-r--r--qpid/java/lib/org.eclipse.swt.gtk.solaris.sparc_3.4.1.v3449c.jarbin0 -> 1877410 bytes
-rw-r--r--qpid/java/management/client/bin/qman-wsdm-start.cmd1
-rw-r--r--qpid/java/management/client/bin/qman-wsdm-start.sh2
-rw-r--r--qpid/java/management/client/build.xml6
-rw-r--r--qpid/java/management/client/console/brokers_management.jsp2
-rw-r--r--qpid/java/management/client/console/fragments/menu.jsp4
-rw-r--r--qpid/java/management/client/console/wsdl-viewer.xsl2523
-rw-r--r--qpid/java/management/client/console/wsdm_rmd_perspective.jsp10
-rw-r--r--qpid/java/management/client/console/wsdm_wsdl_perspective.jsp8
-rw-r--r--qpid/java/management/client/src/example/PauseAndResumeSubscription.out.ok133
-rw-r--r--qpid/java/management/client/src/example/org/apache/qpid/management/example/ConsumerAndProducerExample.java51
-rw-r--r--qpid/java/management/client/src/example/org/apache/qpid/management/example/PausableSubscriptionExample.java88
-rw-r--r--qpid/java/management/client/src/main/java/muse.xml2
-rw-r--r--qpid/java/management/client/src/main/java/org/apache/qpid/management/Messages.java2
-rw-r--r--qpid/java/management/client/src/main/java/org/apache/qpid/management/Names.java4
-rw-r--r--qpid/java/management/client/src/main/java/org/apache/qpid/management/configuration/AccessModeMapping.java83
-rw-r--r--qpid/java/management/client/src/main/java/org/apache/qpid/management/configuration/Configuration.java94
-rw-r--r--qpid/java/management/client/src/main/java/org/apache/qpid/management/configuration/Configurator.java45
-rw-r--r--qpid/java/management/client/src/main/java/org/apache/qpid/management/configuration/TypeMapping.java90
-rw-r--r--qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/JmxService.java28
-rw-r--r--qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/services/QMan.java86
-rw-r--r--qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/services/QpidService.java2
-rw-r--r--qpid/java/management/client/src/main/java/org/apache/qpid/management/web/action/BrokerModel.java42
-rw-r--r--qpid/java/management/client/src/main/java/org/apache/qpid/management/web/action/BrokersManagementAction.java30
-rw-r--r--qpid/java/management/client/src/main/java/org/apache/qpid/management/web/action/WsdmPropertiesPerspectiveAction.java3
-rw-r--r--qpid/java/management/client/src/main/java/org/apache/qpid/management/web/action/WsdmRmdPerspectiveAction.java78
-rw-r--r--qpid/java/management/client/src/main/java/org/apache/qpid/management/web/action/WsdmWsdlPerspectiveAction.java16
-rw-r--r--qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/QEmuInitializer.java8
-rw-r--r--qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/capabilities/Constants.java44
-rw-r--r--qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/capabilities/ConsumerCapability.java2
-rw-r--r--qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/capabilities/DummyCapabilityBuilder.java37
-rw-r--r--qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/capabilities/MBeanCapability.java8
-rw-r--r--qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/capabilities/MBeanCapabilityBuilder.java8
-rw-r--r--qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/capabilities/QManMetadataExchangeCapability.java36
-rw-r--r--qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/capabilities/Result.java64
-rw-r--r--qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/capabilities/RmdBuilder.java3
-rw-r--r--qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/capabilities/WSDMArtifactsDirector.java5
-rw-r--r--qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/capabilities/WsArtifactsFactory.java9
-rw-r--r--qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/capabilities/WsdlBuilder.java414
-rw-r--r--qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/common/EntityInstanceNotFoundFault.java5
-rw-r--r--qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/common/ThreadSession.java8
-rw-r--r--qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/muse/engine/WSDMAdapterEnvironment.java15
-rw-r--r--qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/muse/serializer/InvocationResultSerializer.java32
-rw-r--r--qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/muse/serializer/MapSerializer.java30
-rw-r--r--qpid/java/management/client/src/main/java/wsdl/QManWsResource.wsdl28
-rw-r--r--qpid/java/management/client/src/main/java/wsdl/WS-BaseNotification-1_3.wsdl13
-rw-r--r--qpid/java/management/client/src/main/java/wsdl/WS-ServiceGroupEntry-1_2.wsdl2
-rw-r--r--qpid/java/management/client/src/test/java/org/apache/qpid/management/TestConstants.java2
-rw-r--r--qpid/java/management/client/src/test/java/org/apache/qpid/management/configuration/ConfigurationTest.java39
-rw-r--r--qpid/java/management/client/src/test/java/org/apache/qpid/management/wsdm/BaseWsDmAdapterTestCase.java143
-rw-r--r--qpid/java/management/client/src/test/java/org/apache/qpid/management/wsdm/GetMultipleResourcePropertiesTestCase.java125
-rw-r--r--qpid/java/management/client/src/test/java/org/apache/qpid/management/wsdm/GetResourcePropertiesTestCase.java105
-rw-r--r--qpid/java/management/client/src/test/java/org/apache/qpid/management/wsdm/GetResourcePropertyDocumentTestCase.java134
-rw-r--r--qpid/java/management/client/src/test/java/org/apache/qpid/management/wsdm/MetadataExchangeInterfaceTestCase.java169
-rw-r--r--qpid/java/management/client/src/test/java/org/apache/qpid/management/wsdm/OperationInvocationInterfaceTestCase.java580
-rw-r--r--qpid/java/management/client/src/test/java/org/apache/qpid/management/wsdm/SetResourcePropertiesTestCase.java219
-rw-r--r--qpid/java/management/client/src/test/java/org/apache/qpid/management/wsdm/WsDmAdapterTest.java975
-rw-r--r--qpid/java/management/client/web.xml170
-rw-r--r--qpid/java/management/eclipse-plugin/META-INF/MANIFEST.MF4
-rw-r--r--qpid/java/management/eclipse-plugin/build-release-linux-gtk-x86_64.properties36
-rw-r--r--qpid/java/management/eclipse-plugin/build-release-solaris-gtk-sparc.properties39
-rw-r--r--qpid/java/management/eclipse-plugin/build-release.xml14
-rw-r--r--qpid/java/management/eclipse-plugin/build.xml13
-rw-r--r--qpid/java/management/eclipse-plugin/icons/splash.bmpbin207078 -> 275178 bytes
-rw-r--r--qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/Constants.java5
-rw-r--r--qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/ManagedBean.java63
-rw-r--r--qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/ManagedServer.java19
-rw-r--r--qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/actions/AddServer.java41
-rw-r--r--qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/actions/ReconnectServer.java18
-rw-r--r--qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/jmx/ClientListener.java2
-rw-r--r--qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/jmx/ClientNotificationListener.java1
-rw-r--r--qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/jmx/JMXServerRegistry.java1
-rw-r--r--qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/jmx/MBeanUtility.java12
-rw-r--r--qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/MBeanTypeTabControl.java4
-rw-r--r--qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/MBeanView.java14
-rw-r--r--qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/NavigationView.java218
-rw-r--r--qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/OperationTabControl.java43
-rw-r--r--qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/QueueTypeTabControl.java42
-rw-r--r--qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/ViewUtility.java342
-rw-r--r--qpid/java/management/eclipse-plugin/src/main/resources/linux-gtk-x86/Configuration/config.ini3
-rw-r--r--qpid/java/management/eclipse-plugin/src/main/resources/linux-gtk-x86_64/Configuration/config.ini49
-rw-r--r--qpid/java/management/eclipse-plugin/src/main/resources/linux-gtk-x86_64/libcairo-swt.sobin0 -> 335360 bytes
-rw-r--r--qpid/java/management/eclipse-plugin/src/main/resources/linux-gtk-x86_64/qpidmcbin0 -> 67927 bytes
-rw-r--r--qpid/java/management/eclipse-plugin/src/main/resources/linux-gtk-x86_64/qpidmc.ini37
-rw-r--r--qpid/java/management/eclipse-plugin/src/main/resources/macosx/Configuration/config.ini3
-rw-r--r--qpid/java/management/eclipse-plugin/src/main/resources/qpid-management-common-plugin/MANIFEST.MF2
-rw-r--r--qpid/java/management/eclipse-plugin/src/main/resources/solaris-gtk-sparc/Configuration/config.ini49
-rw-r--r--qpid/java/management/eclipse-plugin/src/main/resources/solaris-gtk-sparc/Qpidmc.l.pm311
-rw-r--r--qpid/java/management/eclipse-plugin/src/main/resources/solaris-gtk-sparc/Qpidmc.m.pm295
-rw-r--r--qpid/java/management/eclipse-plugin/src/main/resources/solaris-gtk-sparc/Qpidmc.s.pm287
-rw-r--r--qpid/java/management/eclipse-plugin/src/main/resources/solaris-gtk-sparc/Qpidmc.t.pm279
-rwxr-xr-xqpid/java/management/eclipse-plugin/src/main/resources/solaris-gtk-sparc/qpidmcbin0 -> 31668 bytes
-rw-r--r--qpid/java/management/eclipse-plugin/src/main/resources/solaris-gtk-sparc/qpidmc.ini40
-rw-r--r--qpid/java/management/eclipse-plugin/src/main/resources/win32-win32-x86/Configuration/config.ini3
-rw-r--r--qpid/java/systests/build.xml2
-rw-r--r--qpid/java/systests/src/main/java/org/apache/qpid/client/MessageListenerTest.java8
-rw-r--r--qpid/java/systests/src/main/java/org/apache/qpid/client/MultipleJCAProviderRegistrationTest.java4
-rw-r--r--qpid/java/systests/src/main/java/org/apache/qpid/server/queue/QueueCreateTest.java179
-rw-r--r--qpid/java/systests/src/main/java/org/apache/qpid/server/queue/TimeToLiveTest.java7
-rw-r--r--qpid/java/systests/src/main/java/org/apache/qpid/server/security/acl/SimpleACLTest.java5
-rw-r--r--qpid/java/systests/src/main/java/org/apache/qpid/server/store/SlowMessageStore.java38
-rw-r--r--qpid/java/systests/src/main/java/org/apache/qpid/test/client/QueueBrowsingFlowToDiskTest.java69
-rw-r--r--qpid/java/systests/src/main/java/org/apache/qpid/test/client/failover/FailoverTest.java237
-rw-r--r--qpid/java/systests/src/main/java/org/apache/qpid/test/client/message/ObjectMessageTest.java136
-rw-r--r--qpid/java/systests/src/main/java/org/apache/qpid/test/client/timeouts/SyncWaitDelayTest.java39
-rw-r--r--qpid/java/systests/src/main/java/org/apache/qpid/test/unit/client/connection/ConnectionCloseTest.java2
-rw-r--r--qpid/java/systests/src/main/java/org/apache/qpid/test/utils/FailoverBaseCase.java35
-rw-r--r--qpid/java/systests/src/main/java/org/apache/qpid/test/utils/QpidTestCase.java8
-rw-r--r--qpid/java/test-provider.properties2
-rw-r--r--qpid/java/tools/src/main/java/org/apache/qpid/tools/QpidBench.java2
-rwxr-xr-xqpid/python/commands/qpid-cluster178
-rwxr-xr-xqpid/python/commands/qpid-config55
-rwxr-xr-xqpid/python/commands/qpid-stat449
-rwxr-xr-xqpid/python/examples/datatypes/client.py122
-rwxr-xr-xqpid/python/examples/datatypes/server.py124
-rw-r--r--qpid/python/examples/datatypes/testdata.py180
-rwxr-xr-xqpid/python/perftest8
-rw-r--r--qpid/python/qmf/console.py19
-rw-r--r--qpid/python/qpid/codec010.py25
-rw-r--r--qpid/python/qpid/datatypes.py9
-rw-r--r--qpid/python/qpid/delegates.py6
-rw-r--r--qpid/python/qpid/disp.py165
-rw-r--r--qpid/python/qpid/management.py8
-rw-r--r--qpid/python/qpid/managementdata.py5
-rw-r--r--qpid/python/qpid/peer.py2
-rw-r--r--qpid/python/qpid/spec010.py41
-rw-r--r--qpid/python/qpid/testlib.py12
-rw-r--r--qpid/python/setup.py4
-rw-r--r--qpid/python/tests/codec010.py21
-rw-r--r--qpid/python/tests/datatypes.py10
-rw-r--r--qpid/python/tests_0-10/alternate_exchange.py12
-rw-r--r--qpid/python/tests_0-10/broker.py16
-rw-r--r--qpid/python/tests_0-10/dtx.py6
-rw-r--r--qpid/python/tests_0-10/example.py4
-rw-r--r--qpid/python/tests_0-10/exchange.py4
-rw-r--r--qpid/python/tests_0-10/management.py4
-rw-r--r--qpid/python/tests_0-10/message.py112
-rw-r--r--qpid/python/tests_0-10/persistence.py2
-rw-r--r--qpid/python/tests_0-10/queue.py16
-rw-r--r--qpid/python/tests_0-10/tx.py8
-rw-r--r--qpid/ruby/Makefile47
-rw-r--r--qpid/ruby/lib/qpid/delegates.rb5
-rw-r--r--qpid/specs/management-schema.xml4
743 files changed, 30274 insertions, 11755 deletions
diff --git a/qpid/cpp/configure.ac b/qpid/cpp/configure.ac
index 90b943f047..4cdad71858 100644
--- a/qpid/cpp/configure.ac
+++ b/qpid/cpp/configure.ac
@@ -11,7 +11,7 @@ dnl
dnl When updating the name/version number here, also update it in
dnl src/qpid/Version.h
-AC_INIT([qpidc], [0.4], [qpid-dev@incubator.apache.org])
+AC_INIT([qpidc], [0.5], [dev@qpid.apache.org])
AC_CONFIG_AUX_DIR([build-aux])
AM_INIT_AUTOMAKE([dist-bzip2 subdir-objects])
@@ -87,13 +87,14 @@ else
AC_CHECK_DECL([__SUNPRO_CC], [SUNCC=yes], [SUNCC=no])
# Set up for sun CC compiler
- if test x$SUNCC = xno; then
+ if test x$SUNCC = xyes; then
if test "${enableval}" = yes; then
WARNING_FLAGS=+w
fi
CXXFLAGS="$CXXFLAGS -library=stlport4 -mt"
LD="$CXX"
LDFLAGS="$LDFLAGS -library=stlport4 -mt"
+ AC_SUBST([SUNCC_RUNTIME_LIBS], [-lCrun])
fi
fi
@@ -150,8 +151,9 @@ test -z "$RUBY" && AC_MSG_ERROR([Missing ruby installation (try "yum install rub
specdir=`pwd`/$srcdir/../specs
AMQP_FINAL_XML=$specdir/amqp.0-10-qpid-errata.xml
+test -f $AMQP_FINAL_XML || test -d $srcdir/src/gen || AC_MSG_ERROR([Neither AMQP specs nor spec-generated code present; cannot build.])
AC_SUBST(AMQP_FINAL_XML)
-AM_CONDITIONAL([GENERATE], [ls $AMQP_FINAL_XML >/dev/null])
+AM_CONDITIONAL([GENERATE], [test -f $AMQP_FINAL_XML])
# URL and download URL for the package.
URL=http://rhm.et.redhat.com/qpidc
@@ -311,14 +313,19 @@ LIBS=$tmp_LIBS
AM_CONDITIONAL([RDMA], [test x$with_RDMA = xyes])
# Setup --with-ssl/--without-ssl as arguments to configure
-tmp_LIBS=$LIBS
+SSL_CFLAGS=""
+SSL_LDFLAGS=""
AC_ARG_WITH([ssl],
[AS_HELP_STRING([--with-ssl], [Build with support for SSL])],
[case ${withval} in
yes)
with_SSL=yes
- PKG_CHECK_MODULES([SSL], [nspr],,[AC_MSG_ERROR([nspr not found])])
- PKG_CHECK_MODULES([SSL], [nss],,[AC_MSG_ERROR([nss not found])])
+ AC_PATH_PROG([NSPR_CONFIG], [nspr-config])
+ AS_IF([test x$NSPR_CONFIG = x], [AC_MSG_ERROR([libnspr not found])], [])
+ AC_PATH_PROG([NSS_CONFIG], [nss-config])
+ AS_IF([test x$NSS_CONFIG = x], [AC_MSG_ERROR([libnss not found])], [])
+ SSL_CFLAGS="`$NSPR_CONFIG --cflags` `$NSS_CONFIG --cflags`"
+ SSL_LDFLAGS="`$NSPR_CONFIG --libs` `$NSS_CONFIG --libs`"
;;
no)
with_SSL=no
@@ -329,13 +336,18 @@ AC_ARG_WITH([ssl],
esac],
[
with_SSL=yes
- PKG_CHECK_MODULES([SSL], [nspr],,[with_SSL=no])
- PKG_CHECK_MODULES([SSL], [nss],,[with_SSL=no])
+ AC_PATH_PROG([NSPR_CONFIG], [nspr-config])
+ AS_IF([test x$NSPR_CONFIG = x], [with_SSL=no],
+ [AC_PATH_PROG([NSS_CONFIG], [nss-config])
+ AS_IF([test x$NSS_CONFIG = x], [with_SSL=no],
+ [SSL_CFLAGS="`$NSPR_CONFIG --cflags` `$NSS_CONFIG --cflags`"
+ SSL_LDFLAGS="`$NSPR_CONFIG --libs` `$NSS_CONFIG --libs`"])])
]
)
# Remove from LIBS, we will link it explicitly in make files.
-LIBS=$tmp_LIBS
AM_CONDITIONAL([SSL], [test x$with_SSL = xyes])
+AC_SUBST([SSL_CFLAGS])
+AC_SUBST([SSL_LDFLAGS])
poller=no
@@ -367,6 +379,37 @@ if test $poller = xno; then
AC_MSG_ERROR([Polling mechanism not implemented for $host])
fi
+#Guess host architecture, to choose platform-dependent objects
+case "$host" in
+ *sun-solaris*)
+ arch=solaris
+ ;;
+esac
+AM_CONDITIONAL([SUNOS], [test x$arch = xsolaris])
+
+# Check for some syslog capabilities not present in all systems
+AC_TRY_COMPILE([#include <sys/syslog.h>],
+ [int v = LOG_AUTHPRIV;],
+ [AC_DEFINE([HAVE_LOG_AUTHPRIV], [1], [Set to 1 whether LOG_AUTHPRIV is supported.])],)
+
+AC_TRY_COMPILE([#include <sys/syslog.h>],
+ [int v = LOG_FTP;],
+ [AC_DEFINE([HAVE_LOG_FTP], [1], [Set to 1 whether LOG_FTP is supported.])],)
+
+#Check if we need to include libacl to provide acl API
+gl_saved_libs=$LIBS
+ AC_SEARCH_LIBS(acl, [acl],
+ [test "$ac_cv_search_acl" = "none required" ||
+ LIB_ACL=$ac_cv_search_acl])
+ AC_SUBST([LIB_ACL])
+LIBS=$gl_saved_libs
+
+SOCKLIBS=""
+AC_CHECK_LIB([socket],[socket],[SOCKET_LIB="-lsocket"],[SOCKET_LIB=""],[])
+AC_CHECK_LIB([nsl],[getipnodebyname],[NSL_LIB="-lnsl"],[NSL_LIB=""],[])
+SOCKLIBS="$SOCKET_LIB $NSL_LIB"
+AC_SUBST([SOCKLIBS])
+
AM_PATH_PYTHON()
# Files to generate
diff --git a/qpid/cpp/docs/api/developer.doxygen.in b/qpid/cpp/docs/api/developer.doxygen.in
index 46970d5465..4f643ef097 100644
--- a/qpid/cpp/docs/api/developer.doxygen.in
+++ b/qpid/cpp/docs/api/developer.doxygen.in
@@ -975,13 +975,13 @@ ENABLE_PREPROCESSING = YES
# compilation will be performed. Macro expansion can be done in a controlled
# way by setting EXPAND_ONLY_PREDEF to YES.
-MACRO_EXPANSION = NO
+MACRO_EXPANSION = YES
# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES
# then the macro expansion is limited to the macros specified with the
# PREDEFINED and EXPAND_AS_DEFINED tags.
-EXPAND_ONLY_PREDEF = NO
+EXPAND_ONLY_PREDEF = YES
# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files
# in the INCLUDE_PATH (see below) will be search if a #include is found.
@@ -1009,7 +1009,7 @@ INCLUDE_FILE_PATTERNS =
# undefined via #undef or recursively expanded use the := operator
# instead of the = operator.
-PREDEFINED =
+PREDEFINED = QPID_CLIENT_EXTERN= QPID_COMMON_EXTERN= QPID_CONSOLE_EXTERN= QPID_BROKER_EXTERN=
# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then
# this tag can be used to specify a list of macro names that should be expanded.
diff --git a/qpid/cpp/docs/api/user.doxygen.in b/qpid/cpp/docs/api/user.doxygen.in
index 7a87cc0fab..769ada716e 100644
--- a/qpid/cpp/docs/api/user.doxygen.in
+++ b/qpid/cpp/docs/api/user.doxygen.in
@@ -1003,7 +1003,7 @@ INCLUDE_FILE_PATTERNS =
# undefined via #undef or recursively expanded use the := operator
# instead of the = operator.
-PREDEFINED =
+PREDEFINED = QPID_CLIENT_EXTERN= QPID_COMMON_EXTERN= QPID_CONSOLE_EXTERN= QPID_BROKER_EXTERN=
# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then
# this tag can be used to specify a list of macro names that should be expanded.
diff --git a/qpid/cpp/etc/sasl2/qpidd.conf b/qpid/cpp/etc/sasl2/qpidd.conf
index 45eea4592b..3197d7792a 100644
--- a/qpid/cpp/etc/sasl2/qpidd.conf
+++ b/qpid/cpp/etc/sasl2/qpidd.conf
@@ -39,3 +39,7 @@
pwcheck_method: auxprop
auxprop_plugin: sasldb
sasldb_path: /var/lib/qpidd/qpidd.sasldb
+
+#following line stops spurious 'sql_select option missing' errors when
+#cyrus-sql-sasl plugin is installed
+sql_select: dummy select
diff --git a/qpid/cpp/examples/Makefile.am b/qpid/cpp/examples/Makefile.am
index 255c86a7be..f23f3ee9e0 100644
--- a/qpid/cpp/examples/Makefile.am
+++ b/qpid/cpp/examples/Makefile.am
@@ -27,18 +27,17 @@ if !HAVE_XML
endif
MAKEDIST=.libs/Makefile
-SUBMAKE=' for d in $(SUBDIRS) ; do $$(MAKE) -C $$$$d $$@ ; done'
+
$(MAKEDIST): Makefile
mkdir -p .libs
- @$(ECHO) all: > $(MAKEDIST)
- @$(ECHO) $(SUBMAKE) >> $(MAKEDIST)
- @$(ECHO) clean: >> $(MAKEDIST)
- @$(ECHO) $(SUBMAKE) >> $(MAKEDIST)
+ @(echo 'all clean:' ; \
+ echo ' for d in $(SUBDIRS) ; do $$(MAKE) -C $$$$d $$@ ; done' ; \
+ ) > $(MAKEDIST)
examplesdir=$(pkgdatadir)/examples
-examples_DATA = README $(MAKEDIST)
+dist_examples_DATA = README $(MAKEDIST)
-EXTRA_DIST = $(examples_DATA) README.verify verify verify_all
+EXTRA_DIST = README.verify verify verify_all
# For older versions of automake
abs_top_srcdir = @abs_top_srcdir@
diff --git a/qpid/cpp/examples/direct/Makefile.am b/qpid/cpp/examples/direct/Makefile.am
index 07431f6fe4..8f220d1b7e 100644
--- a/qpid/cpp/examples/direct/Makefile.am
+++ b/qpid/cpp/examples/direct/Makefile.am
@@ -18,6 +18,7 @@
#
examplesdir=$(pkgdatadir)/examples/direct
+MAKELDFLAGS=$(CLIENTFLAGS)
include $(top_srcdir)/examples/makedist.mk
noinst_PROGRAMS=direct_producer listener declare_queues
diff --git a/qpid/cpp/examples/direct/direct_declare_queues.vcproj b/qpid/cpp/examples/direct/direct_declare_queues.vcproj
new file mode 100644
index 0000000000..097b0ee3bf
--- /dev/null
+++ b/qpid/cpp/examples/direct/direct_declare_queues.vcproj
@@ -0,0 +1,374 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="9.00"
+ Name="direct_declare_queues"
+ ProjectGUID="{18165D4D-FECA-1BAD-4346-8C4DF2536AA5}"
+ RootNamespace="direct_declare_queues"
+ Keyword="Win32Proj"
+ SignManifests="true"
+ >
+ <Platforms>
+ <Platform
+ Name="Win32"
+ />
+ <Platform
+ Name="x64"
+ />
+ </Platforms>
+ <ToolFiles>
+ </ToolFiles>
+ <Configurations>
+ <Configuration
+ Name="Debug|Win32"
+ OutputDirectory="."
+ IntermediateDirectory="Debug\direct_declare_queues\I386"
+ ConfigurationType="1"
+ CharacterSet="0"
+
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ AdditionalOptions=""
+ AdditionalIncludeDirectories=""
+ TypeLibraryName="$(InputName).tlb"
+ HeaderFileName="$(InputName).h"
+ InterfaceIdentifierFileName="$(InputName)_i.c"
+ ProxyFileName="$(InputName)_p.c"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..\..\src,..\..\src\gen"
+ PreprocessorDefinitions="_DEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
+ MinimalRebuild="false"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="3"
+ RuntimeTypeInfo="true"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="false"
+ DebugInformationFormat="3"
+ DisableSpecificWarnings="4244;4800"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ PreprocessorDefinitions="_DEBUG;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
+ Culture="1033"
+ AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..\..\src,..\..\src\gen"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="qpidcommond.lib qpidclientd.lib"
+ OutputFile="$(OutDir)\declare_queues.exe"
+ LinkIncremental="2"
+ SuppressStartupBanner="true"
+ AdditionalLibraryDirectories=".;$(BOOST_ROOT)\lib;..\..\src"
+ GenerateDebugInformation="true"
+ SubSystem="1"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|Win32"
+ OutputDirectory="Release"
+ IntermediateDirectory="Release\direct_declare_queues\I386"
+ ConfigurationType="1"
+ CharacterSet="0"
+
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ AdditionalOptions=""
+ AdditionalIncludeDirectories=""
+ TypeLibraryName="$(InputName).tlb"
+ HeaderFileName="$(InputName).h"
+ InterfaceIdentifierFileName="$(InputName)_i.c"
+ ProxyFileName="$(InputName)_p.c"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..\..\src,..\..\src\gen"
+ PreprocessorDefinitions="NDEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
+ RuntimeLibrary="2"
+ RuntimeTypeInfo="true"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="false"
+ DisableSpecificWarnings="4244;4800"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ PreprocessorDefinitions="NDEBUG;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
+ Culture="1033"
+ AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..\..\src,..\..\src\gen"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="qpidcommon.lib qpidclient.lib"
+ OutputFile="$(OutDir)\declare_queues.exe"
+ LinkIncremental="1"
+ SuppressStartupBanner="true"
+ AdditionalLibraryDirectories=".;$(BOOST_ROOT)\lib;..\..\src"
+ GenerateDebugInformation="true"
+ SubSystem="1"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Debug|x64"
+ OutputDirectory="."
+ IntermediateDirectory="Debug\direct_declare_queues\AMD64"
+ ConfigurationType="1"
+ CharacterSet="0"
+
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ AdditionalOptions=""
+ AdditionalIncludeDirectories=""
+ TypeLibraryName="$(InputName).tlb"
+ HeaderFileName="$(InputName).h"
+ InterfaceIdentifierFileName="$(InputName)_i.c"
+ ProxyFileName="$(InputName)_p.c"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..\..\src,..\..\src\gen"
+ PreprocessorDefinitions="_DEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;_AMD64_;_WIN64;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
+ MinimalRebuild="false"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="3"
+ RuntimeTypeInfo="true"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="false"
+ DebugInformationFormat="3"
+ DisableSpecificWarnings="4244;4800"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ PreprocessorDefinitions="_DEBUG;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS;_WIN64"
+ Culture="1033"
+ AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..\..\src,..\..\src\gen"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalOptions="/machine:AMD64"
+ AdditionalDependencies="qpidcommond.lib qpidclientd.lib"
+ OutputFile="$(OutDir)\declare_queues.exe"
+ LinkIncremental="2"
+ SuppressStartupBanner="true"
+ AdditionalLibraryDirectories=".;$(BOOST_ROOT)\lib;..\..\src"
+ GenerateDebugInformation="true"
+ SubSystem="1"
+ TargetMachine="17"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|x64"
+ OutputDirectory="Release"
+ IntermediateDirectory="Release\direct_declare_queues\AMD64"
+ ConfigurationType="1"
+ CharacterSet="0"
+
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ AdditionalOptions=""
+ AdditionalIncludeDirectories=""
+ TypeLibraryName="$(InputName).tlb"
+ HeaderFileName="$(InputName).h"
+ InterfaceIdentifierFileName="$(InputName)_i.c"
+ ProxyFileName="$(InputName)_p.c"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..\..\src,..\..\src\gen"
+ PreprocessorDefinitions="NDEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;_AMD64_;_WIN64;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
+ RuntimeLibrary="2"
+ RuntimeTypeInfo="true"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="false"
+ DisableSpecificWarnings="4244;4800"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ PreprocessorDefinitions="NDEBUG;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS;_WIN64"
+ Culture="1033"
+ AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..\..\src,..\..\src\gen"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalOptions="/machine:AMD64"
+ AdditionalDependencies="qpidcommon.lib qpidclient.lib"
+ OutputFile="$(OutDir)\declare_queues.exe"
+ LinkIncremental="1"
+ SuppressStartupBanner="true"
+ AdditionalLibraryDirectories=".;$(BOOST_ROOT)\lib;..\..\src"
+ GenerateDebugInformation="true"
+ SubSystem="1"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ TargetMachine="17"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ </Configurations>
+ <References>
+ </References>
+ <Files>
+ <Filter
+ Name="Source Files"
+ Filter="cpp;cxx;cc;C;c">
+ <File
+ RelativePath="declare_queues.cpp">
+ </File>
+ </Filter>
+ <Filter
+ Name="Header Files"
+ Filter="h;hpp;hxx;hh">
+ <File
+ RelativePath="ConnectionOptions.h">
+ </File>
+ <File
+ RelativePath="TestOptions.h">
+ </File>
+ </Filter>
+ </Files>
+ <Globals>
+ </Globals>
+</VisualStudioProject>
diff --git a/qpid/cpp/examples/direct/direct_direct_producer.vcproj b/qpid/cpp/examples/direct/direct_direct_producer.vcproj
new file mode 100644
index 0000000000..94f7da5e69
--- /dev/null
+++ b/qpid/cpp/examples/direct/direct_direct_producer.vcproj
@@ -0,0 +1,374 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="9.00"
+ Name="direct_direct_producer"
+ ProjectGUID="{9701E0BD-FECA-1BAD-4346-8C4DF2536AA5}"
+ RootNamespace="direct_direct_producer"
+ Keyword="Win32Proj"
+ SignManifests="true"
+ >
+ <Platforms>
+ <Platform
+ Name="Win32"
+ />
+ <Platform
+ Name="x64"
+ />
+ </Platforms>
+ <ToolFiles>
+ </ToolFiles>
+ <Configurations>
+ <Configuration
+ Name="Debug|Win32"
+ OutputDirectory="."
+ IntermediateDirectory="Debug\direct_direct_producer\I386"
+ ConfigurationType="1"
+ CharacterSet="0"
+
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ AdditionalOptions=""
+ AdditionalIncludeDirectories=""
+ TypeLibraryName="$(InputName).tlb"
+ HeaderFileName="$(InputName).h"
+ InterfaceIdentifierFileName="$(InputName)_i.c"
+ ProxyFileName="$(InputName)_p.c"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..\..\src,..\..\src\gen"
+ PreprocessorDefinitions="_DEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
+ MinimalRebuild="false"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="3"
+ RuntimeTypeInfo="true"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="false"
+ DebugInformationFormat="3"
+ DisableSpecificWarnings="4244;4800"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ PreprocessorDefinitions="_DEBUG;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
+ Culture="1033"
+ AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..\..\src,..\..\src\gen"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="qpidcommond.lib qpidclientd.lib"
+ OutputFile="$(OutDir)\direct_producer.exe"
+ LinkIncremental="2"
+ SuppressStartupBanner="true"
+ AdditionalLibraryDirectories=".;$(BOOST_ROOT)\lib;..\..\src"
+ GenerateDebugInformation="true"
+ SubSystem="1"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|Win32"
+ OutputDirectory="Release"
+ IntermediateDirectory="Release\direct_direct_producer\I386"
+ ConfigurationType="1"
+ CharacterSet="0"
+
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ AdditionalOptions=""
+ AdditionalIncludeDirectories=""
+ TypeLibraryName="$(InputName).tlb"
+ HeaderFileName="$(InputName).h"
+ InterfaceIdentifierFileName="$(InputName)_i.c"
+ ProxyFileName="$(InputName)_p.c"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..\..\src,..\..\src\gen"
+ PreprocessorDefinitions="NDEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
+ RuntimeLibrary="2"
+ RuntimeTypeInfo="true"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="false"
+ DisableSpecificWarnings="4244;4800"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ PreprocessorDefinitions="NDEBUG;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
+ Culture="1033"
+ AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..\..\src,..\..\src\gen"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="qpidcommon.lib qpidclient.lib"
+ OutputFile="$(OutDir)\direct_producer.exe"
+ LinkIncremental="1"
+ SuppressStartupBanner="true"
+ AdditionalLibraryDirectories=".;$(BOOST_ROOT)\lib;..\..\src"
+ GenerateDebugInformation="true"
+ SubSystem="1"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Debug|x64"
+ OutputDirectory="."
+ IntermediateDirectory="Debug\direct_direct_producer\AMD64"
+ ConfigurationType="1"
+ CharacterSet="0"
+
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ AdditionalOptions=""
+ AdditionalIncludeDirectories=""
+ TypeLibraryName="$(InputName).tlb"
+ HeaderFileName="$(InputName).h"
+ InterfaceIdentifierFileName="$(InputName)_i.c"
+ ProxyFileName="$(InputName)_p.c"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..\..\src,..\..\src\gen"
+ PreprocessorDefinitions="_DEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;_AMD64_;_WIN64;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
+ MinimalRebuild="false"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="3"
+ RuntimeTypeInfo="true"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="false"
+ DebugInformationFormat="3"
+ DisableSpecificWarnings="4244;4800"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ PreprocessorDefinitions="_DEBUG;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS;_WIN64"
+ Culture="1033"
+ AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..\..\src,..\..\src\gen"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalOptions="/machine:AMD64"
+ AdditionalDependencies="qpidcommond.lib qpidclientd.lib"
+ OutputFile="$(OutDir)\direct_producer.exe"
+ LinkIncremental="2"
+ SuppressStartupBanner="true"
+ AdditionalLibraryDirectories=".;$(BOOST_ROOT)\lib;..\..\src"
+ GenerateDebugInformation="true"
+ SubSystem="1"
+ TargetMachine="17"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|x64"
+ OutputDirectory="Release"
+ IntermediateDirectory="Release\direct_direct_producer\AMD64"
+ ConfigurationType="1"
+ CharacterSet="0"
+
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ AdditionalOptions=""
+ AdditionalIncludeDirectories=""
+ TypeLibraryName="$(InputName).tlb"
+ HeaderFileName="$(InputName).h"
+ InterfaceIdentifierFileName="$(InputName)_i.c"
+ ProxyFileName="$(InputName)_p.c"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..\..\src,..\..\src\gen"
+ PreprocessorDefinitions="NDEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;_AMD64_;_WIN64;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
+ RuntimeLibrary="2"
+ RuntimeTypeInfo="true"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="false"
+ DisableSpecificWarnings="4244;4800"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ PreprocessorDefinitions="NDEBUG;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS;_WIN64"
+ Culture="1033"
+ AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..\..\src,..\..\src\gen"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalOptions="/machine:AMD64"
+ AdditionalDependencies="qpidcommon.lib qpidclient.lib"
+ OutputFile="$(OutDir)\direct_producer.exe"
+ LinkIncremental="1"
+ SuppressStartupBanner="true"
+ AdditionalLibraryDirectories=".;$(BOOST_ROOT)\lib;..\..\src"
+ GenerateDebugInformation="true"
+ SubSystem="1"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ TargetMachine="17"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ </Configurations>
+ <References>
+ </References>
+ <Files>
+ <Filter
+ Name="Source Files"
+ Filter="cpp;cxx;cc;C;c">
+ <File
+ RelativePath="direct_producer.cpp">
+ </File>
+ </Filter>
+ <Filter
+ Name="Header Files"
+ Filter="h;hpp;hxx;hh">
+ <File
+ RelativePath="ConnectionOptions.h">
+ </File>
+ <File
+ RelativePath="TestOptions.h">
+ </File>
+ </Filter>
+ </Files>
+ <Globals>
+ </Globals>
+</VisualStudioProject>
diff --git a/qpid/cpp/examples/direct/direct_listener.vcproj b/qpid/cpp/examples/direct/direct_listener.vcproj
new file mode 100644
index 0000000000..72e9e15748
--- /dev/null
+++ b/qpid/cpp/examples/direct/direct_listener.vcproj
@@ -0,0 +1,374 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="9.00"
+ Name="direct_listener"
+ ProjectGUID="{95CE1459-FECA-1BAD-4346-8C4DF2536AA5}"
+ RootNamespace="direct_listener"
+ Keyword="Win32Proj"
+ SignManifests="true"
+ >
+ <Platforms>
+ <Platform
+ Name="Win32"
+ />
+ <Platform
+ Name="x64"
+ />
+ </Platforms>
+ <ToolFiles>
+ </ToolFiles>
+ <Configurations>
+ <Configuration
+ Name="Debug|Win32"
+ OutputDirectory="."
+ IntermediateDirectory="Debug\direct_listener\I386"
+ ConfigurationType="1"
+ CharacterSet="0"
+
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ AdditionalOptions=""
+ AdditionalIncludeDirectories=""
+ TypeLibraryName="$(InputName).tlb"
+ HeaderFileName="$(InputName).h"
+ InterfaceIdentifierFileName="$(InputName)_i.c"
+ ProxyFileName="$(InputName)_p.c"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..\..\src,..\..\src\gen"
+ PreprocessorDefinitions="_DEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
+ MinimalRebuild="false"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="3"
+ RuntimeTypeInfo="true"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="false"
+ DebugInformationFormat="3"
+ DisableSpecificWarnings="4244;4800"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ PreprocessorDefinitions="_DEBUG;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
+ Culture="1033"
+ AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..\..\src,..\..\src\gen"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="qpidcommond.lib qpidclientd.lib"
+ OutputFile="$(OutDir)\listener.exe"
+ LinkIncremental="2"
+ SuppressStartupBanner="true"
+ AdditionalLibraryDirectories=".;$(BOOST_ROOT)\lib;..\..\src"
+ GenerateDebugInformation="true"
+ SubSystem="1"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|Win32"
+ OutputDirectory="Release"
+ IntermediateDirectory="Release\direct_listener\I386"
+ ConfigurationType="1"
+ CharacterSet="0"
+
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ AdditionalOptions=""
+ AdditionalIncludeDirectories=""
+ TypeLibraryName="$(InputName).tlb"
+ HeaderFileName="$(InputName).h"
+ InterfaceIdentifierFileName="$(InputName)_i.c"
+ ProxyFileName="$(InputName)_p.c"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..\..\src,..\..\src\gen"
+ PreprocessorDefinitions="NDEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
+ RuntimeLibrary="2"
+ RuntimeTypeInfo="true"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="false"
+ DisableSpecificWarnings="4244;4800"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ PreprocessorDefinitions="NDEBUG;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
+ Culture="1033"
+ AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..\..\src,..\..\src\gen"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="qpidcommon.lib qpidclient.lib"
+ OutputFile="$(OutDir)\listener.exe"
+ LinkIncremental="1"
+ SuppressStartupBanner="true"
+ AdditionalLibraryDirectories=".;$(BOOST_ROOT)\lib;..\..\src"
+ GenerateDebugInformation="true"
+ SubSystem="1"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Debug|x64"
+ OutputDirectory="."
+ IntermediateDirectory="Debug\direct_listener\AMD64"
+ ConfigurationType="1"
+ CharacterSet="0"
+
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ AdditionalOptions=""
+ AdditionalIncludeDirectories=""
+ TypeLibraryName="$(InputName).tlb"
+ HeaderFileName="$(InputName).h"
+ InterfaceIdentifierFileName="$(InputName)_i.c"
+ ProxyFileName="$(InputName)_p.c"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..\..\src,..\..\src\gen"
+ PreprocessorDefinitions="_DEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;_AMD64_;_WIN64;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
+ MinimalRebuild="false"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="3"
+ RuntimeTypeInfo="true"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="false"
+ DebugInformationFormat="3"
+ DisableSpecificWarnings="4244;4800"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ PreprocessorDefinitions="_DEBUG;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS;_WIN64"
+ Culture="1033"
+ AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..\..\src,..\..\src\gen"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalOptions="/machine:AMD64"
+ AdditionalDependencies="qpidcommond.lib qpidclientd.lib"
+ OutputFile="$(OutDir)\listener.exe"
+ LinkIncremental="2"
+ SuppressStartupBanner="true"
+ AdditionalLibraryDirectories=".;$(BOOST_ROOT)\lib;..\..\src"
+ GenerateDebugInformation="true"
+ SubSystem="1"
+ TargetMachine="17"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|x64"
+ OutputDirectory="Release"
+ IntermediateDirectory="Release\direct_listener\AMD64"
+ ConfigurationType="1"
+ CharacterSet="0"
+
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ AdditionalOptions=""
+ AdditionalIncludeDirectories=""
+ TypeLibraryName="$(InputName).tlb"
+ HeaderFileName="$(InputName).h"
+ InterfaceIdentifierFileName="$(InputName)_i.c"
+ ProxyFileName="$(InputName)_p.c"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..\..\src,..\..\src\gen"
+ PreprocessorDefinitions="NDEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;_AMD64_;_WIN64;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
+ RuntimeLibrary="2"
+ RuntimeTypeInfo="true"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="false"
+ DisableSpecificWarnings="4244;4800"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ PreprocessorDefinitions="NDEBUG;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS;_WIN64"
+ Culture="1033"
+ AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..\..\src,..\..\src\gen"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalOptions="/machine:AMD64"
+ AdditionalDependencies="qpidcommon.lib qpidclient.lib"
+ OutputFile="$(OutDir)\listener.exe"
+ LinkIncremental="1"
+ SuppressStartupBanner="true"
+ AdditionalLibraryDirectories=".;$(BOOST_ROOT)\lib;..\..\src"
+ GenerateDebugInformation="true"
+ SubSystem="1"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ TargetMachine="17"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ </Configurations>
+ <References>
+ </References>
+ <Files>
+ <Filter
+ Name="Source Files"
+ Filter="cpp;cxx;cc;C;c">
+ <File
+ RelativePath="listener.cpp">
+ </File>
+ </Filter>
+ <Filter
+ Name="Header Files"
+ Filter="h;hpp;hxx;hh">
+ <File
+ RelativePath="ConnectionOptions.h">
+ </File>
+ <File
+ RelativePath="TestOptions.h">
+ </File>
+ </Filter>
+ </Files>
+ <Globals>
+ </Globals>
+</VisualStudioProject>
diff --git a/qpid/cpp/examples/direct/direct_producer.cpp b/qpid/cpp/examples/direct/direct_producer.cpp
index 7cca1955cf..ecc9675189 100644
--- a/qpid/cpp/examples/direct/direct_producer.cpp
+++ b/qpid/cpp/examples/direct/direct_producer.cpp
@@ -50,7 +50,6 @@
#include <qpid/client/Message.h>
-#include <unistd.h>
#include <cstdlib>
#include <iostream>
diff --git a/qpid/cpp/examples/direct/listener.cpp b/qpid/cpp/examples/direct/listener.cpp
index 55229df8a3..38bf24ec41 100644
--- a/qpid/cpp/examples/direct/listener.cpp
+++ b/qpid/cpp/examples/direct/listener.cpp
@@ -49,7 +49,6 @@
#include <qpid/client/MessageListener.h>
#include <qpid/client/SubscriptionManager.h>
-#include <unistd.h>
#include <cstdlib>
#include <iostream>
diff --git a/qpid/cpp/examples/examples.sln b/qpid/cpp/examples/examples.sln
new file mode 100644
index 0000000000..e7e6fcb53c
--- /dev/null
+++ b/qpid/cpp/examples/examples.sln
@@ -0,0 +1,213 @@
+
+Microsoft Visual Studio Solution File, Format Version 10.00
+# Visual Studio 2008
+# $Id: VC9WorkspaceCreator.pm 1439 2008-07-10 14:31:19Z elliott_c $
+#
+# This file was generated by MPC. Any changes made directly to
+# this file will be lost the next time it is generated.
+#
+# MPC Command:
+# C:\ace\MPC\mwc.pl -type vc9 -features boost=1 examples.mwc
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "direct_declare_queues", "direct\direct_declare_queues.vcproj", "{18165D4D-FECA-1BAD-4346-8C4DF2536AA5}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "direct_direct_producer", "direct\direct_direct_producer.vcproj", "{9701E0BD-FECA-1BAD-4346-8C4DF2536AA5}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "direct_listener", "direct\direct_listener.vcproj", "{95CE1459-FECA-1BAD-4346-8C4DF2536AA5}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "failover_declare_queues", "failover\failover_declare_queues.vcproj", "{7817898E-FECA-1BAD-8026-8D997AD361D0}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "failover_replaying_sender", "failover\failover_replaying_sender.vcproj", "{085D6A66-FECA-1BAD-8026-8D997AD361D0}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "failover_resuming_receiver", "failover\failover_resuming_receiver.vcproj", "{B0DAF702-FECA-1BAD-8026-8D997AD361D0}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "fanout_fanout_producer", "fanout\fanout_fanout_producer.vcproj", "{972AB76B-FECA-1BAD-8826-8C64F27AA1C5}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "fanout_listener", "fanout\fanout_listener.vcproj", "{95E7DF39-FECA-1BAD-8826-8C64F27AA1C5}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "pub_sub_topic_listener", "pub-sub\pub_sub_topic_listener.vcproj", "{A415E66A-FECA-1BAD-A430-FD5330E23A2D}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "pub_sub_topic_publisher", "pub-sub\pub_sub_topic_publisher.vcproj", "{05158653-FECA-1BAD-A430-FD5330E23A2D}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "qmf_console_console", "qmf-console\qmf_console_console.vcproj", "{490473E1-FECA-1BAD-2E13-3FFA2B8669C3}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "qmf_console_ping", "qmf-console\qmf_console_ping.vcproj", "{771767FB-FECA-1BAD-2E13-3FFA2B8669C3}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "qmf_console_printevents", "qmf-console\qmf_console_printevents.vcproj", "{72C74624-FECA-1BAD-2E13-3FFA2B8669C3}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "qmf_console_queuestats", "qmf-console\qmf_console_queuestats.vcproj", "{B21825EA-FECA-1BAD-2E13-3FFA2B8669C3}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "request_response_client", "request-response\request_response_client.vcproj", "{2691FE1E-FECA-1BAD-BD3A-8A467D0C5CCC}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "request_response_server", "request-response\request_response_server.vcproj", "{46817425-FECA-1BAD-BD3A-8A467D0C5CCC}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "tradedemo_declare_queues", "tradedemo\tradedemo_declare_queues.vcproj", "{9057502D-FECA-1BAD-23CE-CD4095BD3C8B}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "tradedemo_topic_listener", "tradedemo\tradedemo_topic_listener.vcproj", "{5A25F2CD-FECA-1BAD-23CE-CD4095BD3C8B}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "tradedemo_topic_publisher", "tradedemo\tradedemo_topic_publisher.vcproj", "{E614CC2C-FECA-1BAD-23CE-CD4095BD3C8B}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Win32 = Debug|Win32
+ Debug|x64 = Debug|x64
+ Release|Win32 = Release|Win32
+ Release|x64 = Release|x64
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {18165D4D-FECA-1BAD-4346-8C4DF2536AA5}.Debug|Win32.ActiveCfg = Debug|Win32
+ {18165D4D-FECA-1BAD-4346-8C4DF2536AA5}.Debug|Win32.Build.0 = Debug|Win32
+ {18165D4D-FECA-1BAD-4346-8C4DF2536AA5}.Debug|x64.ActiveCfg = Debug|x64
+ {18165D4D-FECA-1BAD-4346-8C4DF2536AA5}.Debug|x64.Build.0 = Debug|x64
+ {18165D4D-FECA-1BAD-4346-8C4DF2536AA5}.Release|Win32.ActiveCfg = Release|Win32
+ {18165D4D-FECA-1BAD-4346-8C4DF2536AA5}.Release|Win32.Build.0 = Release|Win32
+ {18165D4D-FECA-1BAD-4346-8C4DF2536AA5}.Release|x64.ActiveCfg = Release|x64
+ {18165D4D-FECA-1BAD-4346-8C4DF2536AA5}.Release|x64.Build.0 = Release|x64
+ {9701E0BD-FECA-1BAD-4346-8C4DF2536AA5}.Debug|Win32.ActiveCfg = Debug|Win32
+ {9701E0BD-FECA-1BAD-4346-8C4DF2536AA5}.Debug|Win32.Build.0 = Debug|Win32
+ {9701E0BD-FECA-1BAD-4346-8C4DF2536AA5}.Debug|x64.ActiveCfg = Debug|x64
+ {9701E0BD-FECA-1BAD-4346-8C4DF2536AA5}.Debug|x64.Build.0 = Debug|x64
+ {9701E0BD-FECA-1BAD-4346-8C4DF2536AA5}.Release|Win32.ActiveCfg = Release|Win32
+ {9701E0BD-FECA-1BAD-4346-8C4DF2536AA5}.Release|Win32.Build.0 = Release|Win32
+ {9701E0BD-FECA-1BAD-4346-8C4DF2536AA5}.Release|x64.ActiveCfg = Release|x64
+ {9701E0BD-FECA-1BAD-4346-8C4DF2536AA5}.Release|x64.Build.0 = Release|x64
+ {95CE1459-FECA-1BAD-4346-8C4DF2536AA5}.Debug|Win32.ActiveCfg = Debug|Win32
+ {95CE1459-FECA-1BAD-4346-8C4DF2536AA5}.Debug|Win32.Build.0 = Debug|Win32
+ {95CE1459-FECA-1BAD-4346-8C4DF2536AA5}.Debug|x64.ActiveCfg = Debug|x64
+ {95CE1459-FECA-1BAD-4346-8C4DF2536AA5}.Debug|x64.Build.0 = Debug|x64
+ {95CE1459-FECA-1BAD-4346-8C4DF2536AA5}.Release|Win32.ActiveCfg = Release|Win32
+ {95CE1459-FECA-1BAD-4346-8C4DF2536AA5}.Release|Win32.Build.0 = Release|Win32
+ {95CE1459-FECA-1BAD-4346-8C4DF2536AA5}.Release|x64.ActiveCfg = Release|x64
+ {95CE1459-FECA-1BAD-4346-8C4DF2536AA5}.Release|x64.Build.0 = Release|x64
+ {7817898E-FECA-1BAD-8026-8D997AD361D0}.Debug|Win32.ActiveCfg = Debug|Win32
+ {7817898E-FECA-1BAD-8026-8D997AD361D0}.Debug|Win32.Build.0 = Debug|Win32
+ {7817898E-FECA-1BAD-8026-8D997AD361D0}.Debug|x64.ActiveCfg = Debug|x64
+ {7817898E-FECA-1BAD-8026-8D997AD361D0}.Debug|x64.Build.0 = Debug|x64
+ {7817898E-FECA-1BAD-8026-8D997AD361D0}.Release|Win32.ActiveCfg = Release|Win32
+ {7817898E-FECA-1BAD-8026-8D997AD361D0}.Release|Win32.Build.0 = Release|Win32
+ {7817898E-FECA-1BAD-8026-8D997AD361D0}.Release|x64.ActiveCfg = Release|x64
+ {7817898E-FECA-1BAD-8026-8D997AD361D0}.Release|x64.Build.0 = Release|x64
+ {085D6A66-FECA-1BAD-8026-8D997AD361D0}.Debug|Win32.ActiveCfg = Debug|Win32
+ {085D6A66-FECA-1BAD-8026-8D997AD361D0}.Debug|Win32.Build.0 = Debug|Win32
+ {085D6A66-FECA-1BAD-8026-8D997AD361D0}.Debug|x64.ActiveCfg = Debug|x64
+ {085D6A66-FECA-1BAD-8026-8D997AD361D0}.Debug|x64.Build.0 = Debug|x64
+ {085D6A66-FECA-1BAD-8026-8D997AD361D0}.Release|Win32.ActiveCfg = Release|Win32
+ {085D6A66-FECA-1BAD-8026-8D997AD361D0}.Release|Win32.Build.0 = Release|Win32
+ {085D6A66-FECA-1BAD-8026-8D997AD361D0}.Release|x64.ActiveCfg = Release|x64
+ {085D6A66-FECA-1BAD-8026-8D997AD361D0}.Release|x64.Build.0 = Release|x64
+ {B0DAF702-FECA-1BAD-8026-8D997AD361D0}.Debug|Win32.ActiveCfg = Debug|Win32
+ {B0DAF702-FECA-1BAD-8026-8D997AD361D0}.Debug|Win32.Build.0 = Debug|Win32
+ {B0DAF702-FECA-1BAD-8026-8D997AD361D0}.Debug|x64.ActiveCfg = Debug|x64
+ {B0DAF702-FECA-1BAD-8026-8D997AD361D0}.Debug|x64.Build.0 = Debug|x64
+ {B0DAF702-FECA-1BAD-8026-8D997AD361D0}.Release|Win32.ActiveCfg = Release|Win32
+ {B0DAF702-FECA-1BAD-8026-8D997AD361D0}.Release|Win32.Build.0 = Release|Win32
+ {B0DAF702-FECA-1BAD-8026-8D997AD361D0}.Release|x64.ActiveCfg = Release|x64
+ {B0DAF702-FECA-1BAD-8026-8D997AD361D0}.Release|x64.Build.0 = Release|x64
+ {972AB76B-FECA-1BAD-8826-8C64F27AA1C5}.Debug|Win32.ActiveCfg = Debug|Win32
+ {972AB76B-FECA-1BAD-8826-8C64F27AA1C5}.Debug|Win32.Build.0 = Debug|Win32
+ {972AB76B-FECA-1BAD-8826-8C64F27AA1C5}.Debug|x64.ActiveCfg = Debug|x64
+ {972AB76B-FECA-1BAD-8826-8C64F27AA1C5}.Debug|x64.Build.0 = Debug|x64
+ {972AB76B-FECA-1BAD-8826-8C64F27AA1C5}.Release|Win32.ActiveCfg = Release|Win32
+ {972AB76B-FECA-1BAD-8826-8C64F27AA1C5}.Release|Win32.Build.0 = Release|Win32
+ {972AB76B-FECA-1BAD-8826-8C64F27AA1C5}.Release|x64.ActiveCfg = Release|x64
+ {972AB76B-FECA-1BAD-8826-8C64F27AA1C5}.Release|x64.Build.0 = Release|x64
+ {95E7DF39-FECA-1BAD-8826-8C64F27AA1C5}.Debug|Win32.ActiveCfg = Debug|Win32
+ {95E7DF39-FECA-1BAD-8826-8C64F27AA1C5}.Debug|Win32.Build.0 = Debug|Win32
+ {95E7DF39-FECA-1BAD-8826-8C64F27AA1C5}.Debug|x64.ActiveCfg = Debug|x64
+ {95E7DF39-FECA-1BAD-8826-8C64F27AA1C5}.Debug|x64.Build.0 = Debug|x64
+ {95E7DF39-FECA-1BAD-8826-8C64F27AA1C5}.Release|Win32.ActiveCfg = Release|Win32
+ {95E7DF39-FECA-1BAD-8826-8C64F27AA1C5}.Release|Win32.Build.0 = Release|Win32
+ {95E7DF39-FECA-1BAD-8826-8C64F27AA1C5}.Release|x64.ActiveCfg = Release|x64
+ {95E7DF39-FECA-1BAD-8826-8C64F27AA1C5}.Release|x64.Build.0 = Release|x64
+ {A415E66A-FECA-1BAD-A430-FD5330E23A2D}.Debug|Win32.ActiveCfg = Debug|Win32
+ {A415E66A-FECA-1BAD-A430-FD5330E23A2D}.Debug|Win32.Build.0 = Debug|Win32
+ {A415E66A-FECA-1BAD-A430-FD5330E23A2D}.Debug|x64.ActiveCfg = Debug|x64
+ {A415E66A-FECA-1BAD-A430-FD5330E23A2D}.Debug|x64.Build.0 = Debug|x64
+ {A415E66A-FECA-1BAD-A430-FD5330E23A2D}.Release|Win32.ActiveCfg = Release|Win32
+ {A415E66A-FECA-1BAD-A430-FD5330E23A2D}.Release|Win32.Build.0 = Release|Win32
+ {A415E66A-FECA-1BAD-A430-FD5330E23A2D}.Release|x64.ActiveCfg = Release|x64
+ {A415E66A-FECA-1BAD-A430-FD5330E23A2D}.Release|x64.Build.0 = Release|x64
+ {05158653-FECA-1BAD-A430-FD5330E23A2D}.Debug|Win32.ActiveCfg = Debug|Win32
+ {05158653-FECA-1BAD-A430-FD5330E23A2D}.Debug|Win32.Build.0 = Debug|Win32
+ {05158653-FECA-1BAD-A430-FD5330E23A2D}.Debug|x64.ActiveCfg = Debug|x64
+ {05158653-FECA-1BAD-A430-FD5330E23A2D}.Debug|x64.Build.0 = Debug|x64
+ {05158653-FECA-1BAD-A430-FD5330E23A2D}.Release|Win32.ActiveCfg = Release|Win32
+ {05158653-FECA-1BAD-A430-FD5330E23A2D}.Release|Win32.Build.0 = Release|Win32
+ {05158653-FECA-1BAD-A430-FD5330E23A2D}.Release|x64.ActiveCfg = Release|x64
+ {05158653-FECA-1BAD-A430-FD5330E23A2D}.Release|x64.Build.0 = Release|x64
+ {490473E1-FECA-1BAD-2E13-3FFA2B8669C3}.Debug|Win32.ActiveCfg = Debug|Win32
+ {490473E1-FECA-1BAD-2E13-3FFA2B8669C3}.Debug|Win32.Build.0 = Debug|Win32
+ {490473E1-FECA-1BAD-2E13-3FFA2B8669C3}.Debug|x64.ActiveCfg = Debug|x64
+ {490473E1-FECA-1BAD-2E13-3FFA2B8669C3}.Debug|x64.Build.0 = Debug|x64
+ {490473E1-FECA-1BAD-2E13-3FFA2B8669C3}.Release|Win32.ActiveCfg = Release|Win32
+ {490473E1-FECA-1BAD-2E13-3FFA2B8669C3}.Release|Win32.Build.0 = Release|Win32
+ {490473E1-FECA-1BAD-2E13-3FFA2B8669C3}.Release|x64.ActiveCfg = Release|x64
+ {490473E1-FECA-1BAD-2E13-3FFA2B8669C3}.Release|x64.Build.0 = Release|x64
+ {771767FB-FECA-1BAD-2E13-3FFA2B8669C3}.Debug|Win32.ActiveCfg = Debug|Win32
+ {771767FB-FECA-1BAD-2E13-3FFA2B8669C3}.Debug|Win32.Build.0 = Debug|Win32
+ {771767FB-FECA-1BAD-2E13-3FFA2B8669C3}.Debug|x64.ActiveCfg = Debug|x64
+ {771767FB-FECA-1BAD-2E13-3FFA2B8669C3}.Debug|x64.Build.0 = Debug|x64
+ {771767FB-FECA-1BAD-2E13-3FFA2B8669C3}.Release|Win32.ActiveCfg = Release|Win32
+ {771767FB-FECA-1BAD-2E13-3FFA2B8669C3}.Release|Win32.Build.0 = Release|Win32
+ {771767FB-FECA-1BAD-2E13-3FFA2B8669C3}.Release|x64.ActiveCfg = Release|x64
+ {771767FB-FECA-1BAD-2E13-3FFA2B8669C3}.Release|x64.Build.0 = Release|x64
+ {72C74624-FECA-1BAD-2E13-3FFA2B8669C3}.Debug|Win32.ActiveCfg = Debug|Win32
+ {72C74624-FECA-1BAD-2E13-3FFA2B8669C3}.Debug|Win32.Build.0 = Debug|Win32
+ {72C74624-FECA-1BAD-2E13-3FFA2B8669C3}.Debug|x64.ActiveCfg = Debug|x64
+ {72C74624-FECA-1BAD-2E13-3FFA2B8669C3}.Debug|x64.Build.0 = Debug|x64
+ {72C74624-FECA-1BAD-2E13-3FFA2B8669C3}.Release|Win32.ActiveCfg = Release|Win32
+ {72C74624-FECA-1BAD-2E13-3FFA2B8669C3}.Release|Win32.Build.0 = Release|Win32
+ {72C74624-FECA-1BAD-2E13-3FFA2B8669C3}.Release|x64.ActiveCfg = Release|x64
+ {72C74624-FECA-1BAD-2E13-3FFA2B8669C3}.Release|x64.Build.0 = Release|x64
+ {B21825EA-FECA-1BAD-2E13-3FFA2B8669C3}.Debug|Win32.ActiveCfg = Debug|Win32
+ {B21825EA-FECA-1BAD-2E13-3FFA2B8669C3}.Debug|Win32.Build.0 = Debug|Win32
+ {B21825EA-FECA-1BAD-2E13-3FFA2B8669C3}.Debug|x64.ActiveCfg = Debug|x64
+ {B21825EA-FECA-1BAD-2E13-3FFA2B8669C3}.Debug|x64.Build.0 = Debug|x64
+ {B21825EA-FECA-1BAD-2E13-3FFA2B8669C3}.Release|Win32.ActiveCfg = Release|Win32
+ {B21825EA-FECA-1BAD-2E13-3FFA2B8669C3}.Release|Win32.Build.0 = Release|Win32
+ {B21825EA-FECA-1BAD-2E13-3FFA2B8669C3}.Release|x64.ActiveCfg = Release|x64
+ {B21825EA-FECA-1BAD-2E13-3FFA2B8669C3}.Release|x64.Build.0 = Release|x64
+ {2691FE1E-FECA-1BAD-BD3A-8A467D0C5CCC}.Debug|Win32.ActiveCfg = Debug|Win32
+ {2691FE1E-FECA-1BAD-BD3A-8A467D0C5CCC}.Debug|Win32.Build.0 = Debug|Win32
+ {2691FE1E-FECA-1BAD-BD3A-8A467D0C5CCC}.Debug|x64.ActiveCfg = Debug|x64
+ {2691FE1E-FECA-1BAD-BD3A-8A467D0C5CCC}.Debug|x64.Build.0 = Debug|x64
+ {2691FE1E-FECA-1BAD-BD3A-8A467D0C5CCC}.Release|Win32.ActiveCfg = Release|Win32
+ {2691FE1E-FECA-1BAD-BD3A-8A467D0C5CCC}.Release|Win32.Build.0 = Release|Win32
+ {2691FE1E-FECA-1BAD-BD3A-8A467D0C5CCC}.Release|x64.ActiveCfg = Release|x64
+ {2691FE1E-FECA-1BAD-BD3A-8A467D0C5CCC}.Release|x64.Build.0 = Release|x64
+ {46817425-FECA-1BAD-BD3A-8A467D0C5CCC}.Debug|Win32.ActiveCfg = Debug|Win32
+ {46817425-FECA-1BAD-BD3A-8A467D0C5CCC}.Debug|Win32.Build.0 = Debug|Win32
+ {46817425-FECA-1BAD-BD3A-8A467D0C5CCC}.Debug|x64.ActiveCfg = Debug|x64
+ {46817425-FECA-1BAD-BD3A-8A467D0C5CCC}.Debug|x64.Build.0 = Debug|x64
+ {46817425-FECA-1BAD-BD3A-8A467D0C5CCC}.Release|Win32.ActiveCfg = Release|Win32
+ {46817425-FECA-1BAD-BD3A-8A467D0C5CCC}.Release|Win32.Build.0 = Release|Win32
+ {46817425-FECA-1BAD-BD3A-8A467D0C5CCC}.Release|x64.ActiveCfg = Release|x64
+ {46817425-FECA-1BAD-BD3A-8A467D0C5CCC}.Release|x64.Build.0 = Release|x64
+ {9057502D-FECA-1BAD-23CE-CD4095BD3C8B}.Debug|Win32.ActiveCfg = Debug|Win32
+ {9057502D-FECA-1BAD-23CE-CD4095BD3C8B}.Debug|Win32.Build.0 = Debug|Win32
+ {9057502D-FECA-1BAD-23CE-CD4095BD3C8B}.Debug|x64.ActiveCfg = Debug|x64
+ {9057502D-FECA-1BAD-23CE-CD4095BD3C8B}.Debug|x64.Build.0 = Debug|x64
+ {9057502D-FECA-1BAD-23CE-CD4095BD3C8B}.Release|Win32.ActiveCfg = Release|Win32
+ {9057502D-FECA-1BAD-23CE-CD4095BD3C8B}.Release|Win32.Build.0 = Release|Win32
+ {9057502D-FECA-1BAD-23CE-CD4095BD3C8B}.Release|x64.ActiveCfg = Release|x64
+ {9057502D-FECA-1BAD-23CE-CD4095BD3C8B}.Release|x64.Build.0 = Release|x64
+ {5A25F2CD-FECA-1BAD-23CE-CD4095BD3C8B}.Debug|Win32.ActiveCfg = Debug|Win32
+ {5A25F2CD-FECA-1BAD-23CE-CD4095BD3C8B}.Debug|Win32.Build.0 = Debug|Win32
+ {5A25F2CD-FECA-1BAD-23CE-CD4095BD3C8B}.Debug|x64.ActiveCfg = Debug|x64
+ {5A25F2CD-FECA-1BAD-23CE-CD4095BD3C8B}.Debug|x64.Build.0 = Debug|x64
+ {5A25F2CD-FECA-1BAD-23CE-CD4095BD3C8B}.Release|Win32.ActiveCfg = Release|Win32
+ {5A25F2CD-FECA-1BAD-23CE-CD4095BD3C8B}.Release|Win32.Build.0 = Release|Win32
+ {5A25F2CD-FECA-1BAD-23CE-CD4095BD3C8B}.Release|x64.ActiveCfg = Release|x64
+ {5A25F2CD-FECA-1BAD-23CE-CD4095BD3C8B}.Release|x64.Build.0 = Release|x64
+ {E614CC2C-FECA-1BAD-23CE-CD4095BD3C8B}.Debug|Win32.ActiveCfg = Debug|Win32
+ {E614CC2C-FECA-1BAD-23CE-CD4095BD3C8B}.Debug|Win32.Build.0 = Debug|Win32
+ {E614CC2C-FECA-1BAD-23CE-CD4095BD3C8B}.Debug|x64.ActiveCfg = Debug|x64
+ {E614CC2C-FECA-1BAD-23CE-CD4095BD3C8B}.Debug|x64.Build.0 = Debug|x64
+ {E614CC2C-FECA-1BAD-23CE-CD4095BD3C8B}.Release|Win32.ActiveCfg = Release|Win32
+ {E614CC2C-FECA-1BAD-23CE-CD4095BD3C8B}.Release|Win32.Build.0 = Release|Win32
+ {E614CC2C-FECA-1BAD-23CE-CD4095BD3C8B}.Release|x64.ActiveCfg = Release|x64
+ {E614CC2C-FECA-1BAD-23CE-CD4095BD3C8B}.Release|x64.Build.0 = Release|x64
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+EndGlobal
diff --git a/qpid/cpp/examples/failover/Makefile.am b/qpid/cpp/examples/failover/Makefile.am
index c41f26eaba..67d9eb4b95 100644
--- a/qpid/cpp/examples/failover/Makefile.am
+++ b/qpid/cpp/examples/failover/Makefile.am
@@ -18,6 +18,7 @@
#
examplesdir=$(pkgdatadir)/examples/failover
+MAKELDFLAGS=$(CLIENTFLAGS)
include $(top_srcdir)/examples/makedist.mk
noinst_PROGRAMS=declare_queues resuming_receiver replaying_sender
diff --git a/qpid/cpp/examples/failover/failover_declare_queues.vcproj b/qpid/cpp/examples/failover/failover_declare_queues.vcproj
new file mode 100644
index 0000000000..918c02e942
--- /dev/null
+++ b/qpid/cpp/examples/failover/failover_declare_queues.vcproj
@@ -0,0 +1,374 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="9.00"
+ Name="failover_declare_queues"
+ ProjectGUID="{7817898E-FECA-1BAD-8026-8D997AD361D0}"
+ RootNamespace="failover_declare_queues"
+ Keyword="Win32Proj"
+ SignManifests="true"
+ >
+ <Platforms>
+ <Platform
+ Name="Win32"
+ />
+ <Platform
+ Name="x64"
+ />
+ </Platforms>
+ <ToolFiles>
+ </ToolFiles>
+ <Configurations>
+ <Configuration
+ Name="Debug|Win32"
+ OutputDirectory="."
+ IntermediateDirectory="Debug\failover_declare_queues\I386"
+ ConfigurationType="1"
+ CharacterSet="0"
+
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ AdditionalOptions=""
+ AdditionalIncludeDirectories=""
+ TypeLibraryName="$(InputName).tlb"
+ HeaderFileName="$(InputName).h"
+ InterfaceIdentifierFileName="$(InputName)_i.c"
+ ProxyFileName="$(InputName)_p.c"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..\..\src,..\..\src\gen"
+ PreprocessorDefinitions="_DEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
+ MinimalRebuild="false"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="3"
+ RuntimeTypeInfo="true"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="false"
+ DebugInformationFormat="3"
+ DisableSpecificWarnings="4244;4800"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ PreprocessorDefinitions="_DEBUG;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
+ Culture="1033"
+ AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..\..\src,..\..\src\gen"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="qpidcommond.lib qpidclientd.lib"
+ OutputFile="$(OutDir)\declare_queues.exe"
+ LinkIncremental="2"
+ SuppressStartupBanner="true"
+ AdditionalLibraryDirectories=".;$(BOOST_ROOT)\lib;..\..\src"
+ GenerateDebugInformation="true"
+ SubSystem="1"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|Win32"
+ OutputDirectory="Release"
+ IntermediateDirectory="Release\failover_declare_queues\I386"
+ ConfigurationType="1"
+ CharacterSet="0"
+
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ AdditionalOptions=""
+ AdditionalIncludeDirectories=""
+ TypeLibraryName="$(InputName).tlb"
+ HeaderFileName="$(InputName).h"
+ InterfaceIdentifierFileName="$(InputName)_i.c"
+ ProxyFileName="$(InputName)_p.c"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..\..\src,..\..\src\gen"
+ PreprocessorDefinitions="NDEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
+ RuntimeLibrary="2"
+ RuntimeTypeInfo="true"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="false"
+ DisableSpecificWarnings="4244;4800"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ PreprocessorDefinitions="NDEBUG;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
+ Culture="1033"
+ AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..\..\src,..\..\src\gen"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="qpidcommon.lib qpidclient.lib"
+ OutputFile="$(OutDir)\declare_queues.exe"
+ LinkIncremental="1"
+ SuppressStartupBanner="true"
+ AdditionalLibraryDirectories=".;$(BOOST_ROOT)\lib;..\..\src"
+ GenerateDebugInformation="true"
+ SubSystem="1"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Debug|x64"
+ OutputDirectory="."
+ IntermediateDirectory="Debug\failover_declare_queues\AMD64"
+ ConfigurationType="1"
+ CharacterSet="0"
+
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ AdditionalOptions=""
+ AdditionalIncludeDirectories=""
+ TypeLibraryName="$(InputName).tlb"
+ HeaderFileName="$(InputName).h"
+ InterfaceIdentifierFileName="$(InputName)_i.c"
+ ProxyFileName="$(InputName)_p.c"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..\..\src,..\..\src\gen"
+ PreprocessorDefinitions="_DEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;_AMD64_;_WIN64;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
+ MinimalRebuild="false"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="3"
+ RuntimeTypeInfo="true"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="false"
+ DebugInformationFormat="3"
+ DisableSpecificWarnings="4244;4800"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ PreprocessorDefinitions="_DEBUG;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS;_WIN64"
+ Culture="1033"
+ AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..\..\src,..\..\src\gen"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalOptions="/machine:AMD64"
+ AdditionalDependencies="qpidcommond.lib qpidclientd.lib"
+ OutputFile="$(OutDir)\declare_queues.exe"
+ LinkIncremental="2"
+ SuppressStartupBanner="true"
+ AdditionalLibraryDirectories=".;$(BOOST_ROOT)\lib;..\..\src"
+ GenerateDebugInformation="true"
+ SubSystem="1"
+ TargetMachine="17"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|x64"
+ OutputDirectory="Release"
+ IntermediateDirectory="Release\failover_declare_queues\AMD64"
+ ConfigurationType="1"
+ CharacterSet="0"
+
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ AdditionalOptions=""
+ AdditionalIncludeDirectories=""
+ TypeLibraryName="$(InputName).tlb"
+ HeaderFileName="$(InputName).h"
+ InterfaceIdentifierFileName="$(InputName)_i.c"
+ ProxyFileName="$(InputName)_p.c"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..\..\src,..\..\src\gen"
+ PreprocessorDefinitions="NDEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;_AMD64_;_WIN64;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
+ RuntimeLibrary="2"
+ RuntimeTypeInfo="true"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="false"
+ DisableSpecificWarnings="4244;4800"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ PreprocessorDefinitions="NDEBUG;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS;_WIN64"
+ Culture="1033"
+ AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..\..\src,..\..\src\gen"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalOptions="/machine:AMD64"
+ AdditionalDependencies="qpidcommon.lib qpidclient.lib"
+ OutputFile="$(OutDir)\declare_queues.exe"
+ LinkIncremental="1"
+ SuppressStartupBanner="true"
+ AdditionalLibraryDirectories=".;$(BOOST_ROOT)\lib;..\..\src"
+ GenerateDebugInformation="true"
+ SubSystem="1"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ TargetMachine="17"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ </Configurations>
+ <References>
+ </References>
+ <Files>
+ <Filter
+ Name="Source Files"
+ Filter="cpp;cxx;cc;C;c">
+ <File
+ RelativePath="declare_queues.cpp">
+ </File>
+ </Filter>
+ <Filter
+ Name="Header Files"
+ Filter="h;hpp;hxx;hh">
+ <File
+ RelativePath="ConnectionOptions.h">
+ </File>
+ <File
+ RelativePath="TestOptions.h">
+ </File>
+ </Filter>
+ </Files>
+ <Globals>
+ </Globals>
+</VisualStudioProject>
diff --git a/qpid/cpp/examples/failover/failover_replaying_sender.vcproj b/qpid/cpp/examples/failover/failover_replaying_sender.vcproj
new file mode 100644
index 0000000000..c1a53471e6
--- /dev/null
+++ b/qpid/cpp/examples/failover/failover_replaying_sender.vcproj
@@ -0,0 +1,374 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="9.00"
+ Name="failover_replaying_sender"
+ ProjectGUID="{085D6A66-FECA-1BAD-8026-8D997AD361D0}"
+ RootNamespace="failover_replaying_sender"
+ Keyword="Win32Proj"
+ SignManifests="true"
+ >
+ <Platforms>
+ <Platform
+ Name="Win32"
+ />
+ <Platform
+ Name="x64"
+ />
+ </Platforms>
+ <ToolFiles>
+ </ToolFiles>
+ <Configurations>
+ <Configuration
+ Name="Debug|Win32"
+ OutputDirectory="."
+ IntermediateDirectory="Debug\failover_replaying_sender\I386"
+ ConfigurationType="1"
+ CharacterSet="0"
+
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ AdditionalOptions=""
+ AdditionalIncludeDirectories=""
+ TypeLibraryName="$(InputName).tlb"
+ HeaderFileName="$(InputName).h"
+ InterfaceIdentifierFileName="$(InputName)_i.c"
+ ProxyFileName="$(InputName)_p.c"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..\..\src,..\..\src\gen"
+ PreprocessorDefinitions="_DEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
+ MinimalRebuild="false"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="3"
+ RuntimeTypeInfo="true"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="false"
+ DebugInformationFormat="3"
+ DisableSpecificWarnings="4244;4800"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ PreprocessorDefinitions="_DEBUG;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
+ Culture="1033"
+ AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..\..\src,..\..\src\gen"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="qpidcommond.lib qpidclientd.lib"
+ OutputFile="$(OutDir)\replaying_sender.exe"
+ LinkIncremental="2"
+ SuppressStartupBanner="true"
+ AdditionalLibraryDirectories=".;$(BOOST_ROOT)\lib;..\..\src"
+ GenerateDebugInformation="true"
+ SubSystem="1"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|Win32"
+ OutputDirectory="Release"
+ IntermediateDirectory="Release\failover_replaying_sender\I386"
+ ConfigurationType="1"
+ CharacterSet="0"
+
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ AdditionalOptions=""
+ AdditionalIncludeDirectories=""
+ TypeLibraryName="$(InputName).tlb"
+ HeaderFileName="$(InputName).h"
+ InterfaceIdentifierFileName="$(InputName)_i.c"
+ ProxyFileName="$(InputName)_p.c"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..\..\src,..\..\src\gen"
+ PreprocessorDefinitions="NDEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
+ RuntimeLibrary="2"
+ RuntimeTypeInfo="true"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="false"
+ DisableSpecificWarnings="4244;4800"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ PreprocessorDefinitions="NDEBUG;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
+ Culture="1033"
+ AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..\..\src,..\..\src\gen"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="qpidcommon.lib qpidclient.lib"
+ OutputFile="$(OutDir)\replaying_sender.exe"
+ LinkIncremental="1"
+ SuppressStartupBanner="true"
+ AdditionalLibraryDirectories=".;$(BOOST_ROOT)\lib;..\..\src"
+ GenerateDebugInformation="true"
+ SubSystem="1"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Debug|x64"
+ OutputDirectory="."
+ IntermediateDirectory="Debug\failover_replaying_sender\AMD64"
+ ConfigurationType="1"
+ CharacterSet="0"
+
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ AdditionalOptions=""
+ AdditionalIncludeDirectories=""
+ TypeLibraryName="$(InputName).tlb"
+ HeaderFileName="$(InputName).h"
+ InterfaceIdentifierFileName="$(InputName)_i.c"
+ ProxyFileName="$(InputName)_p.c"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..\..\src,..\..\src\gen"
+ PreprocessorDefinitions="_DEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;_AMD64_;_WIN64;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
+ MinimalRebuild="false"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="3"
+ RuntimeTypeInfo="true"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="false"
+ DebugInformationFormat="3"
+ DisableSpecificWarnings="4244;4800"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ PreprocessorDefinitions="_DEBUG;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS;_WIN64"
+ Culture="1033"
+ AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..\..\src,..\..\src\gen"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalOptions="/machine:AMD64"
+ AdditionalDependencies="qpidcommond.lib qpidclientd.lib"
+ OutputFile="$(OutDir)\replaying_sender.exe"
+ LinkIncremental="2"
+ SuppressStartupBanner="true"
+ AdditionalLibraryDirectories=".;$(BOOST_ROOT)\lib;..\..\src"
+ GenerateDebugInformation="true"
+ SubSystem="1"
+ TargetMachine="17"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|x64"
+ OutputDirectory="Release"
+ IntermediateDirectory="Release\failover_replaying_sender\AMD64"
+ ConfigurationType="1"
+ CharacterSet="0"
+
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ AdditionalOptions=""
+ AdditionalIncludeDirectories=""
+ TypeLibraryName="$(InputName).tlb"
+ HeaderFileName="$(InputName).h"
+ InterfaceIdentifierFileName="$(InputName)_i.c"
+ ProxyFileName="$(InputName)_p.c"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..\..\src,..\..\src\gen"
+ PreprocessorDefinitions="NDEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;_AMD64_;_WIN64;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
+ RuntimeLibrary="2"
+ RuntimeTypeInfo="true"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="false"
+ DisableSpecificWarnings="4244;4800"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ PreprocessorDefinitions="NDEBUG;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS;_WIN64"
+ Culture="1033"
+ AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..\..\src,..\..\src\gen"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalOptions="/machine:AMD64"
+ AdditionalDependencies="qpidcommon.lib qpidclient.lib"
+ OutputFile="$(OutDir)\replaying_sender.exe"
+ LinkIncremental="1"
+ SuppressStartupBanner="true"
+ AdditionalLibraryDirectories=".;$(BOOST_ROOT)\lib;..\..\src"
+ GenerateDebugInformation="true"
+ SubSystem="1"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ TargetMachine="17"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ </Configurations>
+ <References>
+ </References>
+ <Files>
+ <Filter
+ Name="Source Files"
+ Filter="cpp;cxx;cc;C;c">
+ <File
+ RelativePath="replaying_sender.cpp">
+ </File>
+ </Filter>
+ <Filter
+ Name="Header Files"
+ Filter="h;hpp;hxx;hh">
+ <File
+ RelativePath="ConnectionOptions.h">
+ </File>
+ <File
+ RelativePath="TestOptions.h">
+ </File>
+ </Filter>
+ </Files>
+ <Globals>
+ </Globals>
+</VisualStudioProject>
diff --git a/qpid/cpp/examples/failover/failover_resuming_receiver.vcproj b/qpid/cpp/examples/failover/failover_resuming_receiver.vcproj
new file mode 100644
index 0000000000..b62e1b5636
--- /dev/null
+++ b/qpid/cpp/examples/failover/failover_resuming_receiver.vcproj
@@ -0,0 +1,374 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="9.00"
+ Name="failover_resuming_receiver"
+ ProjectGUID="{B0DAF702-FECA-1BAD-8026-8D997AD361D0}"
+ RootNamespace="failover_resuming_receiver"
+ Keyword="Win32Proj"
+ SignManifests="true"
+ >
+ <Platforms>
+ <Platform
+ Name="Win32"
+ />
+ <Platform
+ Name="x64"
+ />
+ </Platforms>
+ <ToolFiles>
+ </ToolFiles>
+ <Configurations>
+ <Configuration
+ Name="Debug|Win32"
+ OutputDirectory="."
+ IntermediateDirectory="Debug\failover_resuming_receiver\I386"
+ ConfigurationType="1"
+ CharacterSet="0"
+
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ AdditionalOptions=""
+ AdditionalIncludeDirectories=""
+ TypeLibraryName="$(InputName).tlb"
+ HeaderFileName="$(InputName).h"
+ InterfaceIdentifierFileName="$(InputName)_i.c"
+ ProxyFileName="$(InputName)_p.c"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..\..\src,..\..\src\gen"
+ PreprocessorDefinitions="_DEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
+ MinimalRebuild="false"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="3"
+ RuntimeTypeInfo="true"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="false"
+ DebugInformationFormat="3"
+ DisableSpecificWarnings="4244;4800"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ PreprocessorDefinitions="_DEBUG;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
+ Culture="1033"
+ AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..\..\src,..\..\src\gen"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="qpidcommond.lib qpidclientd.lib"
+ OutputFile="$(OutDir)\resuming_receiver.exe"
+ LinkIncremental="2"
+ SuppressStartupBanner="true"
+ AdditionalLibraryDirectories=".;$(BOOST_ROOT)\lib;..\..\src"
+ GenerateDebugInformation="true"
+ SubSystem="1"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|Win32"
+ OutputDirectory="Release"
+ IntermediateDirectory="Release\failover_resuming_receiver\I386"
+ ConfigurationType="1"
+ CharacterSet="0"
+
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ AdditionalOptions=""
+ AdditionalIncludeDirectories=""
+ TypeLibraryName="$(InputName).tlb"
+ HeaderFileName="$(InputName).h"
+ InterfaceIdentifierFileName="$(InputName)_i.c"
+ ProxyFileName="$(InputName)_p.c"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..\..\src,..\..\src\gen"
+ PreprocessorDefinitions="NDEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
+ RuntimeLibrary="2"
+ RuntimeTypeInfo="true"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="false"
+ DisableSpecificWarnings="4244;4800"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ PreprocessorDefinitions="NDEBUG;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
+ Culture="1033"
+ AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..\..\src,..\..\src\gen"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="qpidcommon.lib qpidclient.lib"
+ OutputFile="$(OutDir)\resuming_receiver.exe"
+ LinkIncremental="1"
+ SuppressStartupBanner="true"
+ AdditionalLibraryDirectories=".;$(BOOST_ROOT)\lib;..\..\src"
+ GenerateDebugInformation="true"
+ SubSystem="1"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Debug|x64"
+ OutputDirectory="."
+ IntermediateDirectory="Debug\failover_resuming_receiver\AMD64"
+ ConfigurationType="1"
+ CharacterSet="0"
+
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ AdditionalOptions=""
+ AdditionalIncludeDirectories=""
+ TypeLibraryName="$(InputName).tlb"
+ HeaderFileName="$(InputName).h"
+ InterfaceIdentifierFileName="$(InputName)_i.c"
+ ProxyFileName="$(InputName)_p.c"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..\..\src,..\..\src\gen"
+ PreprocessorDefinitions="_DEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;_AMD64_;_WIN64;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
+ MinimalRebuild="false"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="3"
+ RuntimeTypeInfo="true"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="false"
+ DebugInformationFormat="3"
+ DisableSpecificWarnings="4244;4800"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ PreprocessorDefinitions="_DEBUG;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS;_WIN64"
+ Culture="1033"
+ AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..\..\src,..\..\src\gen"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalOptions="/machine:AMD64"
+ AdditionalDependencies="qpidcommond.lib qpidclientd.lib"
+ OutputFile="$(OutDir)\resuming_receiver.exe"
+ LinkIncremental="2"
+ SuppressStartupBanner="true"
+ AdditionalLibraryDirectories=".;$(BOOST_ROOT)\lib;..\..\src"
+ GenerateDebugInformation="true"
+ SubSystem="1"
+ TargetMachine="17"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|x64"
+ OutputDirectory="Release"
+ IntermediateDirectory="Release\failover_resuming_receiver\AMD64"
+ ConfigurationType="1"
+ CharacterSet="0"
+
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ AdditionalOptions=""
+ AdditionalIncludeDirectories=""
+ TypeLibraryName="$(InputName).tlb"
+ HeaderFileName="$(InputName).h"
+ InterfaceIdentifierFileName="$(InputName)_i.c"
+ ProxyFileName="$(InputName)_p.c"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..\..\src,..\..\src\gen"
+ PreprocessorDefinitions="NDEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;_AMD64_;_WIN64;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
+ RuntimeLibrary="2"
+ RuntimeTypeInfo="true"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="false"
+ DisableSpecificWarnings="4244;4800"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ PreprocessorDefinitions="NDEBUG;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS;_WIN64"
+ Culture="1033"
+ AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..\..\src,..\..\src\gen"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalOptions="/machine:AMD64"
+ AdditionalDependencies="qpidcommon.lib qpidclient.lib"
+ OutputFile="$(OutDir)\resuming_receiver.exe"
+ LinkIncremental="1"
+ SuppressStartupBanner="true"
+ AdditionalLibraryDirectories=".;$(BOOST_ROOT)\lib;..\..\src"
+ GenerateDebugInformation="true"
+ SubSystem="1"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ TargetMachine="17"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ </Configurations>
+ <References>
+ </References>
+ <Files>
+ <Filter
+ Name="Source Files"
+ Filter="cpp;cxx;cc;C;c">
+ <File
+ RelativePath="resuming_receiver.cpp">
+ </File>
+ </Filter>
+ <Filter
+ Name="Header Files"
+ Filter="h;hpp;hxx;hh">
+ <File
+ RelativePath="ConnectionOptions.h">
+ </File>
+ <File
+ RelativePath="TestOptions.h">
+ </File>
+ </Filter>
+ </Files>
+ <Globals>
+ </Globals>
+</VisualStudioProject>
diff --git a/qpid/cpp/examples/fanout/Makefile.am b/qpid/cpp/examples/fanout/Makefile.am
index 6cbf2c93ad..395fcec9aa 100644
--- a/qpid/cpp/examples/fanout/Makefile.am
+++ b/qpid/cpp/examples/fanout/Makefile.am
@@ -18,6 +18,7 @@
#
examplesdir=$(pkgdatadir)/examples/fanout
+MAKELDFLAGS=$(CLIENTFLAGS)
include $(top_srcdir)/examples/makedist.mk
noinst_PROGRAMS=fanout_producer listener
diff --git a/qpid/cpp/examples/fanout/fanout_fanout_producer.vcproj b/qpid/cpp/examples/fanout/fanout_fanout_producer.vcproj
new file mode 100644
index 0000000000..7addd69274
--- /dev/null
+++ b/qpid/cpp/examples/fanout/fanout_fanout_producer.vcproj
@@ -0,0 +1,374 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="9.00"
+ Name="fanout_fanout_producer"
+ ProjectGUID="{972AB76B-FECA-1BAD-8826-8C64F27AA1C5}"
+ RootNamespace="fanout_fanout_producer"
+ Keyword="Win32Proj"
+ SignManifests="true"
+ >
+ <Platforms>
+ <Platform
+ Name="Win32"
+ />
+ <Platform
+ Name="x64"
+ />
+ </Platforms>
+ <ToolFiles>
+ </ToolFiles>
+ <Configurations>
+ <Configuration
+ Name="Debug|Win32"
+ OutputDirectory="."
+ IntermediateDirectory="Debug\fanout_fanout_producer\I386"
+ ConfigurationType="1"
+ CharacterSet="0"
+
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ AdditionalOptions=""
+ AdditionalIncludeDirectories=""
+ TypeLibraryName="$(InputName).tlb"
+ HeaderFileName="$(InputName).h"
+ InterfaceIdentifierFileName="$(InputName)_i.c"
+ ProxyFileName="$(InputName)_p.c"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..\..\src,..\..\src\gen"
+ PreprocessorDefinitions="_DEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
+ MinimalRebuild="false"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="3"
+ RuntimeTypeInfo="true"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="false"
+ DebugInformationFormat="3"
+ DisableSpecificWarnings="4244;4800"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ PreprocessorDefinitions="_DEBUG;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
+ Culture="1033"
+ AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..\..\src,..\..\src\gen"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="qpidcommond.lib qpidclientd.lib"
+ OutputFile="$(OutDir)\fanout_producer.exe"
+ LinkIncremental="2"
+ SuppressStartupBanner="true"
+ AdditionalLibraryDirectories=".;$(BOOST_ROOT)\lib;..\..\src"
+ GenerateDebugInformation="true"
+ SubSystem="1"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|Win32"
+ OutputDirectory="Release"
+ IntermediateDirectory="Release\fanout_fanout_producer\I386"
+ ConfigurationType="1"
+ CharacterSet="0"
+
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ AdditionalOptions=""
+ AdditionalIncludeDirectories=""
+ TypeLibraryName="$(InputName).tlb"
+ HeaderFileName="$(InputName).h"
+ InterfaceIdentifierFileName="$(InputName)_i.c"
+ ProxyFileName="$(InputName)_p.c"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..\..\src,..\..\src\gen"
+ PreprocessorDefinitions="NDEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
+ RuntimeLibrary="2"
+ RuntimeTypeInfo="true"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="false"
+ DisableSpecificWarnings="4244;4800"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ PreprocessorDefinitions="NDEBUG;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
+ Culture="1033"
+ AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..\..\src,..\..\src\gen"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="qpidcommon.lib qpidclient.lib"
+ OutputFile="$(OutDir)\fanout_producer.exe"
+ LinkIncremental="1"
+ SuppressStartupBanner="true"
+ AdditionalLibraryDirectories=".;$(BOOST_ROOT)\lib;..\..\src"
+ GenerateDebugInformation="true"
+ SubSystem="1"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Debug|x64"
+ OutputDirectory="."
+ IntermediateDirectory="Debug\fanout_fanout_producer\AMD64"
+ ConfigurationType="1"
+ CharacterSet="0"
+
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ AdditionalOptions=""
+ AdditionalIncludeDirectories=""
+ TypeLibraryName="$(InputName).tlb"
+ HeaderFileName="$(InputName).h"
+ InterfaceIdentifierFileName="$(InputName)_i.c"
+ ProxyFileName="$(InputName)_p.c"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..\..\src,..\..\src\gen"
+ PreprocessorDefinitions="_DEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;_AMD64_;_WIN64;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
+ MinimalRebuild="false"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="3"
+ RuntimeTypeInfo="true"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="false"
+ DebugInformationFormat="3"
+ DisableSpecificWarnings="4244;4800"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ PreprocessorDefinitions="_DEBUG;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS;_WIN64"
+ Culture="1033"
+ AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..\..\src,..\..\src\gen"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalOptions="/machine:AMD64"
+ AdditionalDependencies="qpidcommond.lib qpidclientd.lib"
+ OutputFile="$(OutDir)\fanout_producer.exe"
+ LinkIncremental="2"
+ SuppressStartupBanner="true"
+ AdditionalLibraryDirectories=".;$(BOOST_ROOT)\lib;..\..\src"
+ GenerateDebugInformation="true"
+ SubSystem="1"
+ TargetMachine="17"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|x64"
+ OutputDirectory="Release"
+ IntermediateDirectory="Release\fanout_fanout_producer\AMD64"
+ ConfigurationType="1"
+ CharacterSet="0"
+
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ AdditionalOptions=""
+ AdditionalIncludeDirectories=""
+ TypeLibraryName="$(InputName).tlb"
+ HeaderFileName="$(InputName).h"
+ InterfaceIdentifierFileName="$(InputName)_i.c"
+ ProxyFileName="$(InputName)_p.c"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..\..\src,..\..\src\gen"
+ PreprocessorDefinitions="NDEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;_AMD64_;_WIN64;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
+ RuntimeLibrary="2"
+ RuntimeTypeInfo="true"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="false"
+ DisableSpecificWarnings="4244;4800"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ PreprocessorDefinitions="NDEBUG;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS;_WIN64"
+ Culture="1033"
+ AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..\..\src,..\..\src\gen"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalOptions="/machine:AMD64"
+ AdditionalDependencies="qpidcommon.lib qpidclient.lib"
+ OutputFile="$(OutDir)\fanout_producer.exe"
+ LinkIncremental="1"
+ SuppressStartupBanner="true"
+ AdditionalLibraryDirectories=".;$(BOOST_ROOT)\lib;..\..\src"
+ GenerateDebugInformation="true"
+ SubSystem="1"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ TargetMachine="17"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ </Configurations>
+ <References>
+ </References>
+ <Files>
+ <Filter
+ Name="Source Files"
+ Filter="cpp;cxx;cc;C;c">
+ <File
+ RelativePath="fanout_producer.cpp">
+ </File>
+ </Filter>
+ <Filter
+ Name="Header Files"
+ Filter="h;hpp;hxx;hh">
+ <File
+ RelativePath="ConnectionOptions.h">
+ </File>
+ <File
+ RelativePath="TestOptions.h">
+ </File>
+ </Filter>
+ </Files>
+ <Globals>
+ </Globals>
+</VisualStudioProject>
diff --git a/qpid/cpp/examples/fanout/fanout_listener.vcproj b/qpid/cpp/examples/fanout/fanout_listener.vcproj
new file mode 100644
index 0000000000..d097779e80
--- /dev/null
+++ b/qpid/cpp/examples/fanout/fanout_listener.vcproj
@@ -0,0 +1,374 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="9.00"
+ Name="fanout_listener"
+ ProjectGUID="{95E7DF39-FECA-1BAD-8826-8C64F27AA1C5}"
+ RootNamespace="fanout_listener"
+ Keyword="Win32Proj"
+ SignManifests="true"
+ >
+ <Platforms>
+ <Platform
+ Name="Win32"
+ />
+ <Platform
+ Name="x64"
+ />
+ </Platforms>
+ <ToolFiles>
+ </ToolFiles>
+ <Configurations>
+ <Configuration
+ Name="Debug|Win32"
+ OutputDirectory="."
+ IntermediateDirectory="Debug\fanout_listener\I386"
+ ConfigurationType="1"
+ CharacterSet="0"
+
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ AdditionalOptions=""
+ AdditionalIncludeDirectories=""
+ TypeLibraryName="$(InputName).tlb"
+ HeaderFileName="$(InputName).h"
+ InterfaceIdentifierFileName="$(InputName)_i.c"
+ ProxyFileName="$(InputName)_p.c"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..\..\src,..\..\src\gen"
+ PreprocessorDefinitions="_DEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
+ MinimalRebuild="false"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="3"
+ RuntimeTypeInfo="true"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="false"
+ DebugInformationFormat="3"
+ DisableSpecificWarnings="4244;4800"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ PreprocessorDefinitions="_DEBUG;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
+ Culture="1033"
+ AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..\..\src,..\..\src\gen"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="qpidcommond.lib qpidclientd.lib"
+ OutputFile="$(OutDir)\listener.exe"
+ LinkIncremental="2"
+ SuppressStartupBanner="true"
+ AdditionalLibraryDirectories=".;$(BOOST_ROOT)\lib;..\..\src"
+ GenerateDebugInformation="true"
+ SubSystem="1"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|Win32"
+ OutputDirectory="Release"
+ IntermediateDirectory="Release\fanout_listener\I386"
+ ConfigurationType="1"
+ CharacterSet="0"
+
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ AdditionalOptions=""
+ AdditionalIncludeDirectories=""
+ TypeLibraryName="$(InputName).tlb"
+ HeaderFileName="$(InputName).h"
+ InterfaceIdentifierFileName="$(InputName)_i.c"
+ ProxyFileName="$(InputName)_p.c"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..\..\src,..\..\src\gen"
+ PreprocessorDefinitions="NDEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
+ RuntimeLibrary="2"
+ RuntimeTypeInfo="true"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="false"
+ DisableSpecificWarnings="4244;4800"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ PreprocessorDefinitions="NDEBUG;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
+ Culture="1033"
+ AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..\..\src,..\..\src\gen"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="qpidcommon.lib qpidclient.lib"
+ OutputFile="$(OutDir)\listener.exe"
+ LinkIncremental="1"
+ SuppressStartupBanner="true"
+ AdditionalLibraryDirectories=".;$(BOOST_ROOT)\lib;..\..\src"
+ GenerateDebugInformation="true"
+ SubSystem="1"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Debug|x64"
+ OutputDirectory="."
+ IntermediateDirectory="Debug\fanout_listener\AMD64"
+ ConfigurationType="1"
+ CharacterSet="0"
+
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ AdditionalOptions=""
+ AdditionalIncludeDirectories=""
+ TypeLibraryName="$(InputName).tlb"
+ HeaderFileName="$(InputName).h"
+ InterfaceIdentifierFileName="$(InputName)_i.c"
+ ProxyFileName="$(InputName)_p.c"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..\..\src,..\..\src\gen"
+ PreprocessorDefinitions="_DEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;_AMD64_;_WIN64;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
+ MinimalRebuild="false"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="3"
+ RuntimeTypeInfo="true"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="false"
+ DebugInformationFormat="3"
+ DisableSpecificWarnings="4244;4800"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ PreprocessorDefinitions="_DEBUG;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS;_WIN64"
+ Culture="1033"
+ AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..\..\src,..\..\src\gen"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalOptions="/machine:AMD64"
+ AdditionalDependencies="qpidcommond.lib qpidclientd.lib"
+ OutputFile="$(OutDir)\listener.exe"
+ LinkIncremental="2"
+ SuppressStartupBanner="true"
+ AdditionalLibraryDirectories=".;$(BOOST_ROOT)\lib;..\..\src"
+ GenerateDebugInformation="true"
+ SubSystem="1"
+ TargetMachine="17"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|x64"
+ OutputDirectory="Release"
+ IntermediateDirectory="Release\fanout_listener\AMD64"
+ ConfigurationType="1"
+ CharacterSet="0"
+
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ AdditionalOptions=""
+ AdditionalIncludeDirectories=""
+ TypeLibraryName="$(InputName).tlb"
+ HeaderFileName="$(InputName).h"
+ InterfaceIdentifierFileName="$(InputName)_i.c"
+ ProxyFileName="$(InputName)_p.c"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..\..\src,..\..\src\gen"
+ PreprocessorDefinitions="NDEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;_AMD64_;_WIN64;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
+ RuntimeLibrary="2"
+ RuntimeTypeInfo="true"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="false"
+ DisableSpecificWarnings="4244;4800"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ PreprocessorDefinitions="NDEBUG;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS;_WIN64"
+ Culture="1033"
+ AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..\..\src,..\..\src\gen"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalOptions="/machine:AMD64"
+ AdditionalDependencies="qpidcommon.lib qpidclient.lib"
+ OutputFile="$(OutDir)\listener.exe"
+ LinkIncremental="1"
+ SuppressStartupBanner="true"
+ AdditionalLibraryDirectories=".;$(BOOST_ROOT)\lib;..\..\src"
+ GenerateDebugInformation="true"
+ SubSystem="1"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ TargetMachine="17"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ </Configurations>
+ <References>
+ </References>
+ <Files>
+ <Filter
+ Name="Source Files"
+ Filter="cpp;cxx;cc;C;c">
+ <File
+ RelativePath="listener.cpp">
+ </File>
+ </Filter>
+ <Filter
+ Name="Header Files"
+ Filter="h;hpp;hxx;hh">
+ <File
+ RelativePath="ConnectionOptions.h">
+ </File>
+ <File
+ RelativePath="TestOptions.h">
+ </File>
+ </Filter>
+ </Files>
+ <Globals>
+ </Globals>
+</VisualStudioProject>
diff --git a/qpid/cpp/examples/fanout/fanout_producer.cpp b/qpid/cpp/examples/fanout/fanout_producer.cpp
index fb16f7e8b1..decd4d314d 100644
--- a/qpid/cpp/examples/fanout/fanout_producer.cpp
+++ b/qpid/cpp/examples/fanout/fanout_producer.cpp
@@ -48,7 +48,6 @@
#include <qpid/client/Message.h>
-#include <unistd.h>
#include <cstdlib>
#include <iostream>
diff --git a/qpid/cpp/examples/fanout/listener.cpp b/qpid/cpp/examples/fanout/listener.cpp
index b6050ef728..cd3071c29a 100644
--- a/qpid/cpp/examples/fanout/listener.cpp
+++ b/qpid/cpp/examples/fanout/listener.cpp
@@ -48,7 +48,6 @@
#include <qpid/client/MessageListener.h>
#include <qpid/client/SubscriptionManager.h>
-#include <unistd.h>
#include <cstdlib>
#include <iostream>
diff --git a/qpid/cpp/examples/makedist.mk b/qpid/cpp/examples/makedist.mk
index 4345378983..391ddf47e7 100644
--- a/qpid/cpp/examples/makedist.mk
+++ b/qpid/cpp/examples/makedist.mk
@@ -3,20 +3,21 @@ AM_CXXFLAGS = $(WARNING_CFLAGS)
INCLUDES = -I$(top_srcdir)/src -I$(top_srcdir)/src/gen -I$(top_builddir)/src -I$(top_builddir)/src/gen
CLIENT_LIB=$(top_builddir)/src/libqpidclient.la
CONSOLE_LIB=$(top_builddir)/src/libqmfconsole.la
-MAKELDFLAG ?= qpidclient
+CLIENTFLAGS=-lqpidclient
+CONSOLEFLAGS=-lqmfconsole
# Generate a simple non-automake Makefile for distribution.
MAKEDIST=.libs/Makefile
$(MAKEDIST): Makefile
mkdir -p .libs
- @$(ECHO) CXX=$(CXX) > $(MAKEDIST)
- @$(ECHO) CXXFLAGS=$(CXXFLAGS) >> $(MAKEDIST)
- @$(ECHO) LDFLAGS=-l$(MAKELDFLAG) >> $(MAKEDIST)
- @$(ECHO) >> $(MAKEDIST)
- @$(ECHO) all: $(noinst_PROGRAMS) >> $(MAKEDIST)
- @$(ECHO) >> $(MAKEDIST)
- @$(ECHO) clean: >> $(MAKEDIST)
- @$(ECHO) " rm -f $(noinst_PROGRAMS)" >> $(MAKEDIST)
-
+ @(echo CXX=$(CXX) ; \
+ echo CXXFLAGS=$(CXXFLAGS) ; \
+ echo LDFLAGS=$(MAKELDFLAGS) ; \
+ echo ; \
+ echo all: $(noinst_PROGRAMS) ; \
+ echo ; \
+ echo clean: ; \
+ echo " rm -f $(noinst_PROGRAMS)" ; \
+ ) > $(MAKEDIST)
diff --git a/qpid/cpp/examples/pub-sub/Makefile.am b/qpid/cpp/examples/pub-sub/Makefile.am
index bdbf0f8d20..1d52daf638 100644
--- a/qpid/cpp/examples/pub-sub/Makefile.am
+++ b/qpid/cpp/examples/pub-sub/Makefile.am
@@ -18,6 +18,7 @@
#
examplesdir=$(pkgdatadir)/examples/pub-sub
+MAKELDFLAGS=$(CLIENTFLAGS)
include $(top_srcdir)/examples/makedist.mk
noinst_PROGRAMS=topic_listener topic_publisher
diff --git a/qpid/cpp/examples/pub-sub/pub_sub_topic_listener.vcproj b/qpid/cpp/examples/pub-sub/pub_sub_topic_listener.vcproj
new file mode 100644
index 0000000000..72a6543a13
--- /dev/null
+++ b/qpid/cpp/examples/pub-sub/pub_sub_topic_listener.vcproj
@@ -0,0 +1,374 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="9.00"
+ Name="pub_sub_topic_listener"
+ ProjectGUID="{A415E66A-FECA-1BAD-A430-FD5330E23A2D}"
+ RootNamespace="pub_sub_topic_listener"
+ Keyword="Win32Proj"
+ SignManifests="true"
+ >
+ <Platforms>
+ <Platform
+ Name="Win32"
+ />
+ <Platform
+ Name="x64"
+ />
+ </Platforms>
+ <ToolFiles>
+ </ToolFiles>
+ <Configurations>
+ <Configuration
+ Name="Debug|Win32"
+ OutputDirectory="."
+ IntermediateDirectory="Debug\pub_sub_topic_listener\I386"
+ ConfigurationType="1"
+ CharacterSet="0"
+
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ AdditionalOptions=""
+ AdditionalIncludeDirectories=""
+ TypeLibraryName="$(InputName).tlb"
+ HeaderFileName="$(InputName).h"
+ InterfaceIdentifierFileName="$(InputName)_i.c"
+ ProxyFileName="$(InputName)_p.c"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..\..\src,..\..\src\gen"
+ PreprocessorDefinitions="_DEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
+ MinimalRebuild="false"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="3"
+ RuntimeTypeInfo="true"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="false"
+ DebugInformationFormat="3"
+ DisableSpecificWarnings="4244;4800"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ PreprocessorDefinitions="_DEBUG;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
+ Culture="1033"
+ AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..\..\src,..\..\src\gen"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="qpidcommond.lib qpidclientd.lib"
+ OutputFile="$(OutDir)\topic_listener.exe"
+ LinkIncremental="2"
+ SuppressStartupBanner="true"
+ AdditionalLibraryDirectories=".;$(BOOST_ROOT)\lib;..\..\src"
+ GenerateDebugInformation="true"
+ SubSystem="1"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|Win32"
+ OutputDirectory="Release"
+ IntermediateDirectory="Release\pub_sub_topic_listener\I386"
+ ConfigurationType="1"
+ CharacterSet="0"
+
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ AdditionalOptions=""
+ AdditionalIncludeDirectories=""
+ TypeLibraryName="$(InputName).tlb"
+ HeaderFileName="$(InputName).h"
+ InterfaceIdentifierFileName="$(InputName)_i.c"
+ ProxyFileName="$(InputName)_p.c"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..\..\src,..\..\src\gen"
+ PreprocessorDefinitions="NDEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
+ RuntimeLibrary="2"
+ RuntimeTypeInfo="true"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="false"
+ DisableSpecificWarnings="4244;4800"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ PreprocessorDefinitions="NDEBUG;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
+ Culture="1033"
+ AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..\..\src,..\..\src\gen"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="qpidcommon.lib qpidclient.lib"
+ OutputFile="$(OutDir)\topic_listener.exe"
+ LinkIncremental="1"
+ SuppressStartupBanner="true"
+ AdditionalLibraryDirectories=".;$(BOOST_ROOT)\lib;..\..\src"
+ GenerateDebugInformation="true"
+ SubSystem="1"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Debug|x64"
+ OutputDirectory="."
+ IntermediateDirectory="Debug\pub_sub_topic_listener\AMD64"
+ ConfigurationType="1"
+ CharacterSet="0"
+
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ AdditionalOptions=""
+ AdditionalIncludeDirectories=""
+ TypeLibraryName="$(InputName).tlb"
+ HeaderFileName="$(InputName).h"
+ InterfaceIdentifierFileName="$(InputName)_i.c"
+ ProxyFileName="$(InputName)_p.c"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..\..\src,..\..\src\gen"
+ PreprocessorDefinitions="_DEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;_AMD64_;_WIN64;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
+ MinimalRebuild="false"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="3"
+ RuntimeTypeInfo="true"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="false"
+ DebugInformationFormat="3"
+ DisableSpecificWarnings="4244;4800"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ PreprocessorDefinitions="_DEBUG;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS;_WIN64"
+ Culture="1033"
+ AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..\..\src,..\..\src\gen"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalOptions="/machine:AMD64"
+ AdditionalDependencies="qpidcommond.lib qpidclientd.lib"
+ OutputFile="$(OutDir)\topic_listener.exe"
+ LinkIncremental="2"
+ SuppressStartupBanner="true"
+ AdditionalLibraryDirectories=".;$(BOOST_ROOT)\lib;..\..\src"
+ GenerateDebugInformation="true"
+ SubSystem="1"
+ TargetMachine="17"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|x64"
+ OutputDirectory="Release"
+ IntermediateDirectory="Release\pub_sub_topic_listener\AMD64"
+ ConfigurationType="1"
+ CharacterSet="0"
+
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ AdditionalOptions=""
+ AdditionalIncludeDirectories=""
+ TypeLibraryName="$(InputName).tlb"
+ HeaderFileName="$(InputName).h"
+ InterfaceIdentifierFileName="$(InputName)_i.c"
+ ProxyFileName="$(InputName)_p.c"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..\..\src,..\..\src\gen"
+ PreprocessorDefinitions="NDEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;_AMD64_;_WIN64;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
+ RuntimeLibrary="2"
+ RuntimeTypeInfo="true"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="false"
+ DisableSpecificWarnings="4244;4800"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ PreprocessorDefinitions="NDEBUG;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS;_WIN64"
+ Culture="1033"
+ AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..\..\src,..\..\src\gen"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalOptions="/machine:AMD64"
+ AdditionalDependencies="qpidcommon.lib qpidclient.lib"
+ OutputFile="$(OutDir)\topic_listener.exe"
+ LinkIncremental="1"
+ SuppressStartupBanner="true"
+ AdditionalLibraryDirectories=".;$(BOOST_ROOT)\lib;..\..\src"
+ GenerateDebugInformation="true"
+ SubSystem="1"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ TargetMachine="17"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ </Configurations>
+ <References>
+ </References>
+ <Files>
+ <Filter
+ Name="Source Files"
+ Filter="cpp;cxx;cc;C;c">
+ <File
+ RelativePath="topic_listener.cpp">
+ </File>
+ </Filter>
+ <Filter
+ Name="Header Files"
+ Filter="h;hpp;hxx;hh">
+ <File
+ RelativePath="ConnectionOptions.h">
+ </File>
+ <File
+ RelativePath="TestOptions.h">
+ </File>
+ </Filter>
+ </Files>
+ <Globals>
+ </Globals>
+</VisualStudioProject>
diff --git a/qpid/cpp/examples/pub-sub/pub_sub_topic_publisher.vcproj b/qpid/cpp/examples/pub-sub/pub_sub_topic_publisher.vcproj
new file mode 100644
index 0000000000..5182b30435
--- /dev/null
+++ b/qpid/cpp/examples/pub-sub/pub_sub_topic_publisher.vcproj
@@ -0,0 +1,374 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="9.00"
+ Name="pub_sub_topic_publisher"
+ ProjectGUID="{05158653-FECA-1BAD-A430-FD5330E23A2D}"
+ RootNamespace="pub_sub_topic_publisher"
+ Keyword="Win32Proj"
+ SignManifests="true"
+ >
+ <Platforms>
+ <Platform
+ Name="Win32"
+ />
+ <Platform
+ Name="x64"
+ />
+ </Platforms>
+ <ToolFiles>
+ </ToolFiles>
+ <Configurations>
+ <Configuration
+ Name="Debug|Win32"
+ OutputDirectory="."
+ IntermediateDirectory="Debug\pub_sub_topic_publisher\I386"
+ ConfigurationType="1"
+ CharacterSet="0"
+
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ AdditionalOptions=""
+ AdditionalIncludeDirectories=""
+ TypeLibraryName="$(InputName).tlb"
+ HeaderFileName="$(InputName).h"
+ InterfaceIdentifierFileName="$(InputName)_i.c"
+ ProxyFileName="$(InputName)_p.c"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..\..\src,..\..\src\gen"
+ PreprocessorDefinitions="_DEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
+ MinimalRebuild="false"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="3"
+ RuntimeTypeInfo="true"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="false"
+ DebugInformationFormat="3"
+ DisableSpecificWarnings="4244;4800"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ PreprocessorDefinitions="_DEBUG;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
+ Culture="1033"
+ AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..\..\src,..\..\src\gen"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="qpidcommond.lib qpidclientd.lib"
+ OutputFile="$(OutDir)\topic_publisher.exe"
+ LinkIncremental="2"
+ SuppressStartupBanner="true"
+ AdditionalLibraryDirectories=".;$(BOOST_ROOT)\lib;..\..\src"
+ GenerateDebugInformation="true"
+ SubSystem="1"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|Win32"
+ OutputDirectory="Release"
+ IntermediateDirectory="Release\pub_sub_topic_publisher\I386"
+ ConfigurationType="1"
+ CharacterSet="0"
+
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ AdditionalOptions=""
+ AdditionalIncludeDirectories=""
+ TypeLibraryName="$(InputName).tlb"
+ HeaderFileName="$(InputName).h"
+ InterfaceIdentifierFileName="$(InputName)_i.c"
+ ProxyFileName="$(InputName)_p.c"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..\..\src,..\..\src\gen"
+ PreprocessorDefinitions="NDEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
+ RuntimeLibrary="2"
+ RuntimeTypeInfo="true"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="false"
+ DisableSpecificWarnings="4244;4800"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ PreprocessorDefinitions="NDEBUG;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
+ Culture="1033"
+ AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..\..\src,..\..\src\gen"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="qpidcommon.lib qpidclient.lib"
+ OutputFile="$(OutDir)\topic_publisher.exe"
+ LinkIncremental="1"
+ SuppressStartupBanner="true"
+ AdditionalLibraryDirectories=".;$(BOOST_ROOT)\lib;..\..\src"
+ GenerateDebugInformation="true"
+ SubSystem="1"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Debug|x64"
+ OutputDirectory="."
+ IntermediateDirectory="Debug\pub_sub_topic_publisher\AMD64"
+ ConfigurationType="1"
+ CharacterSet="0"
+
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ AdditionalOptions=""
+ AdditionalIncludeDirectories=""
+ TypeLibraryName="$(InputName).tlb"
+ HeaderFileName="$(InputName).h"
+ InterfaceIdentifierFileName="$(InputName)_i.c"
+ ProxyFileName="$(InputName)_p.c"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..\..\src,..\..\src\gen"
+ PreprocessorDefinitions="_DEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;_AMD64_;_WIN64;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
+ MinimalRebuild="false"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="3"
+ RuntimeTypeInfo="true"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="false"
+ DebugInformationFormat="3"
+ DisableSpecificWarnings="4244;4800"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ PreprocessorDefinitions="_DEBUG;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS;_WIN64"
+ Culture="1033"
+ AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..\..\src,..\..\src\gen"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalOptions="/machine:AMD64"
+ AdditionalDependencies="qpidcommond.lib qpidclientd.lib"
+ OutputFile="$(OutDir)\topic_publisher.exe"
+ LinkIncremental="2"
+ SuppressStartupBanner="true"
+ AdditionalLibraryDirectories=".;$(BOOST_ROOT)\lib;..\..\src"
+ GenerateDebugInformation="true"
+ SubSystem="1"
+ TargetMachine="17"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|x64"
+ OutputDirectory="Release"
+ IntermediateDirectory="Release\pub_sub_topic_publisher\AMD64"
+ ConfigurationType="1"
+ CharacterSet="0"
+
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ AdditionalOptions=""
+ AdditionalIncludeDirectories=""
+ TypeLibraryName="$(InputName).tlb"
+ HeaderFileName="$(InputName).h"
+ InterfaceIdentifierFileName="$(InputName)_i.c"
+ ProxyFileName="$(InputName)_p.c"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..\..\src,..\..\src\gen"
+ PreprocessorDefinitions="NDEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;_AMD64_;_WIN64;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
+ RuntimeLibrary="2"
+ RuntimeTypeInfo="true"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="false"
+ DisableSpecificWarnings="4244;4800"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ PreprocessorDefinitions="NDEBUG;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS;_WIN64"
+ Culture="1033"
+ AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..\..\src,..\..\src\gen"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalOptions="/machine:AMD64"
+ AdditionalDependencies="qpidcommon.lib qpidclient.lib"
+ OutputFile="$(OutDir)\topic_publisher.exe"
+ LinkIncremental="1"
+ SuppressStartupBanner="true"
+ AdditionalLibraryDirectories=".;$(BOOST_ROOT)\lib;..\..\src"
+ GenerateDebugInformation="true"
+ SubSystem="1"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ TargetMachine="17"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ </Configurations>
+ <References>
+ </References>
+ <Files>
+ <Filter
+ Name="Source Files"
+ Filter="cpp;cxx;cc;C;c">
+ <File
+ RelativePath="topic_publisher.cpp">
+ </File>
+ </Filter>
+ <Filter
+ Name="Header Files"
+ Filter="h;hpp;hxx;hh">
+ <File
+ RelativePath="ConnectionOptions.h">
+ </File>
+ <File
+ RelativePath="TestOptions.h">
+ </File>
+ </Filter>
+ </Files>
+ <Globals>
+ </Globals>
+</VisualStudioProject>
diff --git a/qpid/cpp/examples/pub-sub/topic_listener.cpp b/qpid/cpp/examples/pub-sub/topic_listener.cpp
index fe0280cb7e..d38a806303 100644
--- a/qpid/cpp/examples/pub-sub/topic_listener.cpp
+++ b/qpid/cpp/examples/pub-sub/topic_listener.cpp
@@ -49,7 +49,6 @@
#include <qpid/client/MessageListener.h>
#include <qpid/client/SubscriptionManager.h>
-#include <unistd.h>
#include <cstdlib>
#include <iostream>
diff --git a/qpid/cpp/examples/pub-sub/topic_publisher.cpp b/qpid/cpp/examples/pub-sub/topic_publisher.cpp
index 72ba572f75..aed5f8f033 100644
--- a/qpid/cpp/examples/pub-sub/topic_publisher.cpp
+++ b/qpid/cpp/examples/pub-sub/topic_publisher.cpp
@@ -50,7 +50,6 @@
#include <qpid/client/Message.h>
-#include <unistd.h>
#include <cstdlib>
#include <iostream>
diff --git a/qpid/cpp/examples/qmf-console/Makefile.am b/qpid/cpp/examples/qmf-console/Makefile.am
index 471620f465..04a92c214e 100644
--- a/qpid/cpp/examples/qmf-console/Makefile.am
+++ b/qpid/cpp/examples/qmf-console/Makefile.am
@@ -19,7 +19,7 @@
examplesdir=$(pkgdatadir)/examples/qmf-console
-MAKELDFLAG = qmfconsole
+MAKELDFLAGS=$(CONSOLEFLAGS)
include $(top_srcdir)/examples/makedist.mk
noinst_PROGRAMS=console printevents ping queuestats
diff --git a/qpid/cpp/examples/qmf-console/ping.cpp b/qpid/cpp/examples/qmf-console/ping.cpp
index debca7428a..39ec0d3039 100644
--- a/qpid/cpp/examples/qmf-console/ping.cpp
+++ b/qpid/cpp/examples/qmf-console/ping.cpp
@@ -20,6 +20,7 @@
*/
#include "qpid/console/SessionManager.h"
+#include "qpid/sys/Time.h"
using namespace std;
using namespace qpid::console;
@@ -107,7 +108,7 @@ int main_int(int /*argc*/, char** /*argv*/)
cout << endl;
if (result.code == 0 && iter < count - 1)
- ::sleep(1);
+ qpid::sys::sleep(1);
}
}
diff --git a/qpid/cpp/examples/qmf-console/printevents.cpp b/qpid/cpp/examples/qmf-console/printevents.cpp
index 38d6f830aa..898972f28d 100644
--- a/qpid/cpp/examples/qmf-console/printevents.cpp
+++ b/qpid/cpp/examples/qmf-console/printevents.cpp
@@ -88,7 +88,7 @@ int main_int(int /*argc*/, char** /*argv*/)
// Sleep indefinitely while asynchronous events are handled by the listener.
//
for (;;)
- ::sleep(1);
+ qpid::sys::sleep(1);
sm.delBroker(broker);
return 0;
diff --git a/qpid/cpp/examples/qmf-console/qmf_console_console.vcproj b/qpid/cpp/examples/qmf-console/qmf_console_console.vcproj
new file mode 100644
index 0000000000..67e34fde98
--- /dev/null
+++ b/qpid/cpp/examples/qmf-console/qmf_console_console.vcproj
@@ -0,0 +1,374 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="9.00"
+ Name="qmf_console_console"
+ ProjectGUID="{490473E1-FECA-1BAD-2E13-3FFA2B8669C3}"
+ RootNamespace="qmf_console_console"
+ Keyword="Win32Proj"
+ SignManifests="true"
+ >
+ <Platforms>
+ <Platform
+ Name="Win32"
+ />
+ <Platform
+ Name="x64"
+ />
+ </Platforms>
+ <ToolFiles>
+ </ToolFiles>
+ <Configurations>
+ <Configuration
+ Name="Debug|Win32"
+ OutputDirectory="."
+ IntermediateDirectory="Debug\qmf_console_console\I386"
+ ConfigurationType="1"
+ CharacterSet="0"
+
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ AdditionalOptions=""
+ AdditionalIncludeDirectories=""
+ TypeLibraryName="$(InputName).tlb"
+ HeaderFileName="$(InputName).h"
+ InterfaceIdentifierFileName="$(InputName)_i.c"
+ ProxyFileName="$(InputName)_p.c"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..\..\src,..\..\src\gen"
+ PreprocessorDefinitions="_DEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
+ MinimalRebuild="false"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="3"
+ RuntimeTypeInfo="true"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="false"
+ DebugInformationFormat="3"
+ DisableSpecificWarnings="4244;4800"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ PreprocessorDefinitions="_DEBUG;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
+ Culture="1033"
+ AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..\..\src,..\..\src\gen"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="qpidcommond.lib qpidclientd.lib qmfconsoled.lib"
+ OutputFile="$(OutDir)\console.exe"
+ LinkIncremental="2"
+ SuppressStartupBanner="true"
+ AdditionalLibraryDirectories=".;$(BOOST_ROOT)\lib;..\..\src"
+ GenerateDebugInformation="true"
+ SubSystem="1"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|Win32"
+ OutputDirectory="Release"
+ IntermediateDirectory="Release\qmf_console_console\I386"
+ ConfigurationType="1"
+ CharacterSet="0"
+
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ AdditionalOptions=""
+ AdditionalIncludeDirectories=""
+ TypeLibraryName="$(InputName).tlb"
+ HeaderFileName="$(InputName).h"
+ InterfaceIdentifierFileName="$(InputName)_i.c"
+ ProxyFileName="$(InputName)_p.c"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..\..\src,..\..\src\gen"
+ PreprocessorDefinitions="NDEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
+ RuntimeLibrary="2"
+ RuntimeTypeInfo="true"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="false"
+ DisableSpecificWarnings="4244;4800"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ PreprocessorDefinitions="NDEBUG;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
+ Culture="1033"
+ AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..\..\src,..\..\src\gen"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="qpidcommon.lib qpidclient.lib qmfconsole.lib"
+ OutputFile="$(OutDir)\console.exe"
+ LinkIncremental="1"
+ SuppressStartupBanner="true"
+ AdditionalLibraryDirectories=".;$(BOOST_ROOT)\lib;..\..\src"
+ GenerateDebugInformation="true"
+ SubSystem="1"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Debug|x64"
+ OutputDirectory="."
+ IntermediateDirectory="Debug\qmf_console_console\AMD64"
+ ConfigurationType="1"
+ CharacterSet="0"
+
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ AdditionalOptions=""
+ AdditionalIncludeDirectories=""
+ TypeLibraryName="$(InputName).tlb"
+ HeaderFileName="$(InputName).h"
+ InterfaceIdentifierFileName="$(InputName)_i.c"
+ ProxyFileName="$(InputName)_p.c"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..\..\src,..\..\src\gen"
+ PreprocessorDefinitions="_DEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;_AMD64_;_WIN64;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
+ MinimalRebuild="false"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="3"
+ RuntimeTypeInfo="true"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="false"
+ DebugInformationFormat="3"
+ DisableSpecificWarnings="4244;4800"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ PreprocessorDefinitions="_DEBUG;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS;_WIN64"
+ Culture="1033"
+ AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..\..\src,..\..\src\gen"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalOptions="/machine:AMD64"
+ AdditionalDependencies="qpidcommond.lib qpidclientd.lib qmfconsoled.lib"
+ OutputFile="$(OutDir)\console.exe"
+ LinkIncremental="2"
+ SuppressStartupBanner="true"
+ AdditionalLibraryDirectories=".;$(BOOST_ROOT)\lib;..\..\src"
+ GenerateDebugInformation="true"
+ SubSystem="1"
+ TargetMachine="17"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|x64"
+ OutputDirectory="Release"
+ IntermediateDirectory="Release\qmf_console_console\AMD64"
+ ConfigurationType="1"
+ CharacterSet="0"
+
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ AdditionalOptions=""
+ AdditionalIncludeDirectories=""
+ TypeLibraryName="$(InputName).tlb"
+ HeaderFileName="$(InputName).h"
+ InterfaceIdentifierFileName="$(InputName)_i.c"
+ ProxyFileName="$(InputName)_p.c"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..\..\src,..\..\src\gen"
+ PreprocessorDefinitions="NDEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;_AMD64_;_WIN64;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
+ RuntimeLibrary="2"
+ RuntimeTypeInfo="true"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="false"
+ DisableSpecificWarnings="4244;4800"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ PreprocessorDefinitions="NDEBUG;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS;_WIN64"
+ Culture="1033"
+ AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..\..\src,..\..\src\gen"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalOptions="/machine:AMD64"
+ AdditionalDependencies="qpidcommon.lib qpidclient.lib qmfconsole.lib"
+ OutputFile="$(OutDir)\console.exe"
+ LinkIncremental="1"
+ SuppressStartupBanner="true"
+ AdditionalLibraryDirectories=".;$(BOOST_ROOT)\lib;..\..\src"
+ GenerateDebugInformation="true"
+ SubSystem="1"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ TargetMachine="17"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ </Configurations>
+ <References>
+ </References>
+ <Files>
+ <Filter
+ Name="Source Files"
+ Filter="cpp;cxx;cc;C;c">
+ <File
+ RelativePath="console.cpp">
+ </File>
+ </Filter>
+ <Filter
+ Name="Header Files"
+ Filter="h;hpp;hxx;hh">
+ <File
+ RelativePath="ConnectionOptions.h">
+ </File>
+ <File
+ RelativePath="TestOptions.h">
+ </File>
+ </Filter>
+ </Files>
+ <Globals>
+ </Globals>
+</VisualStudioProject>
diff --git a/qpid/cpp/examples/qmf-console/qmf_console_ping.vcproj b/qpid/cpp/examples/qmf-console/qmf_console_ping.vcproj
new file mode 100644
index 0000000000..daf2fd2b74
--- /dev/null
+++ b/qpid/cpp/examples/qmf-console/qmf_console_ping.vcproj
@@ -0,0 +1,374 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="9.00"
+ Name="qmf_console_ping"
+ ProjectGUID="{771767FB-FECA-1BAD-2E13-3FFA2B8669C3}"
+ RootNamespace="qmf_console_ping"
+ Keyword="Win32Proj"
+ SignManifests="true"
+ >
+ <Platforms>
+ <Platform
+ Name="Win32"
+ />
+ <Platform
+ Name="x64"
+ />
+ </Platforms>
+ <ToolFiles>
+ </ToolFiles>
+ <Configurations>
+ <Configuration
+ Name="Debug|Win32"
+ OutputDirectory="."
+ IntermediateDirectory="Debug\qmf_console_ping\I386"
+ ConfigurationType="1"
+ CharacterSet="0"
+
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ AdditionalOptions=""
+ AdditionalIncludeDirectories=""
+ TypeLibraryName="$(InputName).tlb"
+ HeaderFileName="$(InputName).h"
+ InterfaceIdentifierFileName="$(InputName)_i.c"
+ ProxyFileName="$(InputName)_p.c"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..\..\src,..\..\src\gen"
+ PreprocessorDefinitions="_DEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
+ MinimalRebuild="false"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="3"
+ RuntimeTypeInfo="true"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="false"
+ DebugInformationFormat="3"
+ DisableSpecificWarnings="4244;4800"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ PreprocessorDefinitions="_DEBUG;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
+ Culture="1033"
+ AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..\..\src,..\..\src\gen"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="qpidcommond.lib qpidclientd.lib qmfconsoled.lib"
+ OutputFile="$(OutDir)\ping.exe"
+ LinkIncremental="2"
+ SuppressStartupBanner="true"
+ AdditionalLibraryDirectories=".;$(BOOST_ROOT)\lib;..\..\src"
+ GenerateDebugInformation="true"
+ SubSystem="1"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|Win32"
+ OutputDirectory="Release"
+ IntermediateDirectory="Release\qmf_console_ping\I386"
+ ConfigurationType="1"
+ CharacterSet="0"
+
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ AdditionalOptions=""
+ AdditionalIncludeDirectories=""
+ TypeLibraryName="$(InputName).tlb"
+ HeaderFileName="$(InputName).h"
+ InterfaceIdentifierFileName="$(InputName)_i.c"
+ ProxyFileName="$(InputName)_p.c"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..\..\src,..\..\src\gen"
+ PreprocessorDefinitions="NDEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
+ RuntimeLibrary="2"
+ RuntimeTypeInfo="true"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="false"
+ DisableSpecificWarnings="4244;4800"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ PreprocessorDefinitions="NDEBUG;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
+ Culture="1033"
+ AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..\..\src,..\..\src\gen"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="qpidcommon.lib qpidclient.lib qmfconsole.lib"
+ OutputFile="$(OutDir)\ping.exe"
+ LinkIncremental="1"
+ SuppressStartupBanner="true"
+ AdditionalLibraryDirectories=".;$(BOOST_ROOT)\lib;..\..\src"
+ GenerateDebugInformation="true"
+ SubSystem="1"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Debug|x64"
+ OutputDirectory="."
+ IntermediateDirectory="Debug\qmf_console_ping\AMD64"
+ ConfigurationType="1"
+ CharacterSet="0"
+
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ AdditionalOptions=""
+ AdditionalIncludeDirectories=""
+ TypeLibraryName="$(InputName).tlb"
+ HeaderFileName="$(InputName).h"
+ InterfaceIdentifierFileName="$(InputName)_i.c"
+ ProxyFileName="$(InputName)_p.c"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..\..\src,..\..\src\gen"
+ PreprocessorDefinitions="_DEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;_AMD64_;_WIN64;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
+ MinimalRebuild="false"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="3"
+ RuntimeTypeInfo="true"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="false"
+ DebugInformationFormat="3"
+ DisableSpecificWarnings="4244;4800"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ PreprocessorDefinitions="_DEBUG;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS;_WIN64"
+ Culture="1033"
+ AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..\..\src,..\..\src\gen"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalOptions="/machine:AMD64"
+ AdditionalDependencies="qpidcommond.lib qpidclientd.lib qmfconsoled.lib"
+ OutputFile="$(OutDir)\ping.exe"
+ LinkIncremental="2"
+ SuppressStartupBanner="true"
+ AdditionalLibraryDirectories=".;$(BOOST_ROOT)\lib;..\..\src"
+ GenerateDebugInformation="true"
+ SubSystem="1"
+ TargetMachine="17"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|x64"
+ OutputDirectory="Release"
+ IntermediateDirectory="Release\qmf_console_ping\AMD64"
+ ConfigurationType="1"
+ CharacterSet="0"
+
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ AdditionalOptions=""
+ AdditionalIncludeDirectories=""
+ TypeLibraryName="$(InputName).tlb"
+ HeaderFileName="$(InputName).h"
+ InterfaceIdentifierFileName="$(InputName)_i.c"
+ ProxyFileName="$(InputName)_p.c"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..\..\src,..\..\src\gen"
+ PreprocessorDefinitions="NDEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;_AMD64_;_WIN64;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
+ RuntimeLibrary="2"
+ RuntimeTypeInfo="true"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="false"
+ DisableSpecificWarnings="4244;4800"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ PreprocessorDefinitions="NDEBUG;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS;_WIN64"
+ Culture="1033"
+ AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..\..\src,..\..\src\gen"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalOptions="/machine:AMD64"
+ AdditionalDependencies="qpidcommon.lib qpidclient.lib qmfconsole.lib"
+ OutputFile="$(OutDir)\ping.exe"
+ LinkIncremental="1"
+ SuppressStartupBanner="true"
+ AdditionalLibraryDirectories=".;$(BOOST_ROOT)\lib;..\..\src"
+ GenerateDebugInformation="true"
+ SubSystem="1"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ TargetMachine="17"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ </Configurations>
+ <References>
+ </References>
+ <Files>
+ <Filter
+ Name="Source Files"
+ Filter="cpp;cxx;cc;C;c">
+ <File
+ RelativePath="ping.cpp">
+ </File>
+ </Filter>
+ <Filter
+ Name="Header Files"
+ Filter="h;hpp;hxx;hh">
+ <File
+ RelativePath="ConnectionOptions.h">
+ </File>
+ <File
+ RelativePath="TestOptions.h">
+ </File>
+ </Filter>
+ </Files>
+ <Globals>
+ </Globals>
+</VisualStudioProject>
diff --git a/qpid/cpp/examples/qmf-console/qmf_console_printevents.vcproj b/qpid/cpp/examples/qmf-console/qmf_console_printevents.vcproj
new file mode 100644
index 0000000000..b11f4b8d31
--- /dev/null
+++ b/qpid/cpp/examples/qmf-console/qmf_console_printevents.vcproj
@@ -0,0 +1,374 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="9.00"
+ Name="qmf_console_printevents"
+ ProjectGUID="{72C74624-FECA-1BAD-2E13-3FFA2B8669C3}"
+ RootNamespace="qmf_console_printevents"
+ Keyword="Win32Proj"
+ SignManifests="true"
+ >
+ <Platforms>
+ <Platform
+ Name="Win32"
+ />
+ <Platform
+ Name="x64"
+ />
+ </Platforms>
+ <ToolFiles>
+ </ToolFiles>
+ <Configurations>
+ <Configuration
+ Name="Debug|Win32"
+ OutputDirectory="."
+ IntermediateDirectory="Debug\qmf_console_printevents\I386"
+ ConfigurationType="1"
+ CharacterSet="0"
+
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ AdditionalOptions=""
+ AdditionalIncludeDirectories=""
+ TypeLibraryName="$(InputName).tlb"
+ HeaderFileName="$(InputName).h"
+ InterfaceIdentifierFileName="$(InputName)_i.c"
+ ProxyFileName="$(InputName)_p.c"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..\..\src,..\..\src\gen"
+ PreprocessorDefinitions="_DEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
+ MinimalRebuild="false"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="3"
+ RuntimeTypeInfo="true"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="false"
+ DebugInformationFormat="3"
+ DisableSpecificWarnings="4244;4800"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ PreprocessorDefinitions="_DEBUG;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
+ Culture="1033"
+ AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..\..\src,..\..\src\gen"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="qpidcommond.lib qpidclientd.lib qmfconsoled.lib"
+ OutputFile="$(OutDir)\printevents.exe"
+ LinkIncremental="2"
+ SuppressStartupBanner="true"
+ AdditionalLibraryDirectories=".;$(BOOST_ROOT)\lib;..\..\src"
+ GenerateDebugInformation="true"
+ SubSystem="1"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|Win32"
+ OutputDirectory="Release"
+ IntermediateDirectory="Release\qmf_console_printevents\I386"
+ ConfigurationType="1"
+ CharacterSet="0"
+
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ AdditionalOptions=""
+ AdditionalIncludeDirectories=""
+ TypeLibraryName="$(InputName).tlb"
+ HeaderFileName="$(InputName).h"
+ InterfaceIdentifierFileName="$(InputName)_i.c"
+ ProxyFileName="$(InputName)_p.c"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..\..\src,..\..\src\gen"
+ PreprocessorDefinitions="NDEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
+ RuntimeLibrary="2"
+ RuntimeTypeInfo="true"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="false"
+ DisableSpecificWarnings="4244;4800"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ PreprocessorDefinitions="NDEBUG;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
+ Culture="1033"
+ AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..\..\src,..\..\src\gen"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="qpidcommon.lib qpidclient.lib qmfconsole.lib"
+ OutputFile="$(OutDir)\printevents.exe"
+ LinkIncremental="1"
+ SuppressStartupBanner="true"
+ AdditionalLibraryDirectories=".;$(BOOST_ROOT)\lib;..\..\src"
+ GenerateDebugInformation="true"
+ SubSystem="1"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Debug|x64"
+ OutputDirectory="."
+ IntermediateDirectory="Debug\qmf_console_printevents\AMD64"
+ ConfigurationType="1"
+ CharacterSet="0"
+
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ AdditionalOptions=""
+ AdditionalIncludeDirectories=""
+ TypeLibraryName="$(InputName).tlb"
+ HeaderFileName="$(InputName).h"
+ InterfaceIdentifierFileName="$(InputName)_i.c"
+ ProxyFileName="$(InputName)_p.c"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..\..\src,..\..\src\gen"
+ PreprocessorDefinitions="_DEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;_AMD64_;_WIN64;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
+ MinimalRebuild="false"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="3"
+ RuntimeTypeInfo="true"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="false"
+ DebugInformationFormat="3"
+ DisableSpecificWarnings="4244;4800"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ PreprocessorDefinitions="_DEBUG;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS;_WIN64"
+ Culture="1033"
+ AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..\..\src,..\..\src\gen"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalOptions="/machine:AMD64"
+ AdditionalDependencies="qpidcommond.lib qpidclientd.lib qmfconsoled.lib"
+ OutputFile="$(OutDir)\printevents.exe"
+ LinkIncremental="2"
+ SuppressStartupBanner="true"
+ AdditionalLibraryDirectories=".;$(BOOST_ROOT)\lib;..\..\src"
+ GenerateDebugInformation="true"
+ SubSystem="1"
+ TargetMachine="17"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|x64"
+ OutputDirectory="Release"
+ IntermediateDirectory="Release\qmf_console_printevents\AMD64"
+ ConfigurationType="1"
+ CharacterSet="0"
+
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ AdditionalOptions=""
+ AdditionalIncludeDirectories=""
+ TypeLibraryName="$(InputName).tlb"
+ HeaderFileName="$(InputName).h"
+ InterfaceIdentifierFileName="$(InputName)_i.c"
+ ProxyFileName="$(InputName)_p.c"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..\..\src,..\..\src\gen"
+ PreprocessorDefinitions="NDEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;_AMD64_;_WIN64;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
+ RuntimeLibrary="2"
+ RuntimeTypeInfo="true"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="false"
+ DisableSpecificWarnings="4244;4800"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ PreprocessorDefinitions="NDEBUG;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS;_WIN64"
+ Culture="1033"
+ AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..\..\src,..\..\src\gen"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalOptions="/machine:AMD64"
+ AdditionalDependencies="qpidcommon.lib qpidclient.lib qmfconsole.lib"
+ OutputFile="$(OutDir)\printevents.exe"
+ LinkIncremental="1"
+ SuppressStartupBanner="true"
+ AdditionalLibraryDirectories=".;$(BOOST_ROOT)\lib;..\..\src"
+ GenerateDebugInformation="true"
+ SubSystem="1"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ TargetMachine="17"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ </Configurations>
+ <References>
+ </References>
+ <Files>
+ <Filter
+ Name="Source Files"
+ Filter="cpp;cxx;cc;C;c">
+ <File
+ RelativePath="printevents.cpp">
+ </File>
+ </Filter>
+ <Filter
+ Name="Header Files"
+ Filter="h;hpp;hxx;hh">
+ <File
+ RelativePath="ConnectionOptions.h">
+ </File>
+ <File
+ RelativePath="TestOptions.h">
+ </File>
+ </Filter>
+ </Files>
+ <Globals>
+ </Globals>
+</VisualStudioProject>
diff --git a/qpid/cpp/examples/qmf-console/qmf_console_queuestats.vcproj b/qpid/cpp/examples/qmf-console/qmf_console_queuestats.vcproj
new file mode 100644
index 0000000000..8c0bce672c
--- /dev/null
+++ b/qpid/cpp/examples/qmf-console/qmf_console_queuestats.vcproj
@@ -0,0 +1,374 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="9.00"
+ Name="qmf_console_queuestats"
+ ProjectGUID="{B21825EA-FECA-1BAD-2E13-3FFA2B8669C3}"
+ RootNamespace="qmf_console_queuestats"
+ Keyword="Win32Proj"
+ SignManifests="true"
+ >
+ <Platforms>
+ <Platform
+ Name="Win32"
+ />
+ <Platform
+ Name="x64"
+ />
+ </Platforms>
+ <ToolFiles>
+ </ToolFiles>
+ <Configurations>
+ <Configuration
+ Name="Debug|Win32"
+ OutputDirectory="."
+ IntermediateDirectory="Debug\qmf_console_queuestats\I386"
+ ConfigurationType="1"
+ CharacterSet="0"
+
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ AdditionalOptions=""
+ AdditionalIncludeDirectories=""
+ TypeLibraryName="$(InputName).tlb"
+ HeaderFileName="$(InputName).h"
+ InterfaceIdentifierFileName="$(InputName)_i.c"
+ ProxyFileName="$(InputName)_p.c"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..\..\src,..\..\src\gen"
+ PreprocessorDefinitions="_DEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
+ MinimalRebuild="false"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="3"
+ RuntimeTypeInfo="true"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="false"
+ DebugInformationFormat="3"
+ DisableSpecificWarnings="4244;4800"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ PreprocessorDefinitions="_DEBUG;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
+ Culture="1033"
+ AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..\..\src,..\..\src\gen"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="qpidcommond.lib qpidclientd.lib qmfconsoled.lib"
+ OutputFile="$(OutDir)\queuestats.exe"
+ LinkIncremental="2"
+ SuppressStartupBanner="true"
+ AdditionalLibraryDirectories=".;$(BOOST_ROOT)\lib;..\..\src"
+ GenerateDebugInformation="true"
+ SubSystem="1"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|Win32"
+ OutputDirectory="Release"
+ IntermediateDirectory="Release\qmf_console_queuestats\I386"
+ ConfigurationType="1"
+ CharacterSet="0"
+
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ AdditionalOptions=""
+ AdditionalIncludeDirectories=""
+ TypeLibraryName="$(InputName).tlb"
+ HeaderFileName="$(InputName).h"
+ InterfaceIdentifierFileName="$(InputName)_i.c"
+ ProxyFileName="$(InputName)_p.c"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..\..\src,..\..\src\gen"
+ PreprocessorDefinitions="NDEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
+ RuntimeLibrary="2"
+ RuntimeTypeInfo="true"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="false"
+ DisableSpecificWarnings="4244;4800"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ PreprocessorDefinitions="NDEBUG;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
+ Culture="1033"
+ AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..\..\src,..\..\src\gen"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="qpidcommon.lib qpidclient.lib qmfconsole.lib"
+ OutputFile="$(OutDir)\queuestats.exe"
+ LinkIncremental="1"
+ SuppressStartupBanner="true"
+ AdditionalLibraryDirectories=".;$(BOOST_ROOT)\lib;..\..\src"
+ GenerateDebugInformation="true"
+ SubSystem="1"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Debug|x64"
+ OutputDirectory="."
+ IntermediateDirectory="Debug\qmf_console_queuestats\AMD64"
+ ConfigurationType="1"
+ CharacterSet="0"
+
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ AdditionalOptions=""
+ AdditionalIncludeDirectories=""
+ TypeLibraryName="$(InputName).tlb"
+ HeaderFileName="$(InputName).h"
+ InterfaceIdentifierFileName="$(InputName)_i.c"
+ ProxyFileName="$(InputName)_p.c"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..\..\src,..\..\src\gen"
+ PreprocessorDefinitions="_DEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;_AMD64_;_WIN64;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
+ MinimalRebuild="false"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="3"
+ RuntimeTypeInfo="true"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="false"
+ DebugInformationFormat="3"
+ DisableSpecificWarnings="4244;4800"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ PreprocessorDefinitions="_DEBUG;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS;_WIN64"
+ Culture="1033"
+ AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..\..\src,..\..\src\gen"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalOptions="/machine:AMD64"
+ AdditionalDependencies="qpidcommond.lib qpidclientd.lib qmfconsoled.lib"
+ OutputFile="$(OutDir)\queuestats.exe"
+ LinkIncremental="2"
+ SuppressStartupBanner="true"
+ AdditionalLibraryDirectories=".;$(BOOST_ROOT)\lib;..\..\src"
+ GenerateDebugInformation="true"
+ SubSystem="1"
+ TargetMachine="17"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|x64"
+ OutputDirectory="Release"
+ IntermediateDirectory="Release\qmf_console_queuestats\AMD64"
+ ConfigurationType="1"
+ CharacterSet="0"
+
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ AdditionalOptions=""
+ AdditionalIncludeDirectories=""
+ TypeLibraryName="$(InputName).tlb"
+ HeaderFileName="$(InputName).h"
+ InterfaceIdentifierFileName="$(InputName)_i.c"
+ ProxyFileName="$(InputName)_p.c"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..\..\src,..\..\src\gen"
+ PreprocessorDefinitions="NDEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;_AMD64_;_WIN64;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
+ RuntimeLibrary="2"
+ RuntimeTypeInfo="true"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="false"
+ DisableSpecificWarnings="4244;4800"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ PreprocessorDefinitions="NDEBUG;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS;_WIN64"
+ Culture="1033"
+ AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..\..\src,..\..\src\gen"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalOptions="/machine:AMD64"
+ AdditionalDependencies="qpidcommon.lib qpidclient.lib qmfconsole.lib"
+ OutputFile="$(OutDir)\queuestats.exe"
+ LinkIncremental="1"
+ SuppressStartupBanner="true"
+ AdditionalLibraryDirectories=".;$(BOOST_ROOT)\lib;..\..\src"
+ GenerateDebugInformation="true"
+ SubSystem="1"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ TargetMachine="17"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ </Configurations>
+ <References>
+ </References>
+ <Files>
+ <Filter
+ Name="Source Files"
+ Filter="cpp;cxx;cc;C;c">
+ <File
+ RelativePath="queuestats.cpp">
+ </File>
+ </Filter>
+ <Filter
+ Name="Header Files"
+ Filter="h;hpp;hxx;hh">
+ <File
+ RelativePath="ConnectionOptions.h">
+ </File>
+ <File
+ RelativePath="TestOptions.h">
+ </File>
+ </Filter>
+ </Files>
+ <Globals>
+ </Globals>
+</VisualStudioProject>
diff --git a/qpid/cpp/examples/qmf-console/queuestats.cpp b/qpid/cpp/examples/qmf-console/queuestats.cpp
index ea6dc13022..2c38777ad8 100644
--- a/qpid/cpp/examples/qmf-console/queuestats.cpp
+++ b/qpid/cpp/examples/qmf-console/queuestats.cpp
@@ -21,6 +21,7 @@
#include "qpid/console/ConsoleListener.h"
#include "qpid/console/SessionManager.h"
+#include "qpid/sys/Time.h"
using namespace std;
using namespace qpid::console;
@@ -123,7 +124,7 @@ int main_int(int /*argc*/, char** /*argv*/)
// Sleep while the listener does all the work asynchronously.
//
for (;;) {
- sleep(1);
+ qpid::sys::sleep(1);
}
sm.delBroker(broker);
diff --git a/qpid/cpp/examples/request-response/Makefile.am b/qpid/cpp/examples/request-response/Makefile.am
index 8fb95f24fc..d7e7d692de 100644
--- a/qpid/cpp/examples/request-response/Makefile.am
+++ b/qpid/cpp/examples/request-response/Makefile.am
@@ -18,6 +18,7 @@
#
examplesdir=$(pkgdatadir)/examples/request-response
+MAKELDFLAGS=$(CLIENTFLAGS)
include $(top_srcdir)/examples/makedist.mk
noinst_PROGRAMS=client server
diff --git a/qpid/cpp/examples/request-response/client.cpp b/qpid/cpp/examples/request-response/client.cpp
index b1f8d0b587..679d1c5fc2 100644
--- a/qpid/cpp/examples/request-response/client.cpp
+++ b/qpid/cpp/examples/request-response/client.cpp
@@ -61,7 +61,6 @@
#include <qpid/client/MessageListener.h>
#include <qpid/client/SubscriptionManager.h>
-#include <unistd.h>
#include <cstdlib>
#include <iostream>
diff --git a/qpid/cpp/examples/request-response/request_response_client.vcproj b/qpid/cpp/examples/request-response/request_response_client.vcproj
new file mode 100644
index 0000000000..c40478ca7a
--- /dev/null
+++ b/qpid/cpp/examples/request-response/request_response_client.vcproj
@@ -0,0 +1,374 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="9.00"
+ Name="request_response_client"
+ ProjectGUID="{2691FE1E-FECA-1BAD-BD3A-8A467D0C5CCC}"
+ RootNamespace="request_response_client"
+ Keyword="Win32Proj"
+ SignManifests="true"
+ >
+ <Platforms>
+ <Platform
+ Name="Win32"
+ />
+ <Platform
+ Name="x64"
+ />
+ </Platforms>
+ <ToolFiles>
+ </ToolFiles>
+ <Configurations>
+ <Configuration
+ Name="Debug|Win32"
+ OutputDirectory="."
+ IntermediateDirectory="Debug\request_response_client\I386"
+ ConfigurationType="1"
+ CharacterSet="0"
+
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ AdditionalOptions=""
+ AdditionalIncludeDirectories=""
+ TypeLibraryName="$(InputName).tlb"
+ HeaderFileName="$(InputName).h"
+ InterfaceIdentifierFileName="$(InputName)_i.c"
+ ProxyFileName="$(InputName)_p.c"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..\..\src,..\..\src\gen"
+ PreprocessorDefinitions="_DEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
+ MinimalRebuild="false"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="3"
+ RuntimeTypeInfo="true"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="false"
+ DebugInformationFormat="3"
+ DisableSpecificWarnings="4244;4800"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ PreprocessorDefinitions="_DEBUG;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
+ Culture="1033"
+ AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..\..\src,..\..\src\gen"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="qpidcommond.lib qpidclientd.lib"
+ OutputFile="$(OutDir)\client.exe"
+ LinkIncremental="2"
+ SuppressStartupBanner="true"
+ AdditionalLibraryDirectories=".;$(BOOST_ROOT)\lib;..\..\src"
+ GenerateDebugInformation="true"
+ SubSystem="1"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|Win32"
+ OutputDirectory="Release"
+ IntermediateDirectory="Release\request_response_client\I386"
+ ConfigurationType="1"
+ CharacterSet="0"
+
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ AdditionalOptions=""
+ AdditionalIncludeDirectories=""
+ TypeLibraryName="$(InputName).tlb"
+ HeaderFileName="$(InputName).h"
+ InterfaceIdentifierFileName="$(InputName)_i.c"
+ ProxyFileName="$(InputName)_p.c"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..\..\src,..\..\src\gen"
+ PreprocessorDefinitions="NDEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
+ RuntimeLibrary="2"
+ RuntimeTypeInfo="true"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="false"
+ DisableSpecificWarnings="4244;4800"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ PreprocessorDefinitions="NDEBUG;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
+ Culture="1033"
+ AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..\..\src,..\..\src\gen"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="qpidcommon.lib qpidclient.lib"
+ OutputFile="$(OutDir)\client.exe"
+ LinkIncremental="1"
+ SuppressStartupBanner="true"
+ AdditionalLibraryDirectories=".;$(BOOST_ROOT)\lib;..\..\src"
+ GenerateDebugInformation="true"
+ SubSystem="1"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Debug|x64"
+ OutputDirectory="."
+ IntermediateDirectory="Debug\request_response_client\AMD64"
+ ConfigurationType="1"
+ CharacterSet="0"
+
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ AdditionalOptions=""
+ AdditionalIncludeDirectories=""
+ TypeLibraryName="$(InputName).tlb"
+ HeaderFileName="$(InputName).h"
+ InterfaceIdentifierFileName="$(InputName)_i.c"
+ ProxyFileName="$(InputName)_p.c"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..\..\src,..\..\src\gen"
+ PreprocessorDefinitions="_DEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;_AMD64_;_WIN64;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
+ MinimalRebuild="false"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="3"
+ RuntimeTypeInfo="true"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="false"
+ DebugInformationFormat="3"
+ DisableSpecificWarnings="4244;4800"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ PreprocessorDefinitions="_DEBUG;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS;_WIN64"
+ Culture="1033"
+ AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..\..\src,..\..\src\gen"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalOptions="/machine:AMD64"
+ AdditionalDependencies="qpidcommond.lib qpidclientd.lib"
+ OutputFile="$(OutDir)\client.exe"
+ LinkIncremental="2"
+ SuppressStartupBanner="true"
+ AdditionalLibraryDirectories=".;$(BOOST_ROOT)\lib;..\..\src"
+ GenerateDebugInformation="true"
+ SubSystem="1"
+ TargetMachine="17"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|x64"
+ OutputDirectory="Release"
+ IntermediateDirectory="Release\request_response_client\AMD64"
+ ConfigurationType="1"
+ CharacterSet="0"
+
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ AdditionalOptions=""
+ AdditionalIncludeDirectories=""
+ TypeLibraryName="$(InputName).tlb"
+ HeaderFileName="$(InputName).h"
+ InterfaceIdentifierFileName="$(InputName)_i.c"
+ ProxyFileName="$(InputName)_p.c"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..\..\src,..\..\src\gen"
+ PreprocessorDefinitions="NDEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;_AMD64_;_WIN64;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
+ RuntimeLibrary="2"
+ RuntimeTypeInfo="true"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="false"
+ DisableSpecificWarnings="4244;4800"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ PreprocessorDefinitions="NDEBUG;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS;_WIN64"
+ Culture="1033"
+ AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..\..\src,..\..\src\gen"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalOptions="/machine:AMD64"
+ AdditionalDependencies="qpidcommon.lib qpidclient.lib"
+ OutputFile="$(OutDir)\client.exe"
+ LinkIncremental="1"
+ SuppressStartupBanner="true"
+ AdditionalLibraryDirectories=".;$(BOOST_ROOT)\lib;..\..\src"
+ GenerateDebugInformation="true"
+ SubSystem="1"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ TargetMachine="17"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ </Configurations>
+ <References>
+ </References>
+ <Files>
+ <Filter
+ Name="Source Files"
+ Filter="cpp;cxx;cc;C;c">
+ <File
+ RelativePath="client.cpp">
+ </File>
+ </Filter>
+ <Filter
+ Name="Header Files"
+ Filter="h;hpp;hxx;hh">
+ <File
+ RelativePath="ConnectionOptions.h">
+ </File>
+ <File
+ RelativePath="TestOptions.h">
+ </File>
+ </Filter>
+ </Files>
+ <Globals>
+ </Globals>
+</VisualStudioProject>
diff --git a/qpid/cpp/examples/request-response/request_response_server.vcproj b/qpid/cpp/examples/request-response/request_response_server.vcproj
new file mode 100644
index 0000000000..170caa0952
--- /dev/null
+++ b/qpid/cpp/examples/request-response/request_response_server.vcproj
@@ -0,0 +1,374 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="9.00"
+ Name="request_response_server"
+ ProjectGUID="{46817425-FECA-1BAD-BD3A-8A467D0C5CCC}"
+ RootNamespace="request_response_server"
+ Keyword="Win32Proj"
+ SignManifests="true"
+ >
+ <Platforms>
+ <Platform
+ Name="Win32"
+ />
+ <Platform
+ Name="x64"
+ />
+ </Platforms>
+ <ToolFiles>
+ </ToolFiles>
+ <Configurations>
+ <Configuration
+ Name="Debug|Win32"
+ OutputDirectory="."
+ IntermediateDirectory="Debug\request_response_server\I386"
+ ConfigurationType="1"
+ CharacterSet="0"
+
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ AdditionalOptions=""
+ AdditionalIncludeDirectories=""
+ TypeLibraryName="$(InputName).tlb"
+ HeaderFileName="$(InputName).h"
+ InterfaceIdentifierFileName="$(InputName)_i.c"
+ ProxyFileName="$(InputName)_p.c"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..\..\src,..\..\src\gen"
+ PreprocessorDefinitions="_DEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
+ MinimalRebuild="false"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="3"
+ RuntimeTypeInfo="true"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="false"
+ DebugInformationFormat="3"
+ DisableSpecificWarnings="4244;4800"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ PreprocessorDefinitions="_DEBUG;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
+ Culture="1033"
+ AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..\..\src,..\..\src\gen"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="qpidcommond.lib qpidclientd.lib"
+ OutputFile="$(OutDir)\server.exe"
+ LinkIncremental="2"
+ SuppressStartupBanner="true"
+ AdditionalLibraryDirectories=".;$(BOOST_ROOT)\lib;..\..\src"
+ GenerateDebugInformation="true"
+ SubSystem="1"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|Win32"
+ OutputDirectory="Release"
+ IntermediateDirectory="Release\request_response_server\I386"
+ ConfigurationType="1"
+ CharacterSet="0"
+
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ AdditionalOptions=""
+ AdditionalIncludeDirectories=""
+ TypeLibraryName="$(InputName).tlb"
+ HeaderFileName="$(InputName).h"
+ InterfaceIdentifierFileName="$(InputName)_i.c"
+ ProxyFileName="$(InputName)_p.c"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..\..\src,..\..\src\gen"
+ PreprocessorDefinitions="NDEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
+ RuntimeLibrary="2"
+ RuntimeTypeInfo="true"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="false"
+ DisableSpecificWarnings="4244;4800"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ PreprocessorDefinitions="NDEBUG;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
+ Culture="1033"
+ AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..\..\src,..\..\src\gen"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="qpidcommon.lib qpidclient.lib"
+ OutputFile="$(OutDir)\server.exe"
+ LinkIncremental="1"
+ SuppressStartupBanner="true"
+ AdditionalLibraryDirectories=".;$(BOOST_ROOT)\lib;..\..\src"
+ GenerateDebugInformation="true"
+ SubSystem="1"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Debug|x64"
+ OutputDirectory="."
+ IntermediateDirectory="Debug\request_response_server\AMD64"
+ ConfigurationType="1"
+ CharacterSet="0"
+
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ AdditionalOptions=""
+ AdditionalIncludeDirectories=""
+ TypeLibraryName="$(InputName).tlb"
+ HeaderFileName="$(InputName).h"
+ InterfaceIdentifierFileName="$(InputName)_i.c"
+ ProxyFileName="$(InputName)_p.c"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..\..\src,..\..\src\gen"
+ PreprocessorDefinitions="_DEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;_AMD64_;_WIN64;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
+ MinimalRebuild="false"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="3"
+ RuntimeTypeInfo="true"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="false"
+ DebugInformationFormat="3"
+ DisableSpecificWarnings="4244;4800"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ PreprocessorDefinitions="_DEBUG;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS;_WIN64"
+ Culture="1033"
+ AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..\..\src,..\..\src\gen"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalOptions="/machine:AMD64"
+ AdditionalDependencies="qpidcommond.lib qpidclientd.lib"
+ OutputFile="$(OutDir)\server.exe"
+ LinkIncremental="2"
+ SuppressStartupBanner="true"
+ AdditionalLibraryDirectories=".;$(BOOST_ROOT)\lib;..\..\src"
+ GenerateDebugInformation="true"
+ SubSystem="1"
+ TargetMachine="17"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|x64"
+ OutputDirectory="Release"
+ IntermediateDirectory="Release\request_response_server\AMD64"
+ ConfigurationType="1"
+ CharacterSet="0"
+
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ AdditionalOptions=""
+ AdditionalIncludeDirectories=""
+ TypeLibraryName="$(InputName).tlb"
+ HeaderFileName="$(InputName).h"
+ InterfaceIdentifierFileName="$(InputName)_i.c"
+ ProxyFileName="$(InputName)_p.c"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..\..\src,..\..\src\gen"
+ PreprocessorDefinitions="NDEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;_AMD64_;_WIN64;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
+ RuntimeLibrary="2"
+ RuntimeTypeInfo="true"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="false"
+ DisableSpecificWarnings="4244;4800"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ PreprocessorDefinitions="NDEBUG;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS;_WIN64"
+ Culture="1033"
+ AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..\..\src,..\..\src\gen"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalOptions="/machine:AMD64"
+ AdditionalDependencies="qpidcommon.lib qpidclient.lib"
+ OutputFile="$(OutDir)\server.exe"
+ LinkIncremental="1"
+ SuppressStartupBanner="true"
+ AdditionalLibraryDirectories=".;$(BOOST_ROOT)\lib;..\..\src"
+ GenerateDebugInformation="true"
+ SubSystem="1"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ TargetMachine="17"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ </Configurations>
+ <References>
+ </References>
+ <Files>
+ <Filter
+ Name="Source Files"
+ Filter="cpp;cxx;cc;C;c">
+ <File
+ RelativePath="server.cpp">
+ </File>
+ </Filter>
+ <Filter
+ Name="Header Files"
+ Filter="h;hpp;hxx;hh">
+ <File
+ RelativePath="ConnectionOptions.h">
+ </File>
+ <File
+ RelativePath="TestOptions.h">
+ </File>
+ </Filter>
+ </Files>
+ <Globals>
+ </Globals>
+</VisualStudioProject>
diff --git a/qpid/cpp/examples/request-response/server.cpp b/qpid/cpp/examples/request-response/server.cpp
index 2d62638dff..65a4717b35 100644
--- a/qpid/cpp/examples/request-response/server.cpp
+++ b/qpid/cpp/examples/request-response/server.cpp
@@ -64,7 +64,6 @@
#include <qpid/client/MessageListener.h>
#include <qpid/client/SubscriptionManager.h>
-#include <unistd.h>
#include <cstdlib>
#include <iostream>
diff --git a/qpid/cpp/examples/tradedemo/Makefile.am b/qpid/cpp/examples/tradedemo/Makefile.am
index ef90e04bb0..a3c7fabd65 100644
--- a/qpid/cpp/examples/tradedemo/Makefile.am
+++ b/qpid/cpp/examples/tradedemo/Makefile.am
@@ -18,6 +18,7 @@
#
examplesdir=$(pkgdatadir)/examples/tradedemo
+MAKELDFLAGS=$(CLIENTFLAGS)
include $(top_srcdir)/examples/makedist.mk
noinst_PROGRAMS=topic_listener topic_publisher declare_queues
diff --git a/qpid/cpp/examples/tradedemo/topic_listener.cpp b/qpid/cpp/examples/tradedemo/topic_listener.cpp
index 569e558147..c488e7fb69 100644
--- a/qpid/cpp/examples/tradedemo/topic_listener.cpp
+++ b/qpid/cpp/examples/tradedemo/topic_listener.cpp
@@ -58,7 +58,6 @@
#include <qpid/client/SubscriptionManager.h>
#include "qpid/client/QueueOptions.h"
-#include <unistd.h>
#include <cstdlib>
#include <iostream>
diff --git a/qpid/cpp/examples/tradedemo/topic_publisher.cpp b/qpid/cpp/examples/tradedemo/topic_publisher.cpp
index 913f2cb9fe..e22c185bc7 100644
--- a/qpid/cpp/examples/tradedemo/topic_publisher.cpp
+++ b/qpid/cpp/examples/tradedemo/topic_publisher.cpp
@@ -59,7 +59,7 @@
#include "qpid/client/QueueOptions.h"
-#include <unistd.h>
+#include <stdlib.h>
#include <cstdlib>
#include <iostream>
#include <set>
diff --git a/qpid/cpp/examples/tradedemo/tradedemo_declare_queues.vcproj b/qpid/cpp/examples/tradedemo/tradedemo_declare_queues.vcproj
new file mode 100644
index 0000000000..483ad2e6c9
--- /dev/null
+++ b/qpid/cpp/examples/tradedemo/tradedemo_declare_queues.vcproj
@@ -0,0 +1,374 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="9.00"
+ Name="tradedemo_declare_queues"
+ ProjectGUID="{9057502D-FECA-1BAD-23CE-CD4095BD3C8B}"
+ RootNamespace="tradedemo_declare_queues"
+ Keyword="Win32Proj"
+ SignManifests="true"
+ >
+ <Platforms>
+ <Platform
+ Name="Win32"
+ />
+ <Platform
+ Name="x64"
+ />
+ </Platforms>
+ <ToolFiles>
+ </ToolFiles>
+ <Configurations>
+ <Configuration
+ Name="Debug|Win32"
+ OutputDirectory="."
+ IntermediateDirectory="Debug\tradedemo_declare_queues\I386"
+ ConfigurationType="1"
+ CharacterSet="0"
+
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ AdditionalOptions=""
+ AdditionalIncludeDirectories=""
+ TypeLibraryName="$(InputName).tlb"
+ HeaderFileName="$(InputName).h"
+ InterfaceIdentifierFileName="$(InputName)_i.c"
+ ProxyFileName="$(InputName)_p.c"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..\..\src,..\..\src\gen"
+ PreprocessorDefinitions="_DEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
+ MinimalRebuild="false"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="3"
+ RuntimeTypeInfo="true"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="false"
+ DebugInformationFormat="3"
+ DisableSpecificWarnings="4244;4800"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ PreprocessorDefinitions="_DEBUG;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
+ Culture="1033"
+ AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..\..\src,..\..\src\gen"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="qpidcommond.lib qpidclientd.lib"
+ OutputFile="$(OutDir)\declare_queues.exe"
+ LinkIncremental="2"
+ SuppressStartupBanner="true"
+ AdditionalLibraryDirectories=".;$(BOOST_ROOT)\lib;..\..\src"
+ GenerateDebugInformation="true"
+ SubSystem="1"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|Win32"
+ OutputDirectory="Release"
+ IntermediateDirectory="Release\tradedemo_declare_queues\I386"
+ ConfigurationType="1"
+ CharacterSet="0"
+
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ AdditionalOptions=""
+ AdditionalIncludeDirectories=""
+ TypeLibraryName="$(InputName).tlb"
+ HeaderFileName="$(InputName).h"
+ InterfaceIdentifierFileName="$(InputName)_i.c"
+ ProxyFileName="$(InputName)_p.c"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..\..\src,..\..\src\gen"
+ PreprocessorDefinitions="NDEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
+ RuntimeLibrary="2"
+ RuntimeTypeInfo="true"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="false"
+ DisableSpecificWarnings="4244;4800"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ PreprocessorDefinitions="NDEBUG;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
+ Culture="1033"
+ AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..\..\src,..\..\src\gen"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="qpidcommon.lib qpidclient.lib"
+ OutputFile="$(OutDir)\declare_queues.exe"
+ LinkIncremental="1"
+ SuppressStartupBanner="true"
+ AdditionalLibraryDirectories=".;$(BOOST_ROOT)\lib;..\..\src"
+ GenerateDebugInformation="true"
+ SubSystem="1"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Debug|x64"
+ OutputDirectory="."
+ IntermediateDirectory="Debug\tradedemo_declare_queues\AMD64"
+ ConfigurationType="1"
+ CharacterSet="0"
+
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ AdditionalOptions=""
+ AdditionalIncludeDirectories=""
+ TypeLibraryName="$(InputName).tlb"
+ HeaderFileName="$(InputName).h"
+ InterfaceIdentifierFileName="$(InputName)_i.c"
+ ProxyFileName="$(InputName)_p.c"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..\..\src,..\..\src\gen"
+ PreprocessorDefinitions="_DEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;_AMD64_;_WIN64;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
+ MinimalRebuild="false"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="3"
+ RuntimeTypeInfo="true"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="false"
+ DebugInformationFormat="3"
+ DisableSpecificWarnings="4244;4800"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ PreprocessorDefinitions="_DEBUG;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS;_WIN64"
+ Culture="1033"
+ AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..\..\src,..\..\src\gen"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalOptions="/machine:AMD64"
+ AdditionalDependencies="qpidcommond.lib qpidclientd.lib"
+ OutputFile="$(OutDir)\declare_queues.exe"
+ LinkIncremental="2"
+ SuppressStartupBanner="true"
+ AdditionalLibraryDirectories=".;$(BOOST_ROOT)\lib;..\..\src"
+ GenerateDebugInformation="true"
+ SubSystem="1"
+ TargetMachine="17"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|x64"
+ OutputDirectory="Release"
+ IntermediateDirectory="Release\tradedemo_declare_queues\AMD64"
+ ConfigurationType="1"
+ CharacterSet="0"
+
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ AdditionalOptions=""
+ AdditionalIncludeDirectories=""
+ TypeLibraryName="$(InputName).tlb"
+ HeaderFileName="$(InputName).h"
+ InterfaceIdentifierFileName="$(InputName)_i.c"
+ ProxyFileName="$(InputName)_p.c"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..\..\src,..\..\src\gen"
+ PreprocessorDefinitions="NDEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;_AMD64_;_WIN64;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
+ RuntimeLibrary="2"
+ RuntimeTypeInfo="true"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="false"
+ DisableSpecificWarnings="4244;4800"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ PreprocessorDefinitions="NDEBUG;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS;_WIN64"
+ Culture="1033"
+ AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..\..\src,..\..\src\gen"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalOptions="/machine:AMD64"
+ AdditionalDependencies="qpidcommon.lib qpidclient.lib"
+ OutputFile="$(OutDir)\declare_queues.exe"
+ LinkIncremental="1"
+ SuppressStartupBanner="true"
+ AdditionalLibraryDirectories=".;$(BOOST_ROOT)\lib;..\..\src"
+ GenerateDebugInformation="true"
+ SubSystem="1"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ TargetMachine="17"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ </Configurations>
+ <References>
+ </References>
+ <Files>
+ <Filter
+ Name="Source Files"
+ Filter="cpp;cxx;cc;C;c">
+ <File
+ RelativePath="declare_queues.cpp">
+ </File>
+ </Filter>
+ <Filter
+ Name="Header Files"
+ Filter="h;hpp;hxx;hh">
+ <File
+ RelativePath="ConnectionOptions.h">
+ </File>
+ <File
+ RelativePath="TestOptions.h">
+ </File>
+ </Filter>
+ </Files>
+ <Globals>
+ </Globals>
+</VisualStudioProject>
diff --git a/qpid/cpp/examples/tradedemo/tradedemo_topic_listener.vcproj b/qpid/cpp/examples/tradedemo/tradedemo_topic_listener.vcproj
new file mode 100644
index 0000000000..2e36090602
--- /dev/null
+++ b/qpid/cpp/examples/tradedemo/tradedemo_topic_listener.vcproj
@@ -0,0 +1,374 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="9.00"
+ Name="tradedemo_topic_listener"
+ ProjectGUID="{5A25F2CD-FECA-1BAD-23CE-CD4095BD3C8B}"
+ RootNamespace="tradedemo_topic_listener"
+ Keyword="Win32Proj"
+ SignManifests="true"
+ >
+ <Platforms>
+ <Platform
+ Name="Win32"
+ />
+ <Platform
+ Name="x64"
+ />
+ </Platforms>
+ <ToolFiles>
+ </ToolFiles>
+ <Configurations>
+ <Configuration
+ Name="Debug|Win32"
+ OutputDirectory="."
+ IntermediateDirectory="Debug\tradedemo_topic_listener\I386"
+ ConfigurationType="1"
+ CharacterSet="0"
+
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ AdditionalOptions=""
+ AdditionalIncludeDirectories=""
+ TypeLibraryName="$(InputName).tlb"
+ HeaderFileName="$(InputName).h"
+ InterfaceIdentifierFileName="$(InputName)_i.c"
+ ProxyFileName="$(InputName)_p.c"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..\..\src,..\..\src\gen"
+ PreprocessorDefinitions="_DEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
+ MinimalRebuild="false"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="3"
+ RuntimeTypeInfo="true"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="false"
+ DebugInformationFormat="3"
+ DisableSpecificWarnings="4244;4800"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ PreprocessorDefinitions="_DEBUG;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
+ Culture="1033"
+ AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..\..\src,..\..\src\gen"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="qpidcommond.lib qpidclientd.lib"
+ OutputFile="$(OutDir)\topic_listener.exe"
+ LinkIncremental="2"
+ SuppressStartupBanner="true"
+ AdditionalLibraryDirectories=".;$(BOOST_ROOT)\lib;..\..\src"
+ GenerateDebugInformation="true"
+ SubSystem="1"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|Win32"
+ OutputDirectory="Release"
+ IntermediateDirectory="Release\tradedemo_topic_listener\I386"
+ ConfigurationType="1"
+ CharacterSet="0"
+
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ AdditionalOptions=""
+ AdditionalIncludeDirectories=""
+ TypeLibraryName="$(InputName).tlb"
+ HeaderFileName="$(InputName).h"
+ InterfaceIdentifierFileName="$(InputName)_i.c"
+ ProxyFileName="$(InputName)_p.c"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..\..\src,..\..\src\gen"
+ PreprocessorDefinitions="NDEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
+ RuntimeLibrary="2"
+ RuntimeTypeInfo="true"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="false"
+ DisableSpecificWarnings="4244;4800"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ PreprocessorDefinitions="NDEBUG;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
+ Culture="1033"
+ AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..\..\src,..\..\src\gen"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="qpidcommon.lib qpidclient.lib"
+ OutputFile="$(OutDir)\topic_listener.exe"
+ LinkIncremental="1"
+ SuppressStartupBanner="true"
+ AdditionalLibraryDirectories=".;$(BOOST_ROOT)\lib;..\..\src"
+ GenerateDebugInformation="true"
+ SubSystem="1"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Debug|x64"
+ OutputDirectory="."
+ IntermediateDirectory="Debug\tradedemo_topic_listener\AMD64"
+ ConfigurationType="1"
+ CharacterSet="0"
+
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ AdditionalOptions=""
+ AdditionalIncludeDirectories=""
+ TypeLibraryName="$(InputName).tlb"
+ HeaderFileName="$(InputName).h"
+ InterfaceIdentifierFileName="$(InputName)_i.c"
+ ProxyFileName="$(InputName)_p.c"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..\..\src,..\..\src\gen"
+ PreprocessorDefinitions="_DEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;_AMD64_;_WIN64;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
+ MinimalRebuild="false"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="3"
+ RuntimeTypeInfo="true"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="false"
+ DebugInformationFormat="3"
+ DisableSpecificWarnings="4244;4800"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ PreprocessorDefinitions="_DEBUG;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS;_WIN64"
+ Culture="1033"
+ AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..\..\src,..\..\src\gen"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalOptions="/machine:AMD64"
+ AdditionalDependencies="qpidcommond.lib qpidclientd.lib"
+ OutputFile="$(OutDir)\topic_listener.exe"
+ LinkIncremental="2"
+ SuppressStartupBanner="true"
+ AdditionalLibraryDirectories=".;$(BOOST_ROOT)\lib;..\..\src"
+ GenerateDebugInformation="true"
+ SubSystem="1"
+ TargetMachine="17"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|x64"
+ OutputDirectory="Release"
+ IntermediateDirectory="Release\tradedemo_topic_listener\AMD64"
+ ConfigurationType="1"
+ CharacterSet="0"
+
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ AdditionalOptions=""
+ AdditionalIncludeDirectories=""
+ TypeLibraryName="$(InputName).tlb"
+ HeaderFileName="$(InputName).h"
+ InterfaceIdentifierFileName="$(InputName)_i.c"
+ ProxyFileName="$(InputName)_p.c"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..\..\src,..\..\src\gen"
+ PreprocessorDefinitions="NDEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;_AMD64_;_WIN64;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
+ RuntimeLibrary="2"
+ RuntimeTypeInfo="true"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="false"
+ DisableSpecificWarnings="4244;4800"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ PreprocessorDefinitions="NDEBUG;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS;_WIN64"
+ Culture="1033"
+ AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..\..\src,..\..\src\gen"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalOptions="/machine:AMD64"
+ AdditionalDependencies="qpidcommon.lib qpidclient.lib"
+ OutputFile="$(OutDir)\topic_listener.exe"
+ LinkIncremental="1"
+ SuppressStartupBanner="true"
+ AdditionalLibraryDirectories=".;$(BOOST_ROOT)\lib;..\..\src"
+ GenerateDebugInformation="true"
+ SubSystem="1"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ TargetMachine="17"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ </Configurations>
+ <References>
+ </References>
+ <Files>
+ <Filter
+ Name="Source Files"
+ Filter="cpp;cxx;cc;C;c">
+ <File
+ RelativePath="topic_listener.cpp">
+ </File>
+ </Filter>
+ <Filter
+ Name="Header Files"
+ Filter="h;hpp;hxx;hh">
+ <File
+ RelativePath="ConnectionOptions.h">
+ </File>
+ <File
+ RelativePath="TestOptions.h">
+ </File>
+ </Filter>
+ </Files>
+ <Globals>
+ </Globals>
+</VisualStudioProject>
diff --git a/qpid/cpp/examples/tradedemo/tradedemo_topic_publisher.vcproj b/qpid/cpp/examples/tradedemo/tradedemo_topic_publisher.vcproj
new file mode 100644
index 0000000000..2fdbb901c0
--- /dev/null
+++ b/qpid/cpp/examples/tradedemo/tradedemo_topic_publisher.vcproj
@@ -0,0 +1,374 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="9.00"
+ Name="tradedemo_topic_publisher"
+ ProjectGUID="{E614CC2C-FECA-1BAD-23CE-CD4095BD3C8B}"
+ RootNamespace="tradedemo_topic_publisher"
+ Keyword="Win32Proj"
+ SignManifests="true"
+ >
+ <Platforms>
+ <Platform
+ Name="Win32"
+ />
+ <Platform
+ Name="x64"
+ />
+ </Platforms>
+ <ToolFiles>
+ </ToolFiles>
+ <Configurations>
+ <Configuration
+ Name="Debug|Win32"
+ OutputDirectory="."
+ IntermediateDirectory="Debug\tradedemo_topic_publisher\I386"
+ ConfigurationType="1"
+ CharacterSet="0"
+
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ AdditionalOptions=""
+ AdditionalIncludeDirectories=""
+ TypeLibraryName="$(InputName).tlb"
+ HeaderFileName="$(InputName).h"
+ InterfaceIdentifierFileName="$(InputName)_i.c"
+ ProxyFileName="$(InputName)_p.c"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..\..\src,..\..\src\gen"
+ PreprocessorDefinitions="_DEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
+ MinimalRebuild="false"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="3"
+ RuntimeTypeInfo="true"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="false"
+ DebugInformationFormat="3"
+ DisableSpecificWarnings="4244;4800"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ PreprocessorDefinitions="_DEBUG;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
+ Culture="1033"
+ AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..\..\src,..\..\src\gen"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="qpidcommond.lib qpidclientd.lib"
+ OutputFile="$(OutDir)\topic_publisher.exe"
+ LinkIncremental="2"
+ SuppressStartupBanner="true"
+ AdditionalLibraryDirectories=".;$(BOOST_ROOT)\lib;..\..\src"
+ GenerateDebugInformation="true"
+ SubSystem="1"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|Win32"
+ OutputDirectory="Release"
+ IntermediateDirectory="Release\tradedemo_topic_publisher\I386"
+ ConfigurationType="1"
+ CharacterSet="0"
+
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ AdditionalOptions=""
+ AdditionalIncludeDirectories=""
+ TypeLibraryName="$(InputName).tlb"
+ HeaderFileName="$(InputName).h"
+ InterfaceIdentifierFileName="$(InputName)_i.c"
+ ProxyFileName="$(InputName)_p.c"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..\..\src,..\..\src\gen"
+ PreprocessorDefinitions="NDEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
+ RuntimeLibrary="2"
+ RuntimeTypeInfo="true"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="false"
+ DisableSpecificWarnings="4244;4800"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ PreprocessorDefinitions="NDEBUG;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
+ Culture="1033"
+ AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..\..\src,..\..\src\gen"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="qpidcommon.lib qpidclient.lib"
+ OutputFile="$(OutDir)\topic_publisher.exe"
+ LinkIncremental="1"
+ SuppressStartupBanner="true"
+ AdditionalLibraryDirectories=".;$(BOOST_ROOT)\lib;..\..\src"
+ GenerateDebugInformation="true"
+ SubSystem="1"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Debug|x64"
+ OutputDirectory="."
+ IntermediateDirectory="Debug\tradedemo_topic_publisher\AMD64"
+ ConfigurationType="1"
+ CharacterSet="0"
+
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ AdditionalOptions=""
+ AdditionalIncludeDirectories=""
+ TypeLibraryName="$(InputName).tlb"
+ HeaderFileName="$(InputName).h"
+ InterfaceIdentifierFileName="$(InputName)_i.c"
+ ProxyFileName="$(InputName)_p.c"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..\..\src,..\..\src\gen"
+ PreprocessorDefinitions="_DEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;_AMD64_;_WIN64;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
+ MinimalRebuild="false"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="3"
+ RuntimeTypeInfo="true"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="false"
+ DebugInformationFormat="3"
+ DisableSpecificWarnings="4244;4800"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ PreprocessorDefinitions="_DEBUG;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS;_WIN64"
+ Culture="1033"
+ AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..\..\src,..\..\src\gen"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalOptions="/machine:AMD64"
+ AdditionalDependencies="qpidcommond.lib qpidclientd.lib"
+ OutputFile="$(OutDir)\topic_publisher.exe"
+ LinkIncremental="2"
+ SuppressStartupBanner="true"
+ AdditionalLibraryDirectories=".;$(BOOST_ROOT)\lib;..\..\src"
+ GenerateDebugInformation="true"
+ SubSystem="1"
+ TargetMachine="17"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|x64"
+ OutputDirectory="Release"
+ IntermediateDirectory="Release\tradedemo_topic_publisher\AMD64"
+ ConfigurationType="1"
+ CharacterSet="0"
+
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ AdditionalOptions=""
+ AdditionalIncludeDirectories=""
+ TypeLibraryName="$(InputName).tlb"
+ HeaderFileName="$(InputName).h"
+ InterfaceIdentifierFileName="$(InputName)_i.c"
+ ProxyFileName="$(InputName)_p.c"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..\..\src,..\..\src\gen"
+ PreprocessorDefinitions="NDEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;_AMD64_;_WIN64;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
+ RuntimeLibrary="2"
+ RuntimeTypeInfo="true"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="false"
+ DisableSpecificWarnings="4244;4800"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ PreprocessorDefinitions="NDEBUG;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS;_WIN64"
+ Culture="1033"
+ AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..\..\src,..\..\src\gen"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalOptions="/machine:AMD64"
+ AdditionalDependencies="qpidcommon.lib qpidclient.lib"
+ OutputFile="$(OutDir)\topic_publisher.exe"
+ LinkIncremental="1"
+ SuppressStartupBanner="true"
+ AdditionalLibraryDirectories=".;$(BOOST_ROOT)\lib;..\..\src"
+ GenerateDebugInformation="true"
+ SubSystem="1"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ TargetMachine="17"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ </Configurations>
+ <References>
+ </References>
+ <Files>
+ <Filter
+ Name="Source Files"
+ Filter="cpp;cxx;cc;C;c">
+ <File
+ RelativePath="topic_publisher.cpp">
+ </File>
+ </Filter>
+ <Filter
+ Name="Header Files"
+ Filter="h;hpp;hxx;hh">
+ <File
+ RelativePath="ConnectionOptions.h">
+ </File>
+ <File
+ RelativePath="TestOptions.h">
+ </File>
+ </Filter>
+ </Files>
+ <Globals>
+ </Globals>
+</VisualStudioProject>
diff --git a/qpid/cpp/examples/xml-exchange/Makefile.am b/qpid/cpp/examples/xml-exchange/Makefile.am
index 0f99aea44e..aa450a32c2 100644
--- a/qpid/cpp/examples/xml-exchange/Makefile.am
+++ b/qpid/cpp/examples/xml-exchange/Makefile.am
@@ -18,6 +18,7 @@
#
examplesdir=$(pkgdatadir)/examples/xml-exchange
+MAKELDFLAGS=$(CLIENTFLAGS)
include $(top_srcdir)/examples/makedist.mk
noinst_PROGRAMS=declare_queues xml_producer listener
diff --git a/qpid/cpp/managementgen/qmf-gen b/qpid/cpp/managementgen/qmf-gen
index f2efa109f3..c6cfca5f83 100755
--- a/qpid/cpp/managementgen/qmf-gen
+++ b/qpid/cpp/managementgen/qmf-gen
@@ -33,6 +33,8 @@ usage = "usage: %prog [options] schema-document..."
parser = OptionParser(usage=usage)
parser.add_option("-o", "--outputdir", dest="outputdir", metavar="DIR", default="./",
help="Output directory")
+parser.add_option("-c", "--cmakelists", dest="cmakelists", metavar="FILE",
+ help="CMakeLists fragment")
parser.add_option("-m", "--makefile", dest="makefile", metavar="FILE",
help="Makefile fragment")
parser.add_option("-t", "--typefile", dest="typefile", metavar="FILE", default=defaultTypeFile,
@@ -72,3 +74,9 @@ if opts.makefile != None:
args["qpidbroker"] = opts.qpidbroker
args["genprefix"] = opts.genprefix
gen.makeSingleFile("Makefile.mk", opts.makefile, force=True, vars=args)
+
+if opts.cmakelists != None:
+ args = {}
+ args["qpidbroker"] = opts.qpidbroker
+ args["genprefix"] = opts.genprefix
+ gen.makeSingleFile("CMakeLists.cmake", opts.cmakelists, force=True, vars=args)
diff --git a/qpid/cpp/managementgen/qmfgen/generate.py b/qpid/cpp/managementgen/qmfgen/generate.py
index 35e222ebad..255d41ea0e 100755
--- a/qpid/cpp/managementgen/qmfgen/generate.py
+++ b/qpid/cpp/managementgen/qmfgen/generate.py
@@ -24,6 +24,7 @@ from errno import *
import os
import os.path
import filecmp
+import re
class Template:
"""
@@ -175,6 +176,81 @@ class Makefile:
return variables["qpidbroker"]
return False
+class CMakeLists(Makefile):
+ """ Object representing a makefile fragment """
+
+ # Regardless of what normalize() did, switch all the dir separators back
+ # to '/' - cmake expects that regardless of platform.
+ def unNormCase (self, path):
+ return re.sub("\\\\", "/", path)
+
+ def genGenSources (self, stream, variables):
+ mdir = self.unNormCase(variables["mgenDir"])
+ sdir = self.unNormCase(variables["specDir"])
+ stream.write (mdir + "/qmf-gen \n")
+ stream.write (" " + mdir + "/qmfgen/generate.py\n")
+ stream.write (" " + mdir + "/qmfgen/schema.py\n")
+ stream.write (" " + mdir + "/qmfgen/management-types.xml\n")
+ stream.write (" " + sdir + "/management-schema.xml\n")
+ first = True
+ for template in self.templateFiles:
+ if first:
+ first = False
+ stream.write (" ")
+ else:
+ stream.write ("\n ")
+ stream.write (mdir + "/qmfgen/templates/" + template)
+
+ def genGenCppFiles (self, stream, variables):
+ first = True
+ for file in self.filelists["cpp"]:
+ if first:
+ first = False
+ else:
+ stream.write (" \n ")
+ stream.write (self.unNormCase(file))
+
+ def genGenHFiles (self, stream, variables):
+ first = True
+ for file in self.filelists["h"]:
+ if first:
+ first = False
+ else:
+ stream.write (" \n ")
+ stream.write (self.unNormCase(file))
+
+ def genGeneratedFiles(self, stream, variables):
+ first = True
+ extensions = ("h", "cpp")
+ for ext in extensions:
+ for file in self.filelists[ext]:
+ if first:
+ first = False
+ else:
+ stream.write(" \n ")
+ if "genprefix" in variables:
+ prefix = variables["genprefix"]
+ if prefix != "":
+ stream.write(prefix + "/")
+ stream.write(self.unNormCase(file))
+
+ def genHeaderInstalls (self, stream, variables):
+ for package in self.packagelist:
+ stream.write("#Come back to this later...\n")
+ name = "_".join(package.split("/"))
+ stream.write("#" + name + "dir = $(includedir)/qmf/" + package + "\n")
+ stream.write("#dist_" + name + "_HEADERS = ")
+ first = True
+ for file in self.filelists["h"]:
+ file = self.unNormCase(file)
+ if file.find("gen/qmf/" + package) == 0:
+ if first:
+ first = False
+ else:
+ stream.write ("\n ")
+ stream.write("#" + file)
+ stream.write("\n\n")
+
class Generator:
"""
@@ -208,9 +284,10 @@ class Generator:
self.input = self.normalize (templateDir)
self.packagePath = self.dest
self.filelists = {}
- self.filelists["h"] = []
- self.filelists["cpp"] = []
- self.filelists["mk"] = []
+ self.filelists["h"] = []
+ self.filelists["cpp"] = []
+ self.filelists["mk"] = []
+ self.filelists["cmake"] = []
self.packagelist = []
self.templateFiles = []
self.variables = {}
@@ -354,7 +431,17 @@ class Generator:
def makeSingleFile (self, templateFile, target, force=False, vars=None):
""" Generate a single expanded template """
- makefile = Makefile (self.filelists, self.templateFiles, self.packagelist)
+ dot = templateFile.find(".")
+ if dot == -1:
+ raise ValueError ("Invalid template file name %s" % templateFile)
+ className = templateFile[0:dot]
+ if className == "Makefile":
+ classType = Makefile
+ elif className == "CMakeLists":
+ classType = CMakeLists
+ else:
+ raise ValueError ("Invalid class name %s" % className)
+ makefile = classType (self.filelists, self.templateFiles, self.packagelist)
template = Template (self.input + templateFile, self)
if vars:
for arg in vars:
diff --git a/qpid/cpp/rubygen/framing.0-10/MethodBodyDefaultVisitor.rb b/qpid/cpp/rubygen/framing.0-10/MethodBodyDefaultVisitor.rb
index 92bd10c9dd..3bacdbd812 100755
--- a/qpid/cpp/rubygen/framing.0-10/MethodBodyDefaultVisitor.rb
+++ b/qpid/cpp/rubygen/framing.0-10/MethodBodyDefaultVisitor.rb
@@ -30,13 +30,14 @@ class MethodBodyDefaultVisitorGen < CppGen
def generate()
h_file(@filename) {
include "qpid/framing/MethodBodyConstVisitor"
+ include "qpid/CommonImportExport.h"
namespace(@namespace) {
genl "class AMQMethodBody;"
cpp_class(@classname, "public MethodBodyConstVisitor") {
genl "public:"
genl "virtual void defaultVisit(const AMQMethodBody&) = 0;"
@amqp.methods_.each { |m|
- genl "virtual void visit(const #{m.body_name}&);" }
+ genl "QPID_COMMON_EXTERN virtual void visit(const #{m.body_name}&);" }
}}}
cpp_file(@filename) {
diff --git a/qpid/cpp/rubygen/framing.0-10/OperationsInvoker.rb b/qpid/cpp/rubygen/framing.0-10/OperationsInvoker.rb
index b751f61d36..6e3b79e51e 100755
--- a/qpid/cpp/rubygen/framing.0-10/OperationsInvoker.rb
+++ b/qpid/cpp/rubygen/framing.0-10/OperationsInvoker.rb
@@ -74,7 +74,7 @@ class OperationsInvokerGen < CppGen
public
genl("Invoker(#{target}& target_) : target(target_) {}")
genl "using MethodBodyDefaultVisitor::visit;"
- methods.each { |m| genl "void visit(const #{m.body_name}& body);" }
+ methods.each { |m| genl "QPID_COMMON_EXTERN void visit(const #{m.body_name}& body);" }
}
end
@@ -82,6 +82,7 @@ class OperationsInvokerGen < CppGen
h_file(@filename) {
include "qpid/framing/#{@ops}"
include "qpid/framing/Invoker.h"
+ include "qpid/CommonImportExport.h"
namespace("qpid::framing") {
# AMQP_*Operations invoker.
methods=@amqp.classes.map { |c| visit_methods(c).to_a }.flatten
diff --git a/qpid/cpp/rubygen/framing.0-10/Proxy.rb b/qpid/cpp/rubygen/framing.0-10/Proxy.rb
index 97d0df7c58..7e11d62d9b 100755
--- a/qpid/cpp/rubygen/framing.0-10/Proxy.rb
+++ b/qpid/cpp/rubygen/framing.0-10/Proxy.rb
@@ -44,7 +44,7 @@ public:
static #{cname}& get(#{@classname}& proxy) { return proxy.get#{cname}(); }
EOS
methods_on(c, @chassis).each { |m|
- genl "virtual void #{m.cppname}(#{m.signature.join(",\n ")});"
+ genl "QPID_COMMON_EXTERN virtual void #{m.cppname}(#{m.signature.join(",\n ")});"
genl
}}
end
@@ -66,10 +66,12 @@ EOS
include "qpid/framing/Array.h"
include "qpid/framing/amqp_types.h"
include "qpid/framing/amqp_structs.h"
+ include "qpid/CommonImportExport.h"
+
namespace("qpid::framing") {
cpp_class(@classname, "public Proxy") {
public
- genl "#{@classname}(FrameHandler& out);"
+ genl "QPID_COMMON_EXTERN #{@classname}(FrameHandler& out);"
genl
@amqp.classes.each { |c|
inner_class_decl(c)
diff --git a/qpid/cpp/rubygen/framing.0-10/Session.rb b/qpid/cpp/rubygen/framing.0-10/Session.rb
index 5dd2a91a56..709491e42e 100644
--- a/qpid/cpp/rubygen/framing.0-10/Session.rb
+++ b/qpid/cpp/rubygen/framing.0-10/Session.rb
@@ -55,9 +55,9 @@ module SyncAsync
def decl_ctor_opeq()
genl
- genl "#{@classname}();"
- genl "#{@classname}(const #{@version_base}& other);"
- genl "#{@classname}& operator=(const #{@version_base}& other);"
+ genl "QPID_CLIENT_EXTERN #{@classname}();"
+ genl "QPID_CLIENT_EXTERN #{@classname}(const #{@version_base}& other);"
+ genl "QPID_CLIENT_EXTERN #{@classname}& operator=(const #{@version_base}& other);"
end
def defn_ctor_opeq(inline="")
@@ -138,6 +138,7 @@ class SessionNoKeywordGen < CppGen
def generate()
h_file(@file) {
include "qpid/client/#{@version_base}.h"
+ include "qpid/client/ClientImportExport.h"
namespace(@namespace) {
doxygen_comment {
genl "AMQP #{@amqp.version} #{sync_adjective} session API."
@@ -151,7 +152,7 @@ class SessionNoKeywordGen < CppGen
genl
doxygen(m)
args=m.sig_c_default.join(", ")
- genl "#{m.return_type(@async)} #{m.session_function}(#{args});"
+ genl "QPID_CLIENT_EXTERN #{m.return_type(@async)} #{m.session_function}(#{args});"
}
}
}}
@@ -229,6 +230,7 @@ class SessionGen < CppGen
h_file(@fqclass.file) {
include @fqbase.file
include "qpid/client/arg"
+ include "qpid/client/ClientImportExport"
namespace("qpid::client") {
# Doxygen comment.
doxygen_comment {
diff --git a/qpid/cpp/rubygen/framing.0-10/constants.rb b/qpid/cpp/rubygen/framing.0-10/constants.rb
index d07c84e63a..fa2031b0ce 100755
--- a/qpid/cpp/rubygen/framing.0-10/constants.rb
+++ b/qpid/cpp/rubygen/framing.0-10/constants.rb
@@ -142,7 +142,7 @@ EOS
enum = @amqp.class_(class_name).domain(domain_name).enum
enum.choices.each { |c| declare_exception(c, base, class_name, enum) unless c.name == "normal" }
genl
- genl "sys::ExceptionHolder create#{base}(int code, const std::string& text);"
+ genl "QPID_COMMON_EXTERN sys::ExceptionHolder create#{base}(int code, const std::string& text);"
end
def create_exception(class_name, domain_name, base, invalid)
@@ -165,6 +165,7 @@ EOS
include "qpid/Exception"
include "qpid/sys/ExceptionHolder"
include "enum"
+ include "qpid/CommonImportExport.h"
namespace(@namespace) {
declare_exceptions("execution", "error-code", "SessionException")
declare_exceptions("connection", "close-code", "ConnectionException")
diff --git a/qpid/cpp/rubygen/framing.0-10/structs.rb b/qpid/cpp/rubygen/framing.0-10/structs.rb
index a68e1afb1e..8ea8a91172 100644
--- a/qpid/cpp/rubygen/framing.0-10/structs.rb
+++ b/qpid/cpp/rubygen/framing.0-10/structs.rb
@@ -351,15 +351,15 @@ EOS
end
def declare_packed_accessors(f)
- genl "void set#{f.name.caps}(#{f.cpptype.param} _#{f.cppname});";
- genl "#{f.cpptype.ret} get#{f.name.caps}() const;"
+ genl "QPID_COMMON_EXTERN void set#{f.name.caps}(#{f.cpptype.param} _#{f.cppname});";
+ genl "QPID_COMMON_EXTERN #{f.cpptype.ret} get#{f.name.caps}() const;"
if (f.cpptype.name == "FieldTable")
- genl "#{f.cpptype.name}& get#{f.name.caps}();"
+ genl "QPID_COMMON_EXTERN #{f.cpptype.name}& get#{f.name.caps}();"
end
if (f.type_ != "bit")
#extra 'accessors' for packed fields:
- genl "bool has#{f.name.caps}() const;"
- genl "void clear#{f.name.caps}Flag();"
+ genl "QPID_COMMON_EXTERN bool has#{f.name.caps}() const;"
+ genl "QPID_COMMON_EXTERN void clear#{f.name.caps}Flag();"
end
end
@@ -399,6 +399,7 @@ EOS
#include <ostream>
#include "qpid/framing/amqp_types_full.h"
+#include "qpid/CommonImportExport.h"
namespace qpid {
namespace framing {
@@ -438,17 +439,17 @@ EOS
methodbody_extra_defs(s)
end
if (s.kind_of? AmqpStruct)
- indent {genl "friend std::ostream& operator<<(std::ostream&, const #{classname}&);" }
+ indent {genl "QPID_COMMON_EXTERN friend std::ostream& operator<<(std::ostream&, const #{classname}&);" }
end
gen <<EOS
- void encode(Buffer&) const;
- void decode(Buffer&, uint32_t=0);
- void encodeStructBody(Buffer&) const;
- void decodeStructBody(Buffer&, uint32_t=0);
- uint32_t encodedSize() const;
- uint32_t bodySize() const;
- void print(std::ostream& out) const;
+ QPID_COMMON_EXTERN void encode(Buffer&) const;
+ QPID_COMMON_EXTERN void decode(Buffer&, uint32_t=0);
+ QPID_COMMON_EXTERN void encodeStructBody(Buffer&) const;
+ QPID_COMMON_EXTERN void decodeStructBody(Buffer&, uint32_t=0);
+ QPID_COMMON_EXTERN uint32_t encodedSize() const;
+ QPID_COMMON_EXTERN uint32_t bodySize() const;
+ QPID_COMMON_EXTERN void print(std::ostream& out) const;
}; /* class #{classname} */
}}
diff --git a/qpid/cpp/rubygen/generate b/qpid/cpp/rubygen/generate
index 836626cd7a..775bd3fd58 100755
--- a/qpid/cpp/rubygen/generate
+++ b/qpid/cpp/rubygen/generate
@@ -26,7 +26,7 @@ require 'amqpgen'
if ARGV.size < 3
puts <<EOS
Usage: #{ARGV[0]} OUTDIR SPEC.xml [ ... ] TEMPLATE.rb [ ... ]
-or: #{ARGV[0]} OUTDIR SPEC.xml [ ... ] all [ makefragment.mk ]
+or: #{ARGV[0]} OUTDIR SPEC.xml [ ... ] all [ makefragment.cmake ]
Parse all SPEC.xml files to create an AMQP model, run each TEMPLATE
putting the resulting files under OUTDIR. Prints a list of files
@@ -76,16 +76,16 @@ templates.each { |t|
end
}
-def make_continue(lines) lines.join(" \\\n "); end
+def cmake_continue(lines) lines.join(" \n "); end
# Generate makefile
-makefile=ARGV.grep(/.mk$/)[0]
+makefile=ARGV.grep(/.cmake$/)[0]
if makefile
dir=Dir.getwd
Dir.chdir File.dirname(__FILE__)
generator_files=Dir["**/*.rb"] << File.basename(__FILE__)
Dir.chdir dir
- rgen_generator=generator_files.map{ |f| "$(rgen_dir)/#{f}" }
+ rgen_generator=generator_files.map{ |f| "${rgen_dir}/#{f}" }
rgen_srcs=GenFiles.get.map{ |f| "#{$outdir}/#{f}" }
rgen_subdirs={}
rgen_srcs.each { |src|
@@ -100,13 +100,13 @@ if makefile
# Generated makefile fragment.
# Including makefile defines $(rgen_dir) $(rgen_cmd) and $(specs).
-rgen_generator=#{make_continue rgen_generator}
+set(rgen_generator #{cmake_continue rgen_generator})
EOS
rgen_subdirs.each_key { |subdir|
- out << "\nrgen_#{subdir}_srcs = #{make_continue(rgen_subdirs[subdir])}\n"
+ out << "\nset(rgen_#{subdir}_srcs #{cmake_continue(rgen_subdirs[subdir])})\n"
}
out << <<EOS
-rgen_srcs=#{make_continue rgen_srcs}
+set(rgen_srcs #{cmake_continue rgen_srcs})
# Header file install rules.
EOS
@@ -115,8 +115,8 @@ EOS
dir_ = dir.tr("/", "_")
regex=%r|#{dir}/[^/]+\.h$|
out << <<EOS
-#{dir_}dir = $(includedir)/#{dir}
-dist_#{dir_}_HEADERS = #{make_continue rgen_srcs.grep(regex)}
+set(#{dir_}dir \${includedir}/#{dir})
+set(dist_#{dir_}_HEADERS #{cmake_continue rgen_srcs.grep(regex)})
EOS
}
diff --git a/qpid/cpp/src/Makefile.am b/qpid/cpp/src/Makefile.am
index d5b53dc502..7de05645fa 100644
--- a/qpid/cpp/src/Makefile.am
+++ b/qpid/cpp/src/Makefile.am
@@ -29,6 +29,7 @@ windows_dist = \
client.vcproj \
qmfconsole.vcproj \
protocol_gen.mak \
+ qpid/client/windows/SaslFactory.cpp \
qpid/log/windows/SinkOptions.cpp \
qpid/log/windows/SinkOptions.h \
qpid/sys/windows/check.h \
@@ -41,6 +42,7 @@ windows_dist = \
qpid/sys/windows/IOHandle.cpp \
qpid/sys/windows/IoHandlePrivate.h \
qpid/sys/windows/LockFile.cpp \
+ qpid/sys/windows/PollableCondition.cpp \
qpid/sys/windows/Mutex.h \
qpid/sys/windows/Shlib.cpp \
qpid/sys/windows/Socket.cpp \
@@ -126,7 +128,6 @@ posix_plat_src = \
qpid/sys/posix/Time.cpp \
qpid/sys/posix/Thread.cpp \
qpid/sys/posix/Shlib.cpp \
- qpid/sys/posix/SystemInfo.cpp \
qpid/sys/posix/Mutex.cpp \
qpid/sys/posix/Fork.cpp \
qpid/sys/posix/StrError.cpp \
@@ -139,7 +140,6 @@ posix_plat_hdr = \
qpid/sys/posix/PrivatePosix.h \
qpid/sys/posix/Mutex.h \
qpid/sys/posix/Fork.h \
- qpid/sys/posix/PollableCondition.h \
qpid/sys/posix/IntegerTypes.h \
qpid/sys/posix/Time.h
@@ -151,7 +151,13 @@ if HAVE_ECF
poller = qpid/sys/solaris/ECFPoller.cpp
endif
-platform_src = $(posix_plat_src) $(poller)
+if SUNOS
+ systeminfo = qpid/sys/solaris/SystemInfo.cpp
+else
+ systeminfo = qpid/sys/posix/SystemInfo.cpp
+endif
+
+platform_src = $(posix_plat_src) $(poller) $(systeminfo)
platform_hdr = $(posix_plat_hdr)
posix_broker_src = \
@@ -495,6 +501,7 @@ nobase_include_HEADERS = \
qpid/broker/Queue.h \
qpid/broker/QueueListeners.h \
qpid/broker/QueueCleaner.h \
+ qpid/broker/BrokerImportExport.h \
qpid/broker/BrokerSingleton.h \
qpid/broker/Bridge.h \
qpid/broker/Connection.h \
@@ -571,6 +578,7 @@ nobase_include_HEADERS = \
qpid/client/AckMode.h \
qpid/client/Bounds.h \
qpid/client/ChainableFrameHandler.h \
+ qpid/client/ClientImportExport.h \
qpid/client/Completion.h \
qpid/client/Connection.h \
qpid/client/ConnectionHandler.h \
@@ -666,6 +674,7 @@ nobase_include_HEADERS = \
qpid/management/ManagementEvent.h \
qpid/management/ManagementExchange.h \
qpid/management/ManagementObject.h \
+ qpid/sys/alloca.h \
qpid/sys/AggregateOutput.h \
qpid/sys/AsynchIO.h \
qpid/sys/AsynchIOHandler.h \
@@ -715,7 +724,8 @@ nobase_include_HEADERS = \
qpid/sys/Time.h \
qpid/sys/Timer.h \
qpid/sys/TimeoutHandler.h \
- qpid/sys/uuid.h
+ qpid/sys/uuid.h \
+ qpid/CommonImportExport.h
# Force build of qpidd during dist phase so help2man will work.
dist-hook: $(BUILT_SOURCES)
diff --git a/qpid/cpp/src/acl.mk b/qpid/cpp/src/acl.mk
index 2b3ab4dfd9..95b47acc1c 100644
--- a/qpid/cpp/src/acl.mk
+++ b/qpid/cpp/src/acl.mk
@@ -31,4 +31,8 @@ acl_la_SOURCES = \
qpid/acl/AclReader.h
acl_la_LIBADD = libqpidbroker.la
+if SUNOS
+ acl_la_LIBADD += libqmfagent.la libqmfconsole.la libqpidcommon.la -lboost_program_options $(SUNCC_RUNTIME_LIBS)
+endif
+
acl_la_LDFLAGS = $(PLUGINLDFLAGS)
diff --git a/qpid/cpp/src/broker.vcproj b/qpid/cpp/src/broker.vcproj
index 7a7bf337a8..e4911e0bfc 100644
--- a/qpid/cpp/src/broker.vcproj
+++ b/qpid/cpp/src/broker.vcproj
@@ -42,9 +42,9 @@
<Configurations>
<Configuration
Name="Debug|Win32"
- OutputDirectory="Static_Debug"
- IntermediateDirectory="Static_Debug\broker\I386"
- ConfigurationType="1"
+ OutputDirectory="."
+ IntermediateDirectory="Debug\broker\I386"
+ ConfigurationType="2"
CharacterSet="0"
>
@@ -73,10 +73,10 @@
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,.,gen"
- PreprocessorDefinitions="_DEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
+ PreprocessorDefinitions="BROKER_EXPORT;_DEBUG;WIN32;_WINDOWS;_CRT_NONSTDC_NO_WARNINGS;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS;BOOST_ALL_DYN_LINK"
MinimalRebuild="false"
BasicRuntimeChecks="3"
- RuntimeLibrary="1"
+ RuntimeLibrary="3"
RuntimeTypeInfo="true"
WarningLevel="3"
Detect64BitPortabilityProblems="false"
@@ -88,7 +88,7 @@
/>
<Tool
Name="VCResourceCompilerTool"
- PreprocessorDefinitions="_DEBUG;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
+ PreprocessorDefinitions="_DEBUG;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS;BOOST_ALL_DYN_LINK"
Culture="1033"
AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,.,gen"
/>
@@ -97,13 +97,14 @@
/>
<Tool
Name="VCLinkerTool"
- AdditionalDependencies="qpidcommonsd.lib ws2_32.lib secur32.lib rpcrt4.lib"
- OutputFile="$(OutDir)\qpidbroker.exe"
+ AdditionalDependencies="qpidcommond.lib secur32.lib"
+ OutputFile="$(OutDir)\qpidbrokerd.dll"
LinkIncremental="2"
SuppressStartupBanner="true"
AdditionalLibraryDirectories=".;$(BOOST_ROOT)\lib"
GenerateDebugInformation="true"
- SubSystem="1"
+ SubSystem="2"
+ ImportLibrary=".\qpidbrokerd.lib"
TargetMachine="1"
/>
<Tool
@@ -120,13 +121,14 @@
/>
<Tool
Name="VCPostBuildEventTool"
+ CommandLine="@if not exist deploy\lib mkdir deploy\lib&#x0D;&#x0A;&#x0D;&#x0A;@copy /Y $(OutDir)\qpidbrokerd.dll deploy\lib\&#x0D;&#x0A;@copy /Y .\qpidbrokerd.lib deploy\lib\&#x0D;&#x0A;"
/>
</Configuration>
<Configuration
Name="Release|Win32"
- OutputDirectory="Static_Release"
- IntermediateDirectory="Static_Release\broker\I386"
- ConfigurationType="1"
+ OutputDirectory="."
+ IntermediateDirectory="Release\broker\I386"
+ ConfigurationType="2"
CharacterSet="0"
>
@@ -155,8 +157,8 @@
Name="VCCLCompilerTool"
Optimization="2"
AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,.,gen"
- PreprocessorDefinitions="NDEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
- RuntimeLibrary="0"
+ PreprocessorDefinitions="BROKER_EXPORT;NDEBUG;WIN32;_WINDOWS;_CRT_NONSTDC_NO_WARNINGS;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS;BOOST_ALL_DYN_LINK"
+ RuntimeLibrary="2"
RuntimeTypeInfo="true"
WarningLevel="3"
Detect64BitPortabilityProblems="false"
@@ -167,7 +169,7 @@
/>
<Tool
Name="VCResourceCompilerTool"
- PreprocessorDefinitions="NDEBUG;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
+ PreprocessorDefinitions="NDEBUG;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS;BOOST_ALL_DYN_LINK"
Culture="1033"
AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,.,gen"
/>
@@ -176,15 +178,16 @@
/>
<Tool
Name="VCLinkerTool"
- AdditionalDependencies="qpidcommons.lib ws2_32.lib secur32.lib rpcrt4.lib"
- OutputFile="$(OutDir)\qpidbroker.exe"
+ AdditionalDependencies="qpidcommon.lib secur32.lib"
+ OutputFile="$(OutDir)\qpidbroker.dll"
LinkIncremental="1"
SuppressStartupBanner="true"
AdditionalLibraryDirectories=".;$(BOOST_ROOT)\lib"
GenerateDebugInformation="true"
- SubSystem="1"
+ SubSystem="2"
OptimizeReferences="2"
EnableCOMDATFolding="2"
+ ImportLibrary=".\qpidbroker.lib"
TargetMachine="1"
/>
<Tool
@@ -201,13 +204,14 @@
/>
<Tool
Name="VCPostBuildEventTool"
+ CommandLine="@if not exist deploy\lib mkdir deploy\lib&#x0D;&#x0A;&#x0D;&#x0A;@copy /Y $(OutDir)\qpidbroker.dll deploy\lib\&#x0D;&#x0A;@copy /Y .\qpidbroker.lib deploy\lib\&#x0D;&#x0A;"
/>
</Configuration>
<Configuration
Name="Debug|x64"
- OutputDirectory="Static_Debug"
- IntermediateDirectory="Static_Debug\broker\AMD64"
- ConfigurationType="1"
+ OutputDirectory="."
+ IntermediateDirectory="Debug\broker\AMD64"
+ ConfigurationType="2"
CharacterSet="0"
>
@@ -236,10 +240,10 @@
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,.,gen"
- PreprocessorDefinitions="_DEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;_AMD64_;_WIN64;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
+ PreprocessorDefinitions="BROKER_EXPORT;_DEBUG;WIN32;_WINDOWS;_CRT_NONSTDC_NO_WARNINGS;_AMD64_;_WIN64;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS;BOOST_ALL_DYN_LINK"
MinimalRebuild="false"
BasicRuntimeChecks="3"
- RuntimeLibrary="1"
+ RuntimeLibrary="3"
RuntimeTypeInfo="true"
WarningLevel="3"
Detect64BitPortabilityProblems="false"
@@ -251,7 +255,7 @@
/>
<Tool
Name="VCResourceCompilerTool"
- PreprocessorDefinitions="_DEBUG;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS;_WIN64"
+ PreprocessorDefinitions="_DEBUG;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS;BOOST_ALL_DYN_LINK;_WIN64"
Culture="1033"
AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,.,gen"
/>
@@ -261,13 +265,14 @@
<Tool
Name="VCLinkerTool"
AdditionalOptions="/machine:AMD64"
- AdditionalDependencies="qpidcommonsd.lib ws2_32.lib secur32.lib rpcrt4.lib"
- OutputFile="$(OutDir)\qpidbroker.exe"
+ AdditionalDependencies="qpidcommond.lib secur32.lib"
+ OutputFile="$(OutDir)\qpidbrokerd.dll"
LinkIncremental="2"
SuppressStartupBanner="true"
AdditionalLibraryDirectories=".;$(BOOST_ROOT)\lib"
GenerateDebugInformation="true"
- SubSystem="1"
+ SubSystem="2"
+ ImportLibrary=".\qpidbrokerd.lib"
TargetMachine="17"
/>
<Tool
@@ -284,13 +289,14 @@
/>
<Tool
Name="VCPostBuildEventTool"
+ CommandLine="@if not exist deploy\lib mkdir deploy\lib&#x0D;&#x0A;&#x0D;&#x0A;@copy /Y $(OutDir)\qpidbrokerd.dll deploy\lib\&#x0D;&#x0A;@copy /Y .\qpidbrokerd.lib deploy\lib\&#x0D;&#x0A;"
/>
</Configuration>
<Configuration
Name="Release|x64"
- OutputDirectory="Static_Release"
- IntermediateDirectory="Static_Release\broker\AMD64"
- ConfigurationType="1"
+ OutputDirectory="."
+ IntermediateDirectory="Release\broker\AMD64"
+ ConfigurationType="2"
CharacterSet="0"
>
@@ -319,8 +325,8 @@
Name="VCCLCompilerTool"
Optimization="2"
AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,.,gen"
- PreprocessorDefinitions="NDEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;_AMD64_;_WIN64;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
- RuntimeLibrary="0"
+ PreprocessorDefinitions="BROKER_EXPORT;NDEBUG;WIN32;_WINDOWS;_CRT_NONSTDC_NO_WARNINGS;_AMD64_;_WIN64;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS;BOOST_ALL_DYN_LINK"
+ RuntimeLibrary="2"
RuntimeTypeInfo="true"
WarningLevel="3"
Detect64BitPortabilityProblems="false"
@@ -331,7 +337,7 @@
/>
<Tool
Name="VCResourceCompilerTool"
- PreprocessorDefinitions="NDEBUG;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS;_WIN64"
+ PreprocessorDefinitions="NDEBUG;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS;BOOST_ALL_DYN_LINK;_WIN64"
Culture="1033"
AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,.,gen"
/>
@@ -341,15 +347,16 @@
<Tool
Name="VCLinkerTool"
AdditionalOptions="/machine:AMD64"
- AdditionalDependencies="qpidcommons.lib ws2_32.lib secur32.lib rpcrt4.lib"
- OutputFile="$(OutDir)\qpidbroker.exe"
+ AdditionalDependencies="qpidcommon.lib secur32.lib"
+ OutputFile="$(OutDir)\qpidbroker.dll"
LinkIncremental="1"
SuppressStartupBanner="true"
AdditionalLibraryDirectories=".;$(BOOST_ROOT)\lib"
GenerateDebugInformation="true"
- SubSystem="1"
+ SubSystem="2"
OptimizeReferences="2"
EnableCOMDATFolding="2"
+ ImportLibrary=".\qpidbroker.lib"
TargetMachine="17"
/>
<Tool
@@ -366,6 +373,7 @@
/>
<Tool
Name="VCPostBuildEventTool"
+ CommandLine="@if not exist deploy\lib mkdir deploy\lib&#x0D;&#x0A;&#x0D;&#x0A;@copy /Y $(OutDir)\qpidbroker.dll deploy\lib\&#x0D;&#x0A;@copy /Y .\qpidbroker.lib deploy\lib\&#x0D;&#x0A;"
/>
</Configuration>
</Configurations>
@@ -909,12 +917,6 @@
<File
RelativePath="qpid\sys\TCPIOPlugin.cpp">
</File>
- <File
- RelativePath="qpidd.cpp">
- </File>
- <File
- RelativePath="windows\QpiddBroker.cpp">
- </File>
</Filter>
<Filter
Name="Header Files"
@@ -1306,9 +1308,6 @@
<File
RelativePath="qpid\management\ManagementObject.h">
</File>
- <File
- RelativePath="qpidd.h">
- </File>
</Filter>
</Files>
<Globals>
diff --git a/qpid/cpp/src/client.vcproj b/qpid/cpp/src/client.vcproj
index e724e04d98..28b7ec73dc 100644
--- a/qpid/cpp/src/client.vcproj
+++ b/qpid/cpp/src/client.vcproj
@@ -43,8 +43,8 @@
<Configuration
Name="Debug|Win32"
OutputDirectory="."
- IntermediateDirectory="Static_Debug\client\I386"
- ConfigurationType="4"
+ IntermediateDirectory="Debug\client\I386"
+ ConfigurationType="2"
CharacterSet="0"
>
@@ -73,10 +73,10 @@
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,.,gen"
- PreprocessorDefinitions="_DEBUG;WIN32;_WINDOWS;_CRT_NONSTDC_NO_WARNINGS;CONF_FILE=\&quot;qpidc.conf\&quot;;MODULE_DIR=\&quot;.\&quot;;NOMINMAX;WIN32_LEAN_AND_MEAN"
+ PreprocessorDefinitions="CLIENT_EXPORT;_DEBUG;WIN32;_WINDOWS;_CRT_NONSTDC_NO_WARNINGS;CONF_FILE=\&quot;qpidc.conf\&quot;;MODULE_DIR=\&quot;.\&quot;;NOMINMAX;WIN32_LEAN_AND_MEAN;BOOST_ALL_DYN_LINK"
MinimalRebuild="false"
BasicRuntimeChecks="3"
- RuntimeLibrary="1"
+ RuntimeLibrary="3"
RuntimeTypeInfo="true"
WarningLevel="3"
Detect64BitPortabilityProblems="false"
@@ -88,7 +88,7 @@
/>
<Tool
Name="VCResourceCompilerTool"
- PreprocessorDefinitions="_DEBUG;CONF_FILE=\&quot;qpidc.conf\&quot;;MODULE_DIR=\&quot;.\&quot;;NOMINMAX;WIN32_LEAN_AND_MEAN"
+ PreprocessorDefinitions="_DEBUG;CONF_FILE=\&quot;qpidc.conf\&quot;;MODULE_DIR=\&quot;.\&quot;;NOMINMAX;WIN32_LEAN_AND_MEAN;BOOST_ALL_DYN_LINK"
Culture="1033"
AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,.,gen"
/>
@@ -96,8 +96,16 @@
Name="VCPreLinkEventTool"
/>
<Tool
- Name="VCLibrarianTool"
- OutputFile=".\qpidclientsd.lib"
+ Name="VCLinkerTool"
+ AdditionalDependencies="qpidcommond.lib"
+ OutputFile="$(OutDir)\qpidclientd.dll"
+ LinkIncremental="2"
+ SuppressStartupBanner="true"
+ AdditionalLibraryDirectories=".;$(BOOST_ROOT)\lib"
+ GenerateDebugInformation="true"
+ SubSystem="2"
+ ImportLibrary=".\qpidclientd.lib"
+ TargetMachine="1"
/>
<Tool
Name="VCALinkTool"
@@ -113,13 +121,14 @@
/>
<Tool
Name="VCPostBuildEventTool"
+ CommandLine="@if not exist deploy\include\qpid\client\no_keyword mkdir deploy\include\qpid\client\no_keyword&#x0D;&#x0A;@if not exist deploy\lib mkdir deploy\lib&#x0D;&#x0A;&#x0D;&#x0A;@copy /Y qpid\client\*.h deploy\include\qpid\client\&#x0D;&#x0A;@copy /Y gen\qpid\client\*.h deploy\include\qpid\client\&#x0D;&#x0A;@copy /Y gen\qpid\client\no_keyword\*.h deploy\include\qpid\client\no_keyword\&#x0D;&#x0A;&#x0D;&#x0A;@copy /Y $(OutDir)\qpidclientd.dll deploy\lib\&#x0D;&#x0A;@copy /Y .\qpidclientd.lib deploy\lib\&#x0D;&#x0A;"
/>
</Configuration>
<Configuration
Name="Release|Win32"
OutputDirectory="."
- IntermediateDirectory="Static_Release\client\I386"
- ConfigurationType="4"
+ IntermediateDirectory="Release\client\I386"
+ ConfigurationType="2"
CharacterSet="0"
>
@@ -148,8 +157,8 @@
Name="VCCLCompilerTool"
Optimization="2"
AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,.,gen"
- PreprocessorDefinitions="NDEBUG;WIN32;_WINDOWS;_CRT_NONSTDC_NO_WARNINGS;CONF_FILE=\&quot;qpidc.conf\&quot;;MODULE_DIR=\&quot;.\&quot;;NOMINMAX;WIN32_LEAN_AND_MEAN"
- RuntimeLibrary="0"
+ PreprocessorDefinitions="CLIENT_EXPORT;NDEBUG;WIN32;_WINDOWS;_CRT_NONSTDC_NO_WARNINGS;CONF_FILE=\&quot;qpidc.conf\&quot;;MODULE_DIR=\&quot;.\&quot;;NOMINMAX;WIN32_LEAN_AND_MEAN;BOOST_ALL_DYN_LINK"
+ RuntimeLibrary="2"
RuntimeTypeInfo="true"
WarningLevel="3"
Detect64BitPortabilityProblems="false"
@@ -160,7 +169,7 @@
/>
<Tool
Name="VCResourceCompilerTool"
- PreprocessorDefinitions="NDEBUG;CONF_FILE=\&quot;qpidc.conf\&quot;;MODULE_DIR=\&quot;.\&quot;;NOMINMAX;WIN32_LEAN_AND_MEAN"
+ PreprocessorDefinitions="NDEBUG;CONF_FILE=\&quot;qpidc.conf\&quot;;MODULE_DIR=\&quot;.\&quot;;NOMINMAX;WIN32_LEAN_AND_MEAN;BOOST_ALL_DYN_LINK"
Culture="1033"
AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,.,gen"
/>
@@ -168,8 +177,18 @@
Name="VCPreLinkEventTool"
/>
<Tool
- Name="VCLibrarianTool"
- OutputFile=".\qpidclients.lib"
+ Name="VCLinkerTool"
+ AdditionalDependencies="qpidcommon.lib"
+ OutputFile="$(OutDir)\qpidclient.dll"
+ LinkIncremental="1"
+ SuppressStartupBanner="true"
+ AdditionalLibraryDirectories=".;$(BOOST_ROOT)\lib"
+ GenerateDebugInformation="true"
+ SubSystem="2"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ ImportLibrary=".\qpidclient.lib"
+ TargetMachine="1"
/>
<Tool
Name="VCALinkTool"
@@ -185,13 +204,14 @@
/>
<Tool
Name="VCPostBuildEventTool"
+ CommandLine="@if not exist deploy\include\qpid\client\no_keyword mkdir deploy\include\qpid\client\no_keyword&#x0D;&#x0A;@if not exist deploy\lib mkdir deploy\lib&#x0D;&#x0A;&#x0D;&#x0A;@copy /Y qpid\client\*.h deploy\include\qpid\client\&#x0D;&#x0A;@copy /Y gen\qpid\client\*.h deploy\include\qpid\client\&#x0D;&#x0A;@copy /Y gen\qpid\client\no_keyword\*.h deploy\include\qpid\client\no_keyword\&#x0D;&#x0A;&#x0D;&#x0A;@copy /Y $(OutDir)\qpidclient.dll deploy\lib\&#x0D;&#x0A;@copy /Y .\qpidclient.lib deploy\lib\&#x0D;&#x0A;"
/>
</Configuration>
<Configuration
Name="Debug|x64"
OutputDirectory="."
- IntermediateDirectory="Static_Debug\client\AMD64"
- ConfigurationType="4"
+ IntermediateDirectory="Debug\client\AMD64"
+ ConfigurationType="2"
CharacterSet="0"
>
@@ -220,10 +240,10 @@
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,.,gen"
- PreprocessorDefinitions="_DEBUG;WIN32;_WINDOWS;_CRT_NONSTDC_NO_WARNINGS;_AMD64_;_WIN64;CONF_FILE=\&quot;qpidc.conf\&quot;;MODULE_DIR=\&quot;.\&quot;;NOMINMAX;WIN32_LEAN_AND_MEAN"
+ PreprocessorDefinitions="CLIENT_EXPORT;_DEBUG;WIN32;_WINDOWS;_CRT_NONSTDC_NO_WARNINGS;_AMD64_;_WIN64;CONF_FILE=\&quot;qpidc.conf\&quot;;MODULE_DIR=\&quot;.\&quot;;NOMINMAX;WIN32_LEAN_AND_MEAN;BOOST_ALL_DYN_LINK"
MinimalRebuild="false"
BasicRuntimeChecks="3"
- RuntimeLibrary="1"
+ RuntimeLibrary="3"
RuntimeTypeInfo="true"
WarningLevel="3"
Detect64BitPortabilityProblems="false"
@@ -235,7 +255,7 @@
/>
<Tool
Name="VCResourceCompilerTool"
- PreprocessorDefinitions="_DEBUG;CONF_FILE=\&quot;qpidc.conf\&quot;;MODULE_DIR=\&quot;.\&quot;;NOMINMAX;WIN32_LEAN_AND_MEAN;_WIN64"
+ PreprocessorDefinitions="_DEBUG;CONF_FILE=\&quot;qpidc.conf\&quot;;MODULE_DIR=\&quot;.\&quot;;NOMINMAX;WIN32_LEAN_AND_MEAN;BOOST_ALL_DYN_LINK;_WIN64"
Culture="1033"
AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,.,gen"
/>
@@ -243,8 +263,17 @@
Name="VCPreLinkEventTool"
/>
<Tool
- Name="VCLibrarianTool"
- OutputFile=".\qpidclientsd.lib"
+ Name="VCLinkerTool"
+ AdditionalOptions="/machine:AMD64"
+ AdditionalDependencies="qpidcommond.lib"
+ OutputFile="$(OutDir)\qpidclientd.dll"
+ LinkIncremental="2"
+ SuppressStartupBanner="true"
+ AdditionalLibraryDirectories=".;$(BOOST_ROOT)\lib"
+ GenerateDebugInformation="true"
+ SubSystem="2"
+ ImportLibrary=".\qpidclientd.lib"
+ TargetMachine="17"
/>
<Tool
Name="VCALinkTool"
@@ -260,13 +289,14 @@
/>
<Tool
Name="VCPostBuildEventTool"
+ CommandLine="@if not exist deploy\include\qpid\client\no_keyword mkdir deploy\include\qpid\client\no_keyword&#x0D;&#x0A;@if not exist deploy\lib mkdir deploy\lib&#x0D;&#x0A;&#x0D;&#x0A;@copy /Y qpid\client\*.h deploy\include\qpid\client\&#x0D;&#x0A;@copy /Y gen\qpid\client\*.h deploy\include\qpid\client\&#x0D;&#x0A;@copy /Y gen\qpid\client\no_keyword\*.h deploy\include\qpid\client\no_keyword\&#x0D;&#x0A;&#x0D;&#x0A;@copy /Y $(OutDir)\qpidclientd.dll deploy\lib\&#x0D;&#x0A;@copy /Y .\qpidclientd.lib deploy\lib\&#x0D;&#x0A;"
/>
</Configuration>
<Configuration
Name="Release|x64"
OutputDirectory="."
- IntermediateDirectory="Static_Release\client\AMD64"
- ConfigurationType="4"
+ IntermediateDirectory="Release\client\AMD64"
+ ConfigurationType="2"
CharacterSet="0"
>
@@ -295,8 +325,8 @@
Name="VCCLCompilerTool"
Optimization="2"
AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,.,gen"
- PreprocessorDefinitions="NDEBUG;WIN32;_WINDOWS;_CRT_NONSTDC_NO_WARNINGS;_AMD64_;_WIN64;CONF_FILE=\&quot;qpidc.conf\&quot;;MODULE_DIR=\&quot;.\&quot;;NOMINMAX;WIN32_LEAN_AND_MEAN"
- RuntimeLibrary="0"
+ PreprocessorDefinitions="CLIENT_EXPORT;NDEBUG;WIN32;_WINDOWS;_CRT_NONSTDC_NO_WARNINGS;_AMD64_;_WIN64;CONF_FILE=\&quot;qpidc.conf\&quot;;MODULE_DIR=\&quot;.\&quot;;NOMINMAX;WIN32_LEAN_AND_MEAN;BOOST_ALL_DYN_LINK"
+ RuntimeLibrary="2"
RuntimeTypeInfo="true"
WarningLevel="3"
Detect64BitPortabilityProblems="false"
@@ -307,7 +337,7 @@
/>
<Tool
Name="VCResourceCompilerTool"
- PreprocessorDefinitions="NDEBUG;CONF_FILE=\&quot;qpidc.conf\&quot;;MODULE_DIR=\&quot;.\&quot;;NOMINMAX;WIN32_LEAN_AND_MEAN;_WIN64"
+ PreprocessorDefinitions="NDEBUG;CONF_FILE=\&quot;qpidc.conf\&quot;;MODULE_DIR=\&quot;.\&quot;;NOMINMAX;WIN32_LEAN_AND_MEAN;BOOST_ALL_DYN_LINK;_WIN64"
Culture="1033"
AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,.,gen"
/>
@@ -315,8 +345,19 @@
Name="VCPreLinkEventTool"
/>
<Tool
- Name="VCLibrarianTool"
- OutputFile=".\qpidclients.lib"
+ Name="VCLinkerTool"
+ AdditionalOptions="/machine:AMD64"
+ AdditionalDependencies="qpidcommon.lib"
+ OutputFile="$(OutDir)\qpidclient.dll"
+ LinkIncremental="1"
+ SuppressStartupBanner="true"
+ AdditionalLibraryDirectories=".;$(BOOST_ROOT)\lib"
+ GenerateDebugInformation="true"
+ SubSystem="2"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ ImportLibrary=".\qpidclient.lib"
+ TargetMachine="17"
/>
<Tool
Name="VCALinkTool"
@@ -332,6 +373,7 @@
/>
<Tool
Name="VCPostBuildEventTool"
+ CommandLine="@if not exist deploy\include\qpid\client\no_keyword mkdir deploy\include\qpid\client\no_keyword&#x0D;&#x0A;@if not exist deploy\lib mkdir deploy\lib&#x0D;&#x0A;&#x0D;&#x0A;@copy /Y qpid\client\*.h deploy\include\qpid\client\&#x0D;&#x0A;@copy /Y gen\qpid\client\*.h deploy\include\qpid\client\&#x0D;&#x0A;@copy /Y gen\qpid\client\no_keyword\*.h deploy\include\qpid\client\no_keyword\&#x0D;&#x0A;&#x0D;&#x0A;@copy /Y $(OutDir)\qpidclient.dll deploy\lib\&#x0D;&#x0A;@copy /Y .\qpidclient.lib deploy\lib\&#x0D;&#x0A;"
/>
</Configuration>
</Configurations>
@@ -414,9 +456,6 @@
RelativePath="qpid\client\Results.cpp">
</File>
<File
- RelativePath="qpid\client\SaslFactory.cpp">
- </File>
- <File
RelativePath="qpid\client\SessionBase_0_10.cpp">
</File>
<File
@@ -440,6 +479,9 @@
<File
RelativePath="qpid\client\SubscriptionManager.cpp">
</File>
+ <File
+ RelativePath="qpid\client\windows\SaslFactory.cpp">
+ </File>
</Filter>
<Filter
Name="Header Files"
diff --git a/qpid/cpp/src/cluster.mk b/qpid/cpp/src/cluster.mk
index 0d34788d2e..e2054d75e9 100644
--- a/qpid/cpp/src/cluster.mk
+++ b/qpid/cpp/src/cluster.mk
@@ -40,6 +40,8 @@ cluster_la_SOURCES = \
$(CMAN_SOURCES) \
qpid/cluster/Cluster.cpp \
qpid/cluster/Cluster.h \
+ qpid/cluster/Decoder.cpp \
+ qpid/cluster/Decoder.h \
qpid/cluster/PollableQueue.h \
qpid/cluster/ClusterMap.cpp \
qpid/cluster/ClusterMap.h \
@@ -49,14 +51,8 @@ cluster_la_SOURCES = \
qpid/cluster/Connection.h \
qpid/cluster/ConnectionCodec.cpp \
qpid/cluster/ConnectionCodec.h \
- qpid/cluster/ConnectionMap.h \
- qpid/cluster/ConnectionMap.cpp \
qpid/cluster/Cpg.cpp \
qpid/cluster/Cpg.h \
- qpid/cluster/Decoder.cpp \
- qpid/cluster/Decoder.h \
- qpid/cluster/ConnectionDecoder.cpp \
- qpid/cluster/ConnectionDecoder.h \
qpid/cluster/Dispatchable.h \
qpid/cluster/UpdateClient.cpp \
qpid/cluster/UpdateClient.h \
@@ -68,8 +64,11 @@ cluster_la_SOURCES = \
qpid/cluster/ExpiryPolicy.cpp \
qpid/cluster/FailoverExchange.cpp \
qpid/cluster/FailoverExchange.h \
+ qpid/cluster/UpdateExchange.h \
+ qpid/cluster/LockedConnectionMap.h \
qpid/cluster/Multicaster.cpp \
qpid/cluster/Multicaster.h \
+ qpid/cluster/McastFrameHandler.h \
qpid/cluster/NoOpConnectionOutputHandler.h \
qpid/cluster/OutputInterceptor.cpp \
qpid/cluster/OutputInterceptor.h \
diff --git a/qpid/cpp/src/common.vcproj b/qpid/cpp/src/common.vcproj
index e8c40da426..96d67b9d54 100644
--- a/qpid/cpp/src/common.vcproj
+++ b/qpid/cpp/src/common.vcproj
@@ -43,8 +43,8 @@
<Configuration
Name="Debug|Win32"
OutputDirectory="."
- IntermediateDirectory="Static_Debug\common\I386"
- ConfigurationType="4"
+ IntermediateDirectory="Debug\common\I386"
+ ConfigurationType="2"
CharacterSet="0"
>
@@ -73,10 +73,10 @@
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,.,gen"
- PreprocessorDefinitions="_DEBUG;WIN32;_WINDOWS;_CRT_NONSTDC_NO_WARNINGS;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
+ PreprocessorDefinitions="COMMON_EXPORT;_DEBUG;WIN32;_WINDOWS;_CRT_NONSTDC_NO_WARNINGS;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS;BOOST_ALL_DYN_LINK"
MinimalRebuild="false"
BasicRuntimeChecks="3"
- RuntimeLibrary="1"
+ RuntimeLibrary="3"
RuntimeTypeInfo="true"
WarningLevel="3"
Detect64BitPortabilityProblems="false"
@@ -88,7 +88,7 @@
/>
<Tool
Name="VCResourceCompilerTool"
- PreprocessorDefinitions="_DEBUG;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
+ PreprocessorDefinitions="_DEBUG;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS;BOOST_ALL_DYN_LINK"
Culture="1033"
AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,.,gen"
/>
@@ -96,8 +96,16 @@
Name="VCPreLinkEventTool"
/>
<Tool
- Name="VCLibrarianTool"
- OutputFile=".\qpidcommonsd.lib"
+ Name="VCLinkerTool"
+ AdditionalDependencies=" ws2_32.lib rpcrt4.lib"
+ OutputFile="$(OutDir)\qpidcommond.dll"
+ LinkIncremental="2"
+ SuppressStartupBanner="true"
+ AdditionalLibraryDirectories=".;$(BOOST_ROOT)\lib"
+ GenerateDebugInformation="true"
+ SubSystem="2"
+ ImportLibrary=".\qpidcommond.lib"
+ TargetMachine="1"
/>
<Tool
Name="VCALinkTool"
@@ -113,13 +121,14 @@
/>
<Tool
Name="VCPostBuildEventTool"
+ CommandLine="@if not exist deploy\include\qpid mkdir deploy\include\qpid&#x0D;&#x0A;@if not exist deploy\include\qpid\amqp_0_10 mkdir deploy\include\qpid\amqp_0_10&#x0D;&#x0A;@if not exist deploy\include\qpid\framing mkdir deploy\include\qpid\framing&#x0D;&#x0A;@if not exist deploy\include\qpid\sys\windows mkdir deploy\include\qpid\sys\windows&#x0D;&#x0A;@if not exist deploy\include\qpid\log\windows mkdir deploy\include\qpid\log\windows&#x0D;&#x0A;@if not exist deploy\include\qpid\management mkdir deploy\include\qpid\management&#x0D;&#x0A;@if not exist deploy\lib mkdir deploy\lib&#x0D;&#x0A;&#x0D;&#x0A;@copy /Y qpid\*.h deploy\include\qpid\&#x0D;&#x0A;@copy /Y qpid\amqp_0_10\*.h deploy\include\qpid\amqp_0_10\&#x0D;&#x0A;@copy /Y qpid\framing\*.h deploy\include\qpid\framing\&#x0D;&#x0A;@copy /Y qpid\sys\*.h deploy\include\qpid\sys\&#x0D;&#x0A;@copy /Y qpid\sys\windows\*.h deploy\include\qpid\sys\windows\&#x0D;&#x0A;@copy /Y qpid\log\*.h deploy\include\qpid\log\&#x0D;&#x0A;@copy /Y qpid\log\windows\*.h deploy\include\qpid\log\windows\&#x0D;&#x0A;@copy /Y qpid\management\*.h deploy\include\qpid\management\&#x0D;&#x0A;&#x0D;&#x0A;@copy /Y $(OutDir)\qpidcommond.dll deploy\lib\&#x0D;&#x0A;@copy /Y .\qpidcommond.lib deploy\lib\&#x0D;&#x0A;"
/>
</Configuration>
<Configuration
Name="Release|Win32"
OutputDirectory="."
- IntermediateDirectory="Static_Release\common\I386"
- ConfigurationType="4"
+ IntermediateDirectory="Release\common\I386"
+ ConfigurationType="2"
CharacterSet="0"
>
@@ -148,8 +157,8 @@
Name="VCCLCompilerTool"
Optimization="2"
AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,.,gen"
- PreprocessorDefinitions="NDEBUG;WIN32;_WINDOWS;_CRT_NONSTDC_NO_WARNINGS;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
- RuntimeLibrary="0"
+ PreprocessorDefinitions="COMMON_EXPORT;NDEBUG;WIN32;_WINDOWS;_CRT_NONSTDC_NO_WARNINGS;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS;BOOST_ALL_DYN_LINK"
+ RuntimeLibrary="2"
RuntimeTypeInfo="true"
WarningLevel="3"
Detect64BitPortabilityProblems="false"
@@ -160,7 +169,7 @@
/>
<Tool
Name="VCResourceCompilerTool"
- PreprocessorDefinitions="NDEBUG;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
+ PreprocessorDefinitions="NDEBUG;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS;BOOST_ALL_DYN_LINK"
Culture="1033"
AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,.,gen"
/>
@@ -168,8 +177,18 @@
Name="VCPreLinkEventTool"
/>
<Tool
- Name="VCLibrarianTool"
- OutputFile=".\qpidcommons.lib"
+ Name="VCLinkerTool"
+ AdditionalDependencies=" ws2_32.lib rpcrt4.lib"
+ OutputFile="$(OutDir)\qpidcommon.dll"
+ LinkIncremental="1"
+ SuppressStartupBanner="true"
+ AdditionalLibraryDirectories=".;$(BOOST_ROOT)\lib"
+ GenerateDebugInformation="true"
+ SubSystem="2"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ ImportLibrary=".\qpidcommon.lib"
+ TargetMachine="1"
/>
<Tool
Name="VCALinkTool"
@@ -185,13 +204,14 @@
/>
<Tool
Name="VCPostBuildEventTool"
+ CommandLine="@if not exist deploy\include\qpid mkdir deploy\include\qpid&#x0D;&#x0A;@if not exist deploy\include\qpid\amqp_0_10 mkdir deploy\include\qpid\amqp_0_10&#x0D;&#x0A;@if not exist deploy\include\qpid\framing mkdir deploy\include\qpid\framing&#x0D;&#x0A;@if not exist deploy\include\qpid\sys\windows mkdir deploy\include\qpid\sys\windows&#x0D;&#x0A;@if not exist deploy\include\qpid\log\windows mkdir deploy\include\qpid\log\windows&#x0D;&#x0A;@if not exist deploy\include\qpid\management mkdir deploy\include\qpid\management&#x0D;&#x0A;@if not exist deploy\lib mkdir deploy\lib&#x0D;&#x0A;&#x0D;&#x0A;@copy /Y qpid\*.h deploy\include\qpid\&#x0D;&#x0A;@copy /Y qpid\amqp_0_10\*.h deploy\include\qpid\amqp_0_10\&#x0D;&#x0A;@copy /Y qpid\framing\*.h deploy\include\qpid\framing\&#x0D;&#x0A;@copy /Y qpid\sys\*.h deploy\include\qpid\sys\&#x0D;&#x0A;@copy /Y qpid\sys\windows\*.h deploy\include\qpid\sys\windows\&#x0D;&#x0A;@copy /Y qpid\log\*.h deploy\include\qpid\log\&#x0D;&#x0A;@copy /Y qpid\log\windows\*.h deploy\include\qpid\log\windows\&#x0D;&#x0A;@copy /Y qpid\management\*.h deploy\include\qpid\management\&#x0D;&#x0A;&#x0D;&#x0A;@copy /Y $(OutDir)\qpidcommon.dll deploy\lib\&#x0D;&#x0A;@copy /Y .\qpidcommon.lib deploy\lib\&#x0D;&#x0A;"
/>
</Configuration>
<Configuration
Name="Debug|x64"
OutputDirectory="."
- IntermediateDirectory="Static_Debug\common\AMD64"
- ConfigurationType="4"
+ IntermediateDirectory="Debug\common\AMD64"
+ ConfigurationType="2"
CharacterSet="0"
>
@@ -220,10 +240,10 @@
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,.,gen"
- PreprocessorDefinitions="_DEBUG;WIN32;_WINDOWS;_CRT_NONSTDC_NO_WARNINGS;_AMD64_;_WIN64;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
+ PreprocessorDefinitions="COMMON_EXPORT;_DEBUG;WIN32;_WINDOWS;_CRT_NONSTDC_NO_WARNINGS;_AMD64_;_WIN64;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS;BOOST_ALL_DYN_LINK"
MinimalRebuild="false"
BasicRuntimeChecks="3"
- RuntimeLibrary="1"
+ RuntimeLibrary="3"
RuntimeTypeInfo="true"
WarningLevel="3"
Detect64BitPortabilityProblems="false"
@@ -235,7 +255,7 @@
/>
<Tool
Name="VCResourceCompilerTool"
- PreprocessorDefinitions="_DEBUG;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS;_WIN64"
+ PreprocessorDefinitions="_DEBUG;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS;BOOST_ALL_DYN_LINK;_WIN64"
Culture="1033"
AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,.,gen"
/>
@@ -243,8 +263,17 @@
Name="VCPreLinkEventTool"
/>
<Tool
- Name="VCLibrarianTool"
- OutputFile=".\qpidcommonsd.lib"
+ Name="VCLinkerTool"
+ AdditionalOptions="/machine:AMD64"
+ AdditionalDependencies=" ws2_32.lib rpcrt4.lib"
+ OutputFile="$(OutDir)\qpidcommond.dll"
+ LinkIncremental="2"
+ SuppressStartupBanner="true"
+ AdditionalLibraryDirectories=".;$(BOOST_ROOT)\lib"
+ GenerateDebugInformation="true"
+ SubSystem="2"
+ ImportLibrary=".\qpidcommond.lib"
+ TargetMachine="17"
/>
<Tool
Name="VCALinkTool"
@@ -260,13 +289,14 @@
/>
<Tool
Name="VCPostBuildEventTool"
+ CommandLine="@if not exist deploy\include\qpid mkdir deploy\include\qpid&#x0D;&#x0A;@if not exist deploy\include\qpid\amqp_0_10 mkdir deploy\include\qpid\amqp_0_10&#x0D;&#x0A;@if not exist deploy\include\qpid\framing mkdir deploy\include\qpid\framing&#x0D;&#x0A;@if not exist deploy\include\qpid\sys\windows mkdir deploy\include\qpid\sys\windows&#x0D;&#x0A;@if not exist deploy\include\qpid\log\windows mkdir deploy\include\qpid\log\windows&#x0D;&#x0A;@if not exist deploy\include\qpid\management mkdir deploy\include\qpid\management&#x0D;&#x0A;@if not exist deploy\lib mkdir deploy\lib&#x0D;&#x0A;&#x0D;&#x0A;@copy /Y qpid\*.h deploy\include\qpid\&#x0D;&#x0A;@copy /Y qpid\amqp_0_10\*.h deploy\include\qpid\amqp_0_10\&#x0D;&#x0A;@copy /Y qpid\framing\*.h deploy\include\qpid\framing\&#x0D;&#x0A;@copy /Y qpid\sys\*.h deploy\include\qpid\sys\&#x0D;&#x0A;@copy /Y qpid\sys\windows\*.h deploy\include\qpid\sys\windows\&#x0D;&#x0A;@copy /Y qpid\log\*.h deploy\include\qpid\log\&#x0D;&#x0A;@copy /Y qpid\log\windows\*.h deploy\include\qpid\log\windows\&#x0D;&#x0A;@copy /Y qpid\management\*.h deploy\include\qpid\management\&#x0D;&#x0A;&#x0D;&#x0A;@copy /Y $(OutDir)\qpidcommond.dll deploy\lib\&#x0D;&#x0A;@copy /Y .\qpidcommond.lib deploy\lib\&#x0D;&#x0A;"
/>
</Configuration>
<Configuration
Name="Release|x64"
OutputDirectory="."
- IntermediateDirectory="Static_Release\common\AMD64"
- ConfigurationType="4"
+ IntermediateDirectory="Release\common\AMD64"
+ ConfigurationType="2"
CharacterSet="0"
>
@@ -295,8 +325,8 @@
Name="VCCLCompilerTool"
Optimization="2"
AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,.,gen"
- PreprocessorDefinitions="NDEBUG;WIN32;_WINDOWS;_CRT_NONSTDC_NO_WARNINGS;_AMD64_;_WIN64;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
- RuntimeLibrary="0"
+ PreprocessorDefinitions="COMMON_EXPORT;NDEBUG;WIN32;_WINDOWS;_CRT_NONSTDC_NO_WARNINGS;_AMD64_;_WIN64;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS;BOOST_ALL_DYN_LINK"
+ RuntimeLibrary="2"
RuntimeTypeInfo="true"
WarningLevel="3"
Detect64BitPortabilityProblems="false"
@@ -307,7 +337,7 @@
/>
<Tool
Name="VCResourceCompilerTool"
- PreprocessorDefinitions="NDEBUG;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS;_WIN64"
+ PreprocessorDefinitions="NDEBUG;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS;BOOST_ALL_DYN_LINK;_WIN64"
Culture="1033"
AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,.,gen"
/>
@@ -315,8 +345,19 @@
Name="VCPreLinkEventTool"
/>
<Tool
- Name="VCLibrarianTool"
- OutputFile=".\qpidcommons.lib"
+ Name="VCLinkerTool"
+ AdditionalOptions="/machine:AMD64"
+ AdditionalDependencies=" ws2_32.lib rpcrt4.lib"
+ OutputFile="$(OutDir)\qpidcommon.dll"
+ LinkIncremental="1"
+ SuppressStartupBanner="true"
+ AdditionalLibraryDirectories=".;$(BOOST_ROOT)\lib"
+ GenerateDebugInformation="true"
+ SubSystem="2"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ ImportLibrary=".\qpidcommon.lib"
+ TargetMachine="17"
/>
<Tool
Name="VCALinkTool"
@@ -332,6 +373,7 @@
/>
<Tool
Name="VCPostBuildEventTool"
+ CommandLine="@if not exist deploy\include\qpid mkdir deploy\include\qpid&#x0D;&#x0A;@if not exist deploy\include\qpid\amqp_0_10 mkdir deploy\include\qpid\amqp_0_10&#x0D;&#x0A;@if not exist deploy\include\qpid\framing mkdir deploy\include\qpid\framing&#x0D;&#x0A;@if not exist deploy\include\qpid\sys\windows mkdir deploy\include\qpid\sys\windows&#x0D;&#x0A;@if not exist deploy\include\qpid\log\windows mkdir deploy\include\qpid\log\windows&#x0D;&#x0A;@if not exist deploy\include\qpid\management mkdir deploy\include\qpid\management&#x0D;&#x0A;@if not exist deploy\lib mkdir deploy\lib&#x0D;&#x0A;&#x0D;&#x0A;@copy /Y qpid\*.h deploy\include\qpid\&#x0D;&#x0A;@copy /Y qpid\amqp_0_10\*.h deploy\include\qpid\amqp_0_10\&#x0D;&#x0A;@copy /Y qpid\framing\*.h deploy\include\qpid\framing\&#x0D;&#x0A;@copy /Y qpid\sys\*.h deploy\include\qpid\sys\&#x0D;&#x0A;@copy /Y qpid\sys\windows\*.h deploy\include\qpid\sys\windows\&#x0D;&#x0A;@copy /Y qpid\log\*.h deploy\include\qpid\log\&#x0D;&#x0A;@copy /Y qpid\log\windows\*.h deploy\include\qpid\log\windows\&#x0D;&#x0A;@copy /Y qpid\management\*.h deploy\include\qpid\management\&#x0D;&#x0A;&#x0D;&#x0A;@copy /Y $(OutDir)\qpidcommon.dll deploy\lib\&#x0D;&#x0A;@copy /Y .\qpidcommon.lib deploy\lib\&#x0D;&#x0A;"
/>
</Configuration>
</Configurations>
@@ -378,6 +420,9 @@
RelativePath="gen\qpid\framing\ClusterConnectionExchangeBody.cpp">
</File>
<File
+ RelativePath="gen\qpid\framing\ClusterConnectionExpiryIdBody.cpp">
+ </File>
+ <File
RelativePath="gen\qpid\framing\ClusterConnectionMembershipBody.cpp">
</File>
<File
@@ -954,6 +999,9 @@
RelativePath="qpid\sys\windows\LockFile.cpp">
</File>
<File
+ RelativePath="qpid\sys\windows\PollableCondition.cpp">
+ </File>
+ <File
RelativePath="qpid\sys\windows\Shlib.cpp">
<FileConfiguration
Name="Debug|Win32">
@@ -1081,6 +1129,9 @@
RelativePath="gen\qpid\framing\ClusterConnectionExchangeBody.h">
</File>
<File
+ RelativePath="gen\qpid\framing\ClusterConnectionExpiryIdBody.h">
+ </File>
+ <File
RelativePath="gen\qpid\framing\ClusterConnectionMembershipBody.h">
</File>
<File
diff --git a/qpid/cpp/src/qmfc.mk b/qpid/cpp/src/qmfc.mk
index 46e8d82f35..a95028413d 100644
--- a/qpid/cpp/src/qmfc.mk
+++ b/qpid/cpp/src/qmfc.mk
@@ -26,6 +26,7 @@ module_hdr += \
qpid/console/Agent.h \
qpid/console/Broker.h \
qpid/console/ClassKey.h \
+ qpid/console/ConsoleImportExport.h \
qpid/console/ConsoleListener.h \
qpid/console/Event.h \
qpid/console/Object.h \
@@ -43,6 +44,7 @@ libqmfconsole_la_SOURCES = \
qpid/console/Broker.cpp \
qpid/console/ClassKey.h \
qpid/console/ClassKey.cpp \
+ qpid/console/ConsoleImportExport.h \
qpid/console/ConsoleListener.h \
qpid/console/Event.h \
qpid/console/Event.cpp \
diff --git a/qpid/cpp/src/qmfconsole.vcproj b/qpid/cpp/src/qmfconsole.vcproj
index c37055adec..d2f79af64b 100644
--- a/qpid/cpp/src/qmfconsole.vcproj
+++ b/qpid/cpp/src/qmfconsole.vcproj
@@ -43,8 +43,8 @@
<Configuration
Name="Debug|Win32"
OutputDirectory="."
- IntermediateDirectory="Static_Debug\qmfconsole\I386"
- ConfigurationType="4"
+ IntermediateDirectory="Debug\qmfconsole\I386"
+ ConfigurationType="2"
CharacterSet="0"
>
@@ -73,10 +73,10 @@
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,.,gen"
- PreprocessorDefinitions="_DEBUG;WIN32;_WINDOWS;_CRT_NONSTDC_NO_WARNINGS;NOMINMAX;WIN32_LEAN_AND_MEAN"
+ PreprocessorDefinitions="CONSOLE_EXPORT;_DEBUG;WIN32;_WINDOWS;_CRT_NONSTDC_NO_WARNINGS;NOMINMAX;WIN32_LEAN_AND_MEAN;BOOST_ALL_DYN_LINK"
MinimalRebuild="false"
BasicRuntimeChecks="3"
- RuntimeLibrary="1"
+ RuntimeLibrary="3"
RuntimeTypeInfo="true"
WarningLevel="3"
Detect64BitPortabilityProblems="false"
@@ -88,7 +88,7 @@
/>
<Tool
Name="VCResourceCompilerTool"
- PreprocessorDefinitions="_DEBUG;NOMINMAX;WIN32_LEAN_AND_MEAN"
+ PreprocessorDefinitions="_DEBUG;NOMINMAX;WIN32_LEAN_AND_MEAN;BOOST_ALL_DYN_LINK"
Culture="1033"
AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,.,gen"
/>
@@ -96,8 +96,16 @@
Name="VCPreLinkEventTool"
/>
<Tool
- Name="VCLibrarianTool"
- OutputFile=".\qmfconsolesd.lib"
+ Name="VCLinkerTool"
+ AdditionalDependencies="qpidcommond.lib qpidclientd.lib"
+ OutputFile="$(OutDir)\qmfconsoled.dll"
+ LinkIncremental="2"
+ SuppressStartupBanner="true"
+ AdditionalLibraryDirectories=".;$(BOOST_ROOT)\lib"
+ GenerateDebugInformation="true"
+ SubSystem="2"
+ ImportLibrary=".\qmfconsoled.lib"
+ TargetMachine="1"
/>
<Tool
Name="VCALinkTool"
@@ -113,13 +121,14 @@
/>
<Tool
Name="VCPostBuildEventTool"
+ CommandLine="@if not exist deploy\include\qpid\console mkdir deploy\include\qpid\console&#x0D;&#x0A;@if not exist deploy\lib mkdir deploy\lib&#x0D;&#x0A;&#x0D;&#x0A;@copy /Y qpid\console\*.h deploy\include\qpid\console\&#x0D;&#x0A;&#x0D;&#x0A;@copy /Y $(OutDir)\qmfconsoled.dll deploy\lib\&#x0D;&#x0A;@copy /Y .\qmfconsoled.lib deploy\lib\&#x0D;&#x0A;"
/>
</Configuration>
<Configuration
Name="Release|Win32"
OutputDirectory="."
- IntermediateDirectory="Static_Release\qmfconsole\I386"
- ConfigurationType="4"
+ IntermediateDirectory="Release\qmfconsole\I386"
+ ConfigurationType="2"
CharacterSet="0"
>
@@ -148,8 +157,8 @@
Name="VCCLCompilerTool"
Optimization="2"
AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,.,gen"
- PreprocessorDefinitions="NDEBUG;WIN32;_WINDOWS;_CRT_NONSTDC_NO_WARNINGS;NOMINMAX;WIN32_LEAN_AND_MEAN"
- RuntimeLibrary="0"
+ PreprocessorDefinitions="CONSOLE_EXPORT;NDEBUG;WIN32;_WINDOWS;_CRT_NONSTDC_NO_WARNINGS;NOMINMAX;WIN32_LEAN_AND_MEAN;BOOST_ALL_DYN_LINK"
+ RuntimeLibrary="2"
RuntimeTypeInfo="true"
WarningLevel="3"
Detect64BitPortabilityProblems="false"
@@ -160,7 +169,7 @@
/>
<Tool
Name="VCResourceCompilerTool"
- PreprocessorDefinitions="NDEBUG;NOMINMAX;WIN32_LEAN_AND_MEAN"
+ PreprocessorDefinitions="NDEBUG;NOMINMAX;WIN32_LEAN_AND_MEAN;BOOST_ALL_DYN_LINK"
Culture="1033"
AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,.,gen"
/>
@@ -168,8 +177,18 @@
Name="VCPreLinkEventTool"
/>
<Tool
- Name="VCLibrarianTool"
- OutputFile=".\qmfconsoles.lib"
+ Name="VCLinkerTool"
+ AdditionalDependencies="qpidcommon.lib qpidclient.lib"
+ OutputFile="$(OutDir)\qmfconsole.dll"
+ LinkIncremental="1"
+ SuppressStartupBanner="true"
+ AdditionalLibraryDirectories=".;$(BOOST_ROOT)\lib"
+ GenerateDebugInformation="true"
+ SubSystem="2"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ ImportLibrary=".\qmfconsole.lib"
+ TargetMachine="1"
/>
<Tool
Name="VCALinkTool"
@@ -185,13 +204,14 @@
/>
<Tool
Name="VCPostBuildEventTool"
+ CommandLine="@if not exist deploy\include\qpid\console mkdir deploy\include\qpid\console&#x0D;&#x0A;@if not exist deploy\lib mkdir deploy\lib&#x0D;&#x0A;&#x0D;&#x0A;@copy /Y qpid\console\*.h deploy\include\qpid\console\&#x0D;&#x0A;&#x0D;&#x0A;@copy /Y $(OutDir)\qmfconsole.dll deploy\lib\&#x0D;&#x0A;@copy /Y .\qmfconsole.lib deploy\lib\&#x0D;&#x0A;"
/>
</Configuration>
<Configuration
Name="Debug|x64"
OutputDirectory="."
- IntermediateDirectory="Static_Debug\qmfconsole\AMD64"
- ConfigurationType="4"
+ IntermediateDirectory="Debug\qmfconsole\AMD64"
+ ConfigurationType="2"
CharacterSet="0"
>
@@ -220,10 +240,10 @@
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,.,gen"
- PreprocessorDefinitions="_DEBUG;WIN32;_WINDOWS;_CRT_NONSTDC_NO_WARNINGS;_AMD64_;_WIN64;NOMINMAX;WIN32_LEAN_AND_MEAN"
+ PreprocessorDefinitions="CONSOLE_EXPORT;_DEBUG;WIN32;_WINDOWS;_CRT_NONSTDC_NO_WARNINGS;_AMD64_;_WIN64;NOMINMAX;WIN32_LEAN_AND_MEAN;BOOST_ALL_DYN_LINK"
MinimalRebuild="false"
BasicRuntimeChecks="3"
- RuntimeLibrary="1"
+ RuntimeLibrary="3"
RuntimeTypeInfo="true"
WarningLevel="3"
Detect64BitPortabilityProblems="false"
@@ -235,7 +255,7 @@
/>
<Tool
Name="VCResourceCompilerTool"
- PreprocessorDefinitions="_DEBUG;NOMINMAX;WIN32_LEAN_AND_MEAN;_WIN64"
+ PreprocessorDefinitions="_DEBUG;NOMINMAX;WIN32_LEAN_AND_MEAN;BOOST_ALL_DYN_LINK;_WIN64"
Culture="1033"
AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,.,gen"
/>
@@ -243,8 +263,17 @@
Name="VCPreLinkEventTool"
/>
<Tool
- Name="VCLibrarianTool"
- OutputFile=".\qmfconsolesd.lib"
+ Name="VCLinkerTool"
+ AdditionalOptions="/machine:AMD64"
+ AdditionalDependencies="qpidcommond.lib qpidclientd.lib"
+ OutputFile="$(OutDir)\qmfconsoled.dll"
+ LinkIncremental="2"
+ SuppressStartupBanner="true"
+ AdditionalLibraryDirectories=".;$(BOOST_ROOT)\lib"
+ GenerateDebugInformation="true"
+ SubSystem="2"
+ ImportLibrary=".\qmfconsoled.lib"
+ TargetMachine="17"
/>
<Tool
Name="VCALinkTool"
@@ -260,13 +289,14 @@
/>
<Tool
Name="VCPostBuildEventTool"
+ CommandLine="@if not exist deploy\include\qpid\console mkdir deploy\include\qpid\console&#x0D;&#x0A;@if not exist deploy\lib mkdir deploy\lib&#x0D;&#x0A;&#x0D;&#x0A;@copy /Y qpid\console\*.h deploy\include\qpid\console\&#x0D;&#x0A;&#x0D;&#x0A;@copy /Y $(OutDir)\qmfconsoled.dll deploy\lib\&#x0D;&#x0A;@copy /Y .\qmfconsoled.lib deploy\lib\&#x0D;&#x0A;"
/>
</Configuration>
<Configuration
Name="Release|x64"
OutputDirectory="."
- IntermediateDirectory="Static_Release\qmfconsole\AMD64"
- ConfigurationType="4"
+ IntermediateDirectory="Release\qmfconsole\AMD64"
+ ConfigurationType="2"
CharacterSet="0"
>
@@ -295,8 +325,8 @@
Name="VCCLCompilerTool"
Optimization="2"
AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,.,gen"
- PreprocessorDefinitions="NDEBUG;WIN32;_WINDOWS;_CRT_NONSTDC_NO_WARNINGS;_AMD64_;_WIN64;NOMINMAX;WIN32_LEAN_AND_MEAN"
- RuntimeLibrary="0"
+ PreprocessorDefinitions="CONSOLE_EXPORT;NDEBUG;WIN32;_WINDOWS;_CRT_NONSTDC_NO_WARNINGS;_AMD64_;_WIN64;NOMINMAX;WIN32_LEAN_AND_MEAN;BOOST_ALL_DYN_LINK"
+ RuntimeLibrary="2"
RuntimeTypeInfo="true"
WarningLevel="3"
Detect64BitPortabilityProblems="false"
@@ -307,7 +337,7 @@
/>
<Tool
Name="VCResourceCompilerTool"
- PreprocessorDefinitions="NDEBUG;NOMINMAX;WIN32_LEAN_AND_MEAN;_WIN64"
+ PreprocessorDefinitions="NDEBUG;NOMINMAX;WIN32_LEAN_AND_MEAN;BOOST_ALL_DYN_LINK;_WIN64"
Culture="1033"
AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,.,gen"
/>
@@ -315,8 +345,19 @@
Name="VCPreLinkEventTool"
/>
<Tool
- Name="VCLibrarianTool"
- OutputFile=".\qmfconsoles.lib"
+ Name="VCLinkerTool"
+ AdditionalOptions="/machine:AMD64"
+ AdditionalDependencies="qpidcommon.lib qpidclient.lib"
+ OutputFile="$(OutDir)\qmfconsole.dll"
+ LinkIncremental="1"
+ SuppressStartupBanner="true"
+ AdditionalLibraryDirectories=".;$(BOOST_ROOT)\lib"
+ GenerateDebugInformation="true"
+ SubSystem="2"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ ImportLibrary=".\qmfconsole.lib"
+ TargetMachine="17"
/>
<Tool
Name="VCALinkTool"
@@ -332,6 +373,7 @@
/>
<Tool
Name="VCPostBuildEventTool"
+ CommandLine="@if not exist deploy\include\qpid\console mkdir deploy\include\qpid\console&#x0D;&#x0A;@if not exist deploy\lib mkdir deploy\lib&#x0D;&#x0A;&#x0D;&#x0A;@copy /Y qpid\console\*.h deploy\include\qpid\console\&#x0D;&#x0A;&#x0D;&#x0A;@copy /Y $(OutDir)\qmfconsole.dll deploy\lib\&#x0D;&#x0A;@copy /Y .\qmfconsole.lib deploy\lib\&#x0D;&#x0A;"
/>
</Configuration>
</Configurations>
diff --git a/qpid/cpp/src/qpid.sln b/qpid/cpp/src/qpid.sln
index a296a13d25..c7004444f9 100644
--- a/qpid/cpp/src/qpid.sln
+++ b/qpid/cpp/src/qpid.sln
@@ -7,7 +7,7 @@ Microsoft Visual Studio Solution File, Format Version 10.00
# this file will be lost the next time it is generated.
#
# MPC Command:
-# C:\ace\MPC\mwc.pl -type vc9 -features boost=1 -static qpid.mwc
+# C:\ace\MPC\mwc.pl -type vc9 -features boost=1 qpid.mwc
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "broker", "broker.vcproj", "{09613D48-FECA-1BAD-9D20-8C374564ADCF}"
ProjectSection(ProjectDependencies) = postProject
{C961EF23-FECA-1BAD-BB9C-8C3A4564ADCF} = {C961EF23-FECA-1BAD-BB9C-8C3A4564ADCF}
@@ -25,6 +25,12 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "qmfconsole", "qmfconsole.vc
{6961DBA3-FECA-1BAD-F396-8C394564ADCF} = {6961DBA3-FECA-1BAD-F396-8C394564ADCF}
EndProjectSection
EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "qpidbroker", "qpidbroker.vcproj", "{66213D3E-FECA-1BAD-9D20-8C374564ADCF}"
+ ProjectSection(ProjectDependencies) = postProject
+ {09613D48-FECA-1BAD-9D20-8C374564ADCF} = {09613D48-FECA-1BAD-9D20-8C374564ADCF}
+ {C961EF23-FECA-1BAD-BB9C-8C3A4564ADCF} = {C961EF23-FECA-1BAD-BB9C-8C3A4564ADCF}
+ EndProjectSection
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Win32 = Debug|Win32
@@ -65,6 +71,14 @@ Global
{C95DE177-FECA-1BAD-5EDC-8FFA4564ADCF}.Release|Win32.Build.0 = Release|Win32
{C95DE177-FECA-1BAD-5EDC-8FFA4564ADCF}.Release|x64.ActiveCfg = Release|x64
{C95DE177-FECA-1BAD-5EDC-8FFA4564ADCF}.Release|x64.Build.0 = Release|x64
+ {66213D3E-FECA-1BAD-9D20-8C374564ADCF}.Debug|Win32.ActiveCfg = Debug|Win32
+ {66213D3E-FECA-1BAD-9D20-8C374564ADCF}.Debug|Win32.Build.0 = Debug|Win32
+ {66213D3E-FECA-1BAD-9D20-8C374564ADCF}.Debug|x64.ActiveCfg = Debug|x64
+ {66213D3E-FECA-1BAD-9D20-8C374564ADCF}.Debug|x64.Build.0 = Debug|x64
+ {66213D3E-FECA-1BAD-9D20-8C374564ADCF}.Release|Win32.ActiveCfg = Release|Win32
+ {66213D3E-FECA-1BAD-9D20-8C374564ADCF}.Release|Win32.Build.0 = Release|Win32
+ {66213D3E-FECA-1BAD-9D20-8C374564ADCF}.Release|x64.ActiveCfg = Release|x64
+ {66213D3E-FECA-1BAD-9D20-8C374564ADCF}.Release|x64.Build.0 = Release|x64
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
diff --git a/qpid/cpp/src/qpid/Address.h b/qpid/cpp/src/qpid/Address.h
index 9669985165..a5a4345ba3 100755
--- a/qpid/cpp/src/qpid/Address.h
+++ b/qpid/cpp/src/qpid/Address.h
@@ -20,7 +20,7 @@
*/
#include "qpid/sys/IntegerTypes.h"
-
+#include "qpid/CommonImportExport.h"
#include <boost/variant.hpp>
#include <iosfwd>
#include <string>
@@ -31,12 +31,12 @@ namespace qpid {
/** TCP address of a broker - host:port */
struct TcpAddress {
static const uint16_t DEFAULT_PORT=5672;
- explicit TcpAddress(const std::string& host_=std::string(),uint16_t port_=DEFAULT_PORT);
+ QPID_COMMON_EXTERN explicit TcpAddress(const std::string& host_=std::string(),uint16_t port_=DEFAULT_PORT);
std::string host;
uint16_t port;
};
bool operator==(const TcpAddress& x, const TcpAddress& y);
-std::ostream& operator<<(std::ostream& os, const TcpAddress& a);
+QPID_COMMON_EXTERN std::ostream& operator<<(std::ostream& os, const TcpAddress& a);
/**@internal Not a real address type, this is a placeholder to
* demonstrate and validate multi-protocol Urls for unit tests and
diff --git a/qpid/cpp/src/qpid/CommonImportExport.h b/qpid/cpp/src/qpid/CommonImportExport.h
new file mode 100644
index 0000000000..47872646d9
--- /dev/null
+++ b/qpid/cpp/src/qpid/CommonImportExport.h
@@ -0,0 +1,33 @@
+#ifndef QPID_COMMON_IMPORT_EXPORT_H
+#define QPID_COMMON_IMPORT_EXPORT_H
+
+/*
+ * 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.
+ */
+
+#if defined(WIN32) && !defined(QPID_DECLARE_STATIC)
+#if defined(COMMON_EXPORT)
+#define QPID_COMMON_EXTERN __declspec(dllexport)
+#else
+#define QPID_COMMON_EXTERN __declspec(dllimport)
+#endif
+#else
+#define QPID_COMMON_EXTERN
+#endif
+
+#endif
diff --git a/qpid/cpp/src/qpid/DataDir.h b/qpid/cpp/src/qpid/DataDir.h
index 6b45d8747b..dfdd498cbc 100644
--- a/qpid/cpp/src/qpid/DataDir.h
+++ b/qpid/cpp/src/qpid/DataDir.h
@@ -24,6 +24,7 @@
#include <string>
#include <memory>
#include "qpid/sys/LockFile.h"
+#include "qpid/CommonImportExport.h"
namespace qpid {
@@ -38,8 +39,8 @@ class DataDir
public:
- DataDir (std::string path);
- ~DataDir ();
+ QPID_COMMON_EXTERN DataDir (std::string path);
+ QPID_COMMON_EXTERN ~DataDir ();
bool isEnabled() { return enabled; }
const std::string& getPath() { return dirPath; }
diff --git a/qpid/cpp/src/qpid/Exception.h b/qpid/cpp/src/qpid/Exception.h
index 86bf8fbc4a..0b0bc33e93 100644
--- a/qpid/cpp/src/qpid/Exception.h
+++ b/qpid/cpp/src/qpid/Exception.h
@@ -27,7 +27,7 @@
#include "qpid/framing/enum.h"
#include "qpid/sys/StrError.h"
#include "qpid/Msg.h"
-
+#include "qpid/CommonImportExport.h"
#include <memory>
#include <string>
#include <errno.h>
@@ -41,11 +41,11 @@ namespace qpid
class Exception : public std::exception
{
public:
- explicit Exception(const std::string& message=std::string()) throw();
- virtual ~Exception() throw();
- virtual const char* what() const throw(); // prefix: message
- virtual std::string getMessage() const; // Unprefixed message
- virtual std::string getPrefix() const; // Prefix
+ QPID_COMMON_EXTERN explicit Exception(const std::string& message=std::string()) throw();
+ QPID_COMMON_EXTERN virtual ~Exception() throw();
+ QPID_COMMON_EXTERN virtual const char* what() const throw(); // prefix: message
+ QPID_COMMON_EXTERN virtual std::string getMessage() const; // Unprefixed message
+ QPID_COMMON_EXTERN virtual std::string getPrefix() const; // Prefix
private:
std::string message;
@@ -77,8 +77,8 @@ struct ConnectionException : public Exception {
};
struct ClosedException : public Exception {
- ClosedException(const std::string& msg=std::string());
- std::string getPrefix() const;
+ QPID_COMMON_EXTERN ClosedException(const std::string& msg=std::string());
+ QPID_COMMON_EXTERN std::string getPrefix() const;
};
/**
diff --git a/qpid/cpp/src/qpid/Modules.h b/qpid/cpp/src/qpid/Modules.h
index 2a3b24f359..ce06dd0ef6 100644
--- a/qpid/cpp/src/qpid/Modules.h
+++ b/qpid/cpp/src/qpid/Modules.h
@@ -25,6 +25,7 @@
#include "Options.h"
#include <string>
#include <vector>
+#include "qpid/CommonImportExport.h"
namespace qpid {
@@ -32,11 +33,11 @@ struct ModuleOptions : public qpid::Options {
std::string loadDir;
std::vector<std::string> load;
bool noLoad;
- ModuleOptions(const std::string& defaultModuleDir);
+ QPID_COMMON_EXTERN ModuleOptions(const std::string& defaultModuleDir);
};
-void tryShlib(const char* libname, bool noThrow);
-void loadModuleDir (std::string dirname, bool isDefault);
+QPID_COMMON_EXTERN void tryShlib(const char* libname, bool noThrow);
+QPID_COMMON_EXTERN void loadModuleDir (std::string dirname, bool isDefault);
} // namespace qpid
diff --git a/qpid/cpp/src/qpid/Options.h b/qpid/cpp/src/qpid/Options.h
index cb86d27241..aeb7a79329 100644
--- a/qpid/cpp/src/qpid/Options.h
+++ b/qpid/cpp/src/qpid/Options.h
@@ -23,13 +23,25 @@
*/
#include "qpid/Exception.h"
+
+// Disable warnings triggered by boost.
+#ifdef _MSC_VER
+# pragma warning(push)
+# pragma warning(disable : 4251 4275)
+#endif
+
#include <boost/program_options.hpp>
#include <boost/format.hpp>
+
+#ifdef _MSC_VER
+# pragma warning(pop)
+#endif
+
#include <sstream>
#include <iterator>
#include <algorithm>
#include <string>
-
+#include "qpid/CommonImportExport.h"
namespace qpid {
namespace po=boost::program_options;
@@ -37,7 +49,7 @@ namespace po=boost::program_options;
///@internal
-std::string prettyArg(const std::string&, const std::string&);
+QPID_COMMON_EXTERN std::string prettyArg(const std::string&, const std::string&);
/** @internal Normally only constructed by optValue() */
template <class T>
@@ -192,24 +204,20 @@ options_description_less_easy_init
#endif
-
-
-
-
struct Options : public po::options_description {
struct Exception : public qpid::Exception {
Exception(const std::string& msg) : qpid::Exception(msg) {}
};
- Options(const std::string& name=std::string());
+ QPID_COMMON_EXTERN Options(const std::string& name=std::string());
/**
* Parses options from argc/argv, environment variables and config file.
* Note the filename argument can reference an options variable that
* is updated by argc/argv or environment variable parsing.
*/
- void parse(int argc, char const* const* argv,
+ QPID_COMMON_EXTERN void parse(int argc, char const* const* argv,
const std::string& configfile=std::string(),
bool allowUnknown = false);
@@ -242,7 +250,7 @@ struct Options : public po::options_description {
* Standard options for configuration
*/
struct CommonOptions : public Options {
- CommonOptions(const std::string& name=std::string(),
+ QPID_COMMON_EXTERN CommonOptions(const std::string& name=std::string(),
const std::string& configfile=std::string());
bool help;
bool version;
diff --git a/qpid/cpp/src/qpid/Plugin.h b/qpid/cpp/src/qpid/Plugin.h
index 50d8e01227..913152f9e1 100644
--- a/qpid/cpp/src/qpid/Plugin.h
+++ b/qpid/cpp/src/qpid/Plugin.h
@@ -24,6 +24,7 @@
#include <boost/noncopyable.hpp>
#include <boost/function.hpp>
#include <vector>
+#include "qpid/CommonImportExport.h"
/**@file Generic plug-in framework. */
@@ -46,10 +47,10 @@ class Plugin : private boost::noncopyable {
{
public:
/** Calls finalize() if not already called. */
- virtual ~Target();
+ QPID_COMMON_EXTERN virtual ~Target();
/** Run all the finalizers */
- void finalize();
+ QPID_COMMON_EXTERN void finalize();
/** Add a function to run when finalize() is called */
void addFinalizer(const boost::function<void()>&);
@@ -65,9 +66,9 @@ class Plugin : private boost::noncopyable {
* member variable in a library so it is registered during
* initialization when the library is loaded.
*/
- Plugin();
+ QPID_COMMON_EXTERN Plugin();
- virtual ~Plugin();
+ QPID_COMMON_EXTERN virtual ~Plugin();
/**
* Configuration options for the plugin.
@@ -76,7 +77,7 @@ class Plugin : private boost::noncopyable {
* @return An options group or 0 for no options. Default returns 0.
* Plugin retains ownership of return value.
*/
- virtual Options* getOptions();
+ QPID_COMMON_EXTERN virtual Options* getOptions();
/**
* Initialize Plugin functionality on a Target, called before
@@ -101,16 +102,16 @@ class Plugin : private boost::noncopyable {
/** List of registered Plugin objects.
* Caller must not delete plugin pointers.
*/
- static const Plugins& getPlugins();
+ QPID_COMMON_EXTERN static const Plugins& getPlugins();
/** Call earlyInitialize() on all registered plugins */
- static void earlyInitAll(Target&);
+ QPID_COMMON_EXTERN static void earlyInitAll(Target&);
/** Call initialize() on all registered plugins */
- static void initializeAll(Target&);
+ QPID_COMMON_EXTERN static void initializeAll(Target&);
/** For each registered plugin, add plugin.getOptions() to opts. */
- static void addOptions(Options& opts);
+ QPID_COMMON_EXTERN static void addOptions(Options& opts);
};
} // namespace qpid
diff --git a/qpid/cpp/src/qpid/SessionId.cpp b/qpid/cpp/src/qpid/SessionId.cpp
index fce6619f5d..098998015f 100644
--- a/qpid/cpp/src/qpid/SessionId.cpp
+++ b/qpid/cpp/src/qpid/SessionId.cpp
@@ -35,7 +35,7 @@ bool SessionId::operator==(const SessionId& id) const {
}
std::ostream& operator<<(std::ostream& o, const SessionId& id) {
- return o << id.getName() << "@" << id.getUserId();
+ return o << id.getUserId() << "." << id.getName();
}
std::string SessionId::str() const {
diff --git a/qpid/cpp/src/qpid/SessionId.h b/qpid/cpp/src/qpid/SessionId.h
index 291c42a2bb..bf52f9856b 100644
--- a/qpid/cpp/src/qpid/SessionId.h
+++ b/qpid/cpp/src/qpid/SessionId.h
@@ -24,6 +24,7 @@
#include <boost/operators.hpp>
#include <string>
+#include <qpid/CommonImportExport.h>
namespace qpid {
@@ -42,16 +43,16 @@ class SessionId : boost::totally_ordered1<SessionId> {
std::string userId;
std::string name;
public:
- SessionId(const std::string& userId=std::string(), const std::string& name=std::string());
+ QPID_COMMON_EXTERN SessionId(const std::string& userId=std::string(), const std::string& name=std::string());
std::string getUserId() const { return userId; }
std::string getName() const { return name; }
- bool operator<(const SessionId&) const ;
- bool operator==(const SessionId& id) const;
+ QPID_COMMON_EXTERN bool operator<(const SessionId&) const ;
+ QPID_COMMON_EXTERN bool operator==(const SessionId& id) const;
// Convert to a string
- std::string str() const;
+ QPID_COMMON_EXTERN std::string str() const;
};
-std::ostream& operator<<(std::ostream&, const SessionId&);
+QPID_COMMON_EXTERN std::ostream& operator<<(std::ostream&, const SessionId&);
} // namespace qpid
diff --git a/qpid/cpp/src/qpid/SessionState.cpp b/qpid/cpp/src/qpid/SessionState.cpp
index ac75b5c5ff..3e844fb24b 100644
--- a/qpid/cpp/src/qpid/SessionState.cpp
+++ b/qpid/cpp/src/qpid/SessionState.cpp
@@ -113,7 +113,8 @@ SessionState::ReplayRange SessionState::senderExpected(const SessionPoint& expec
void SessionState::senderRecord(const AMQFrame& f) {
if (isControl(f)) return; // Ignore control frames.
- QPID_LOG_IF(debug, f.getMethod(), getId() << ": sent cmd " << sender.sendPoint.command << ": " << *f.getMethod());
+ QPID_LOG(trace, getId() << ": sent cmd " << sender.sendPoint.command << ": " << *f.getBody());
+
stateful = true;
if (timeout) sender.replayList.push_back(f);
sender.unflushedSize += f.encodedSize();
@@ -183,6 +184,7 @@ void SessionState::receiverSetCommandPoint(const SessionPoint& point) {
}
bool SessionState::receiverRecord(const AMQFrame& f) {
+ if (receiverTrackingDisabled) return true; //Very nasty hack for push bridges
if (isControl(f)) return true; // Ignore control frames.
stateful = true;
receiver.expected.advance(f);
@@ -192,12 +194,13 @@ bool SessionState::receiverRecord(const AMQFrame& f) {
receiver.received = receiver.expected;
receiver.incomplete += receiverGetCurrent();
}
- QPID_LOG_IF(debug, f.getMethod(), getId() << ": recv cmd " << receiverGetCurrent() << ": " << *f.getMethod());
- QPID_LOG_IF(debug, !firstTime, "Ignoring duplicate frame: " << receiverGetCurrent() << ": " << f);
+ QPID_LOG(trace, getId() << ": recv cmd " << receiverGetCurrent() << ": " << *f.getBody());
+ if (!firstTime) QPID_LOG(trace, "Ignoring duplicate frame.");
return firstTime;
}
void SessionState::receiverCompleted(SequenceNumber command, bool cumulative) {
+ if (receiverTrackingDisabled) return; //Very nasty hack for push bridges
assert(receiver.incomplete.contains(command)); // Internal error to complete command twice.
SequenceNumber first =cumulative ? receiver.incomplete.front() : command;
SequenceNumber last = command;
@@ -237,7 +240,7 @@ SessionState::Configuration::Configuration(size_t flush, size_t hard) :
replayFlushLimit(flush), replayHardLimit(hard) {}
SessionState::SessionState(const SessionId& i, const Configuration& c)
- : id(i), timeout(), config(c), stateful()
+ : id(i), timeout(), config(c), stateful(), receiverTrackingDisabled(false)
{
QPID_LOG(debug, "SessionState::SessionState " << id << ": " << this);
}
@@ -275,4 +278,7 @@ void SessionState::setState(
receiver.bytesSinceKnownCompleted = 0;
}
+void SessionState::disableReceiverTracking() { receiverTrackingDisabled = true; }
+void SessionState::enableReceiverTracking() { receiverTrackingDisabled = false; }
+
} // namespace qpid
diff --git a/qpid/cpp/src/qpid/SessionState.h b/qpid/cpp/src/qpid/SessionState.h
index bf4ff6d326..da28738546 100644
--- a/qpid/cpp/src/qpid/SessionState.h
+++ b/qpid/cpp/src/qpid/SessionState.h
@@ -31,6 +31,7 @@
#include <boost/range/iterator_range.hpp>
#include <vector>
#include <iosfwd>
+#include <qpid/CommonImportExport.h>
namespace qpid {
using framing::SequenceNumber;
@@ -38,19 +39,19 @@ using framing::SequenceSet;
/** A point in the session. Points to command id + offset */
struct SessionPoint : boost::totally_ordered1<SessionPoint> {
- SessionPoint(SequenceNumber command = 0, uint64_t offset = 0);
+ QPID_COMMON_EXTERN SessionPoint(SequenceNumber command = 0, uint64_t offset = 0);
SequenceNumber command;
uint64_t offset;
/** Advance past frame f */
- void advance(const framing::AMQFrame& f);
+ QPID_COMMON_EXTERN void advance(const framing::AMQFrame& f);
- bool operator<(const SessionPoint&) const;
- bool operator==(const SessionPoint&) const;
+ QPID_COMMON_EXTERN bool operator<(const SessionPoint&) const;
+ QPID_COMMON_EXTERN bool operator==(const SessionPoint&) const;
};
-std::ostream& operator<<(std::ostream&, const SessionPoint&);
+QPID_COMMON_EXTERN std::ostream& operator<<(std::ostream&, const SessionPoint&);
/**
* Support for session idempotence barrier and resume as defined in
@@ -78,14 +79,14 @@ class SessionState {
typedef boost::iterator_range<ReplayList::iterator> ReplayRange;
struct Configuration {
- Configuration(size_t flush=1024*1024, size_t hard=0);
+ QPID_COMMON_EXTERN Configuration(size_t flush=1024*1024, size_t hard=0);
size_t replayFlushLimit; // Flush when the replay list >= N bytes. 0 disables.
size_t replayHardLimit; // Kill session if replay list > N bytes. 0 disables.
};
- SessionState(const SessionId& =SessionId(), const Configuration& =Configuration());
+ QPID_COMMON_EXTERN SessionState(const SessionId& =SessionId(), const Configuration& =Configuration());
- virtual ~SessionState();
+ QPID_COMMON_EXTERN virtual ~SessionState();
bool hasState() const;
@@ -100,78 +101,78 @@ class SessionState {
// ==== Functions for sender state.
/** Record frame f for replay. Should not be called during replay. */
- virtual void senderRecord(const framing::AMQFrame& f);
+ QPID_COMMON_EXTERN virtual void senderRecord(const framing::AMQFrame& f);
/** @return true if we should send flush for confirmed and completed commands. */
- virtual bool senderNeedFlush() const;
+ QPID_COMMON_EXTERN virtual bool senderNeedFlush() const;
/** Called when flush for confirmed and completed commands is sent to peer. */
- virtual void senderRecordFlush();
+ QPID_COMMON_EXTERN virtual void senderRecordFlush();
/** True if we should reply to the next incoming completed command */
- virtual bool senderNeedKnownCompleted() const;
+ QPID_COMMON_EXTERN virtual bool senderNeedKnownCompleted() const;
/** Called when knownCompleted is sent to peer. */
- virtual void senderRecordKnownCompleted();
+ QPID_COMMON_EXTERN virtual void senderRecordKnownCompleted();
/** Called when the peer confirms up to comfirmed. */
- virtual void senderConfirmed(const SessionPoint& confirmed);
+ QPID_COMMON_EXTERN virtual void senderConfirmed(const SessionPoint& confirmed);
/** Called when the peer indicates commands completed */
- virtual void senderCompleted(const SequenceSet& commands);
+ QPID_COMMON_EXTERN virtual void senderCompleted(const SequenceSet& commands);
/** Point from which the next new (not replayed) data will be sent. */
- virtual SessionPoint senderGetCommandPoint();
+ QPID_COMMON_EXTERN virtual SessionPoint senderGetCommandPoint();
/** Set of outstanding incomplete commands */
- virtual SequenceSet senderGetIncomplete() const;
+ QPID_COMMON_EXTERN virtual SequenceSet senderGetIncomplete() const;
/** Point from which we can replay. */
- virtual SessionPoint senderGetReplayPoint() const;
+ QPID_COMMON_EXTERN virtual SessionPoint senderGetReplayPoint() const;
/** Peer expecting commands from this point.
*@return Range of frames to be replayed.
*/
- virtual ReplayRange senderExpected(const SessionPoint& expected);
+ QPID_COMMON_EXTERN virtual ReplayRange senderExpected(const SessionPoint& expected);
// ==== Functions for receiver state
/** Set the command point. */
- virtual void receiverSetCommandPoint(const SessionPoint& point);
+ QPID_COMMON_EXTERN virtual void receiverSetCommandPoint(const SessionPoint& point);
/** Returns true if frame should be be processed, false if it is a duplicate. */
- virtual bool receiverRecord(const framing::AMQFrame& f);
+ QPID_COMMON_EXTERN virtual bool receiverRecord(const framing::AMQFrame& f);
/** Command completed locally */
- virtual void receiverCompleted(SequenceNumber command, bool cumulative=false);
+ QPID_COMMON_EXTERN virtual void receiverCompleted(SequenceNumber command, bool cumulative=false);
/** Peer has indicated commands are known completed */
- virtual void receiverKnownCompleted(const SequenceSet& commands);
+ QPID_COMMON_EXTERN virtual void receiverKnownCompleted(const SequenceSet& commands);
/** True if the next completed control should set the timely-reply argument
* to request a knonw-completed response.
*/
- virtual bool receiverNeedKnownCompleted() const;
+ QPID_COMMON_EXTERN virtual bool receiverNeedKnownCompleted() const;
/** Get the incoming command point */
- virtual const SessionPoint& receiverGetExpected() const;
+ QPID_COMMON_EXTERN virtual const SessionPoint& receiverGetExpected() const;
/** Get the received high-water-mark, may be > getExpected() during replay */
- virtual const SessionPoint& receiverGetReceived() const;
+ QPID_COMMON_EXTERN virtual const SessionPoint& receiverGetReceived() const;
/** Completed received commands that the peer may not know about. */
- virtual const SequenceSet& receiverGetUnknownComplete() const;
+ QPID_COMMON_EXTERN virtual const SequenceSet& receiverGetUnknownComplete() const;
/** Incomplete received commands. */
- virtual const SequenceSet& receiverGetIncomplete() const;
+ QPID_COMMON_EXTERN virtual const SequenceSet& receiverGetIncomplete() const;
/** ID of the command currently being handled. */
- virtual SequenceNumber receiverGetCurrent() const;
+ QPID_COMMON_EXTERN virtual SequenceNumber receiverGetCurrent() const;
/** Set the state variables, used to create a session that will resume
* from some previously established point.
*/
- virtual void setState(
+ QPID_COMMON_EXTERN virtual void setState(
const SequenceNumber& replayStart,
const SequenceNumber& sendCommandPoint,
const SequenceSet& sentIncomplete,
@@ -181,6 +182,20 @@ class SessionState {
const SequenceSet& receivedIncomplete
);
+ /**
+ * So called 'push' bridges work by faking a subscribe request
+ * (and the accompanying flows etc) to the local broker to initiate
+ * the outflow of messages for the bridge.
+ *
+ * As the peer doesn't send these it cannot include them in its
+ * session state. To keep the session state on either side of the
+ * bridge in sync, this hack allows the tracking of state for
+ * received messages to be disabled for the faked commands and
+ * subsequently re-enabled.
+ */
+ QPID_COMMON_EXTERN void disableReceiverTracking();
+ QPID_COMMON_EXTERN void enableReceiverTracking();
+
private:
struct SendState {
@@ -209,6 +224,7 @@ class SessionState {
uint32_t timeout;
Configuration config;
bool stateful;
+ bool receiverTrackingDisabled;//very nasty hack for 'push' bridges
};
inline bool operator==(const SessionId& id, const SessionState& s) { return s == id; }
diff --git a/qpid/cpp/src/qpid/StringUtils.h b/qpid/cpp/src/qpid/StringUtils.h
index 3120e43334..4130fae017 100644
--- a/qpid/cpp/src/qpid/StringUtils.h
+++ b/qpid/cpp/src/qpid/StringUtils.h
@@ -22,6 +22,8 @@
*
*/
+#include "qpid/CommonImportExport.h"
+
#include <string>
#include <vector>
@@ -31,12 +33,12 @@ namespace qpid {
* Split 'in' into words using delimiters in 'delims' and put
* resulting strings into 'out' vector.
*/
-void split(std::vector<std::string>& out, const std::string& in, const std::string& delims);
+QPID_COMMON_EXTERN void split(std::vector<std::string>& out, const std::string& in, const std::string& delims);
/**
* Split 'in' into words using delimiters in 'delims' and return the
* resulting strings in a vector.
*/
-std::vector<std::string> split(const std::string& in, const std::string& delims);
+QPID_COMMON_EXTERN std::vector<std::string> split(const std::string& in, const std::string& delims);
} // namespace qpid
diff --git a/qpid/cpp/src/qpid/Url.h b/qpid/cpp/src/qpid/Url.h
index 07ca46e70c..353eac28f3 100644
--- a/qpid/cpp/src/qpid/Url.h
+++ b/qpid/cpp/src/qpid/Url.h
@@ -25,10 +25,11 @@
#include <vector>
#include <new>
#include <ostream>
+#include "qpid/CommonImportExport.h"
namespace qpid {
-std::ostream& operator<<(std::ostream& os, const TcpAddress& a);
+QPID_COMMON_EXTERN std::ostream& operator<<(std::ostream& os, const TcpAddress& a);
/** An AMQP URL contains a list of addresses */
struct Url : public std::vector<Address> {
@@ -38,12 +39,12 @@ struct Url : public std::vector<Address> {
/** Url with local IP address(es), may be more than one address
* on a multi-homed host. */
- static Url getIpAddressesUrl(uint16_t port);
+ QPID_COMMON_EXTERN static Url getIpAddressesUrl(uint16_t port);
struct Invalid : public Exception { Invalid(const std::string& s); };
/** Convert to string form. */
- std::string str() const;
+ QPID_COMMON_EXTERN std::string str() const;
/** Empty URL. */
Url() {}
@@ -62,14 +63,14 @@ struct Url : public std::vector<Address> {
Url& operator=(const std::string& s) { parse(s); return *this; }
/** Throw Invalid if the URL does not contain any addresses. */
- void throwIfEmpty() const;
+ QPID_COMMON_EXTERN void throwIfEmpty() const;
/** Replace contents with parsed URL as defined in
* https://wiki.108.redhat.com/jira/browse/AMQP-95
*@exception Invalid if the url is invalid.
*/
- void parse(const char* url);
- void parse(const std::string& url) { parse(url.c_str()); }
+ QPID_COMMON_EXTERN void parse(const char* url);
+ QPID_COMMON_EXTERN void parse(const std::string& url) { parse(url.c_str()); }
/** Replace contesnts with parsed URL as defined in
* https://wiki.108.redhat.com/jira/browse/AMQP-95
@@ -84,8 +85,8 @@ struct Url : public std::vector<Address> {
inline bool operator==(const Url& a, const Url& b) { return a.str()==b.str(); }
inline bool operator!=(const Url& a, const Url& b) { return a.str()!=b.str(); }
-std::ostream& operator<<(std::ostream& os, const Url& url);
-std::istream& operator>>(std::istream& is, Url& url);
+QPID_COMMON_EXTERN std::ostream& operator<<(std::ostream& os, const Url& url);
+QPID_COMMON_EXTERN std::istream& operator>>(std::istream& is, Url& url);
} // namespace qpid
diff --git a/qpid/cpp/src/qpid/Version.h b/qpid/cpp/src/qpid/Version.h
index 9bd561b7a9..ab7957e000 100755
--- a/qpid/cpp/src/qpid/Version.h
+++ b/qpid/cpp/src/qpid/Version.h
@@ -36,7 +36,7 @@ namespace qpid {
# endif
#else
const std::string product = "qpidc";
- const std::string version = "0.3";
+ const std::string version = "0.5";
const std::string saslName = "qpid-broker";
#endif
}
diff --git a/qpid/cpp/src/qpid/acl/AclPlugin.cpp b/qpid/cpp/src/qpid/acl/AclPlugin.cpp
index 7310139041..4c6efa19dd 100644
--- a/qpid/cpp/src/qpid/acl/AclPlugin.cpp
+++ b/qpid/cpp/src/qpid/acl/AclPlugin.cpp
@@ -62,15 +62,10 @@ struct AclPlugin : public Plugin {
if (acl) throw Exception("ACL plugin cannot be initialized twice in one process.");
- if (values.aclFile.at(0) == '/')
- {
- values.aclFile = values.aclFile;
- }
- else
- {
- std::ostringstream oss;
- oss << b.getDataDir().getPath() << "/" << values.aclFile;
- values.aclFile = oss.str();
+ if (values.aclFile.at(0) != '/' && !b.getDataDir().getPath().empty()) {
+ std::ostringstream oss;
+ oss << b.getDataDir().getPath() << "/" << values.aclFile;
+ values.aclFile = oss.str();
}
acl = new Acl(values, b);
diff --git a/qpid/cpp/src/qpid/agent/ManagementAgentImpl.cpp b/qpid/cpp/src/qpid/agent/ManagementAgentImpl.cpp
index 1e2f4cdd78..7c70c12213 100644
--- a/qpid/cpp/src/qpid/agent/ManagementAgentImpl.cpp
+++ b/qpid/cpp/src/qpid/agent/ManagementAgentImpl.cpp
@@ -151,7 +151,7 @@ void ManagementAgentImpl::init(const client::ConnectionSettings& settings,
// TODO: Abstract the socket calls for portability
if (extThread) {
int pair[2];
- int result = socketpair(PF_LOCAL, SOCK_STREAM, 0, pair);
+ int result = socketpair(PF_UNIX, SOCK_STREAM, 0, pair);
if (result == -1) {
return;
}
@@ -485,6 +485,9 @@ void ManagementAgentImpl::handleGetQuery(Buffer& inBuffer, uint32_t sequence, st
Buffer outBuffer (outputBuffer, MA_BUFFER_SIZE);
uint32_t outLen;
+ if (object->getConfigChanged() || object->getInstChanged())
+ object->setUpdateTime();
+
encodeHeader(outBuffer, 'g', sequence);
object->writeProperties(outBuffer);
object->writeStatistics(outBuffer, true);
@@ -508,6 +511,9 @@ void ManagementAgentImpl::handleGetQuery(Buffer& inBuffer, uint32_t sequence, st
Buffer outBuffer(outputBuffer, MA_BUFFER_SIZE);
uint32_t outLen;
+ if (object->getConfigChanged() || object->getInstChanged())
+ object->setUpdateTime();
+
encodeHeader(outBuffer, 'g', sequence);
object->writeProperties(outBuffer);
object->writeStatistics(outBuffer, true);
diff --git a/qpid/cpp/src/qpid/amqp_0_10/Connection.h b/qpid/cpp/src/qpid/amqp_0_10/Connection.h
index 743a7de3aa..3e0a5d1ee8 100644
--- a/qpid/cpp/src/qpid/amqp_0_10/Connection.h
+++ b/qpid/cpp/src/qpid/amqp_0_10/Connection.h
@@ -27,6 +27,7 @@
#include "qpid/sys/ConnectionInputHandler.h"
#include "qpid/sys/ConnectionOutputHandler.h"
#include "qpid/sys/Mutex.h"
+#include "qpid/broker/BrokerImportExport.h"
#include <boost/intrusive_ptr.hpp>
#include <memory>
#include <deque>
@@ -56,8 +57,8 @@ class Connection : public sys::ConnectionCodec,
size_t buffered;
public:
- Connection(sys::OutputControl&, const std::string& id, bool isClient);
- void setInputHandler(std::auto_ptr<sys::ConnectionInputHandler> c);
+ QPID_BROKER_EXTERN Connection(sys::OutputControl&, const std::string& id, bool isClient);
+ QPID_BROKER_EXTERN void setInputHandler(std::auto_ptr<sys::ConnectionInputHandler> c);
size_t decode(const char* buffer, size_t size);
size_t encode(const char* buffer, size_t size);
bool isClosed() const;
diff --git a/qpid/cpp/src/qpid/amqp_0_10/SessionHandler.cpp b/qpid/cpp/src/qpid/amqp_0_10/SessionHandler.cpp
index f58d59cbd7..db957051d8 100644
--- a/qpid/cpp/src/qpid/amqp_0_10/SessionHandler.cpp
+++ b/qpid/cpp/src/qpid/amqp_0_10/SessionHandler.cpp
@@ -277,7 +277,6 @@ void SessionHandler::sendCompletion() {
}
void SessionHandler::sendAttach(bool force) {
- CHECK_ATTACHED("session.send-attach");
QPID_LOG(debug, "SessionHandler::sendAttach attach id=" << getState()->getId());
peer.attach(getState()->getId().getName(), force);
if (getState()->hasState())
diff --git a/qpid/cpp/src/qpid/amqp_0_10/SessionHandler.h b/qpid/cpp/src/qpid/amqp_0_10/SessionHandler.h
index d7af7dd6c7..0b158ec2b4 100644
--- a/qpid/cpp/src/qpid/amqp_0_10/SessionHandler.h
+++ b/qpid/cpp/src/qpid/amqp_0_10/SessionHandler.h
@@ -26,6 +26,7 @@
#include "qpid/framing/AMQP_AllProxy.h"
#include "qpid/framing/AMQP_AllOperations.h"
#include "qpid/SessionState.h"
+#include "qpid/CommonImportExport.h"
namespace qpid {
@@ -43,8 +44,8 @@ class SessionHandler : public framing::AMQP_AllOperations::SessionHandler,
public framing::FrameHandler::InOutHandler
{
public:
- SessionHandler(framing::FrameHandler* out=0, uint16_t channel=0);
- ~SessionHandler();
+ QPID_COMMON_EXTERN SessionHandler(framing::FrameHandler* out=0, uint16_t channel=0);
+ QPID_COMMON_EXTERN ~SessionHandler();
void setChannel(uint16_t ch) { channel = ch; }
uint16_t getChannel() const { return channel.get(); }
@@ -55,35 +56,35 @@ class SessionHandler : public framing::AMQP_AllOperations::SessionHandler,
virtual framing::FrameHandler* getInHandler() = 0;
// Non-protocol methods, called locally to initiate some action.
- void sendDetach();
- void sendCompletion();
- void sendAttach(bool force);
- void sendTimeout(uint32_t t);
- void sendFlush();
- void markReadyToSend();//TODO: only needed for inter-broker bridge; cleanup
+ QPID_COMMON_EXTERN void sendDetach();
+ QPID_COMMON_EXTERN void sendCompletion();
+ QPID_COMMON_EXTERN void sendAttach(bool force);
+ QPID_COMMON_EXTERN void sendTimeout(uint32_t t);
+ QPID_COMMON_EXTERN void sendFlush();
+ QPID_COMMON_EXTERN void markReadyToSend();//TODO: only needed for inter-broker bridge; cleanup
/** True if the handler is ready to send and receive */
bool ready() const;
// Protocol methods
- void attach(const std::string& name, bool force);
- void attached(const std::string& name);
- void detach(const std::string& name);
- void detached(const std::string& name, uint8_t code);
-
- void requestTimeout(uint32_t t);
- void timeout(uint32_t t);
-
- void commandPoint(const framing::SequenceNumber& id, uint64_t offset);
- void expected(const framing::SequenceSet& commands, const framing::Array& fragments);
- void confirmed(const framing::SequenceSet& commands,const framing::Array& fragments);
- void completed(const framing::SequenceSet& commands, bool timelyReply);
- void knownCompleted(const framing::SequenceSet& commands);
- void flush(bool expected, bool confirmed, bool completed);
- void gap(const framing::SequenceSet& commands);
+ QPID_COMMON_EXTERN void attach(const std::string& name, bool force);
+ QPID_COMMON_EXTERN void attached(const std::string& name);
+ QPID_COMMON_EXTERN void detach(const std::string& name);
+ QPID_COMMON_EXTERN void detached(const std::string& name, uint8_t code);
+
+ QPID_COMMON_EXTERN void requestTimeout(uint32_t t);
+ QPID_COMMON_EXTERN void timeout(uint32_t t);
+
+ QPID_COMMON_EXTERN void commandPoint(const framing::SequenceNumber& id, uint64_t offset);
+ QPID_COMMON_EXTERN void expected(const framing::SequenceSet& commands, const framing::Array& fragments);
+ QPID_COMMON_EXTERN void confirmed(const framing::SequenceSet& commands,const framing::Array& fragments);
+ QPID_COMMON_EXTERN void completed(const framing::SequenceSet& commands, bool timelyReply);
+ QPID_COMMON_EXTERN void knownCompleted(const framing::SequenceSet& commands);
+ QPID_COMMON_EXTERN void flush(bool expected, bool confirmed, bool completed);
+ QPID_COMMON_EXTERN void gap(const framing::SequenceSet& commands);
protected:
- virtual void invoke(const framing::AMQMethodBody& m);
+ QPID_COMMON_EXTERN virtual void invoke(const framing::AMQMethodBody& m);
virtual void setState(const std::string& sessionName, bool force) = 0;
virtual void channelException(framing::session::DetachCode code, const std::string& msg) = 0;
@@ -94,9 +95,9 @@ class SessionHandler : public framing::AMQP_AllOperations::SessionHandler,
virtual void readyToSend() {}
virtual void readyToReceive() {}
- virtual void handleDetach();
- virtual void handleIn(framing::AMQFrame&);
- virtual void handleOut(framing::AMQFrame&);
+ QPID_COMMON_EXTERN virtual void handleDetach();
+ QPID_COMMON_EXTERN virtual void handleIn(framing::AMQFrame&);
+ QPID_COMMON_EXTERN virtual void handleOut(framing::AMQFrame&);
framing::ChannelHandler channel;
framing::AMQP_AllProxy::Session peer;
diff --git a/qpid/cpp/src/qpid/assert.cpp b/qpid/cpp/src/qpid/assert.cpp
index 5d039da528..bf36d3be86 100644
--- a/qpid/cpp/src/qpid/assert.cpp
+++ b/qpid/cpp/src/qpid/assert.cpp
@@ -35,7 +35,7 @@ void assert_fail(char const * expr, char const * function, char const * file, lo
#ifdef NDEBUG
throw framing::InternalErrorException(msg.str());
#else
- std::cerr << msg << std::endl;
+ std::cerr << msg.str() << std::endl;
abort();
#endif
}
diff --git a/qpid/cpp/src/qpid/broker/Bridge.cpp b/qpid/cpp/src/qpid/broker/Bridge.cpp
index 38a9b5d64c..4d275b958f 100644
--- a/qpid/cpp/src/qpid/broker/Bridge.cpp
+++ b/qpid/cpp/src/qpid/broker/Bridge.cpp
@@ -22,6 +22,7 @@
#include "ConnectionState.h"
#include "Connection.h"
#include "LinkRegistry.h"
+#include "SessionState.h"
#include "qpid/agent/ManagementAgent.h"
#include "qpid/framing/FieldTable.h"
@@ -80,31 +81,31 @@ Bridge::~Bridge()
mgmtObject->resourceDestroy();
}
-void Bridge::create(ConnectionState& c)
+void Bridge::create(Connection& c)
{
+ connState = &c;
FieldTable options;
if (args.i_sync) options.setInt("qpid.sync_frequency", args.i_sync);
- connState = &c;
+ SessionHandler& sessionHandler = c.getChannel(id);
if (args.i_srcIsLocal) {
if (args.i_dynamic)
throw Exception("Dynamic routing not supported for push routes");
// Point the bridging commands at the local connection handler
- Connection* conn = dynamic_cast<Connection*>(&c);
- if (conn == 0)
- return;
- pushHandler.reset(new PushHandler(conn));
+ pushHandler.reset(new PushHandler(&c));
channelHandler.reset(new framing::ChannelHandler(id, pushHandler.get()));
+
+ session.reset(new framing::AMQP_ServerProxy::Session(*channelHandler));
+ peer.reset(new framing::AMQP_ServerProxy(*channelHandler));
+
+ session->attach(name, false);
+ session->commandPoint(0,0);
} else {
+ sessionHandler.attachAs(name);
// Point the bridging commands at the remote peer broker
- channelHandler.reset(new framing::ChannelHandler(id, &(connState->getOutput())));
+ peer.reset(new framing::AMQP_ServerProxy(sessionHandler.out));
}
- session.reset(new framing::AMQP_ServerProxy::Session(*channelHandler));
- peer.reset(new framing::AMQP_ServerProxy(*channelHandler));
-
- session->attach(name, false);
- session->commandPoint(0,0);
-
+ if (args.i_srcIsLocal) sessionHandler.getSession()->disableReceiverTracking();
if (args.i_srcIsQueue) {
peer->getMessage().subscribe(args.i_src, args.i_dest, args.i_sync ? 0 : 1, 0, false, "", 0, options);
peer->getMessage().flow(args.i_dest, 0, 0xFFFFFFFF);
@@ -116,7 +117,7 @@ void Bridge::create(ConnectionState& c)
if (args.i_tag.size()) {
queueSettings.setString("qpid.trace.id", args.i_tag);
} else {
- const string& peerTag = connState->getFederationPeerTag();
+ const string& peerTag = c.getFederationPeerTag();
if (peerTag.size())
queueSettings.setString("qpid.trace.id", peerTag);
}
@@ -129,7 +130,7 @@ void Bridge::create(ConnectionState& c)
queueSettings.setString("qpid.trace.exclude", localTag);
}
- bool durable = false;//should this be an arg, or would be use srcIsQueue for durable queues?
+ bool durable = false;//should this be an arg, or would we use srcIsQueue for durable queues?
bool autoDelete = !durable;//auto delete transient queues?
peer->getQueue().declare(queueName, "", false, durable, true, autoDelete, queueSettings);
if (!args.i_dynamic)
@@ -148,12 +149,23 @@ void Bridge::create(ConnectionState& c)
QPID_LOG(debug, "Activated static route from exchange " << args.i_src << " to " << args.i_dest);
}
}
+ if (args.i_srcIsLocal) sessionHandler.getSession()->enableReceiverTracking();
}
-void Bridge::cancel()
+void Bridge::cancel(Connection& c)
{
+ if (args.i_srcIsLocal) {
+ //recreate peer to be sure that the session handler reference
+ //is valid (it could have been deleted due to a detach)
+ SessionHandler& sessionHandler = c.getChannel(id);
+ peer.reset(new framing::AMQP_ServerProxy(sessionHandler.out));
+ }
peer->getMessage().cancel(args.i_dest);
peer->getSession().detach(name);
+}
+
+void Bridge::closed()
+{
if (args.i_dynamic) {
Exchange::shared_ptr exchange = link->getBroker()->getExchanges().get(args.i_src);
if (exchange.get() != 0)
@@ -166,13 +178,13 @@ void Bridge::destroy()
listener(this);
}
-void Bridge::setPersistenceId(uint64_t id) const
+void Bridge::setPersistenceId(uint64_t pId) const
{
if (mgmtObject != 0 && persistenceId == 0) {
ManagementAgent* agent = ManagementAgent::Singleton::getInstance();
- agent->addObject (mgmtObject, id);
+ agent->addObject (mgmtObject, pId);
}
- persistenceId = id;
+ persistenceId = pId;
}
const string& Bridge::getName() const
diff --git a/qpid/cpp/src/qpid/broker/Bridge.h b/qpid/cpp/src/qpid/broker/Bridge.h
index c530a5d696..dae28ddeaa 100644
--- a/qpid/cpp/src/qpid/broker/Bridge.h
+++ b/qpid/cpp/src/qpid/broker/Bridge.h
@@ -52,8 +52,9 @@ public:
const qmf::org::apache::qpid::broker::ArgsLinkBridge& args);
~Bridge();
- void create(ConnectionState& c);
- void cancel();
+ void create(Connection& c);
+ void cancel(Connection& c);
+ void closed();
void destroy();
bool isDurable() { return args.i_durable; }
diff --git a/qpid/cpp/src/qpid/broker/Broker.cpp b/qpid/cpp/src/qpid/broker/Broker.cpp
index 95f55bb596..3f9effc08f 100644
--- a/qpid/cpp/src/qpid/broker/Broker.cpp
+++ b/qpid/cpp/src/qpid/broker/Broker.cpp
@@ -199,6 +199,7 @@ Broker::Broker(const Broker::Options& conf) :
}
QueuePolicy::setDefaultMaxSize(conf.queueLimit);
+ queues.setQueueEvents(&queueEvents);
// Early-Initialize plugins
const Plugin::Plugins& plugins=Plugin::getPlugins();
@@ -383,9 +384,9 @@ Manageable::status_t Broker::ManagementMethod (uint32_t methodId,
_qmf::ArgsBrokerQueueMoveMessages& moveArgs=
dynamic_cast<_qmf::ArgsBrokerQueueMoveMessages&>(args);
if (queueMoveMessages(moveArgs.i_srcQueue, moveArgs.i_destQueue, moveArgs.i_qty))
- status = Manageable::STATUS_OK;
+ status = Manageable::STATUS_OK;
else
- return Manageable::STATUS_INVALID_PARAMETER;
+ return Manageable::STATUS_INVALID_PARAMETER;
break;
}
default:
diff --git a/qpid/cpp/src/qpid/broker/Broker.h b/qpid/cpp/src/qpid/broker/Broker.h
index a52a0f67e0..5a1529a3ba 100644
--- a/qpid/cpp/src/qpid/broker/Broker.h
+++ b/qpid/cpp/src/qpid/broker/Broker.h
@@ -22,6 +22,7 @@
*
*/
+#include "BrokerImportExport.h"
#include "ConnectionFactory.h"
#include "ConnectionToken.h"
#include "DirectExchange.h"
@@ -80,15 +81,16 @@ struct NoSuchTransportException : qpid::Exception
* A broker instance.
*/
class Broker : public sys::Runnable, public Plugin::Target,
- public management::Manageable, public RefCounted
+ public management::Manageable,
+ public RefCounted
{
- public:
+public:
struct Options : public qpid::Options {
static const std::string DEFAULT_DATA_DIR_LOCATION;
static const std::string DEFAULT_DATA_DIR_NAME;
- Options(const std::string& name="Broker Options");
+ QPID_BROKER_EXTERN Options(const std::string& name="Broker Options");
bool noDataDir;
std::string dataDir;
@@ -148,9 +150,9 @@ class Broker : public sys::Runnable, public Plugin::Target,
virtual ~Broker();
- Broker(const Options& configuration);
- static boost::intrusive_ptr<Broker> create(const Options& configuration);
- static boost::intrusive_ptr<Broker> create(int16_t port = DEFAULT_PORT);
+ QPID_BROKER_EXTERN Broker(const Options& configuration);
+ static QPID_BROKER_EXTERN boost::intrusive_ptr<Broker> create(const Options& configuration);
+ static QPID_BROKER_EXTERN boost::intrusive_ptr<Broker> create(int16_t port = DEFAULT_PORT);
/**
* Return listening port. If called before bind this is
@@ -169,7 +171,7 @@ class Broker : public sys::Runnable, public Plugin::Target,
/** Shut down the broker */
virtual void shutdown();
- void setStore (MessageStore*);
+ QPID_BROKER_EXTERN void setStore (MessageStore*);
MessageStore& getStore() { return *store; }
void setAcl (AclModule* _acl) {acl = _acl;}
AclModule* getAcl() { return acl; }
@@ -229,7 +231,7 @@ class Broker : public sys::Runnable, public Plugin::Target,
boost::function<std::vector<Url> ()> getKnownBrokers;
- static const std::string TCP_TRANSPORT;
+ static QPID_BROKER_EXTERN const std::string TCP_TRANSPORT;
void setRecovery(bool set) { recovery = set; }
bool getRecovery() const { return recovery; }
diff --git a/qpid/cpp/src/qpid/broker/BrokerImportExport.h b/qpid/cpp/src/qpid/broker/BrokerImportExport.h
new file mode 100644
index 0000000000..2edc90993e
--- /dev/null
+++ b/qpid/cpp/src/qpid/broker/BrokerImportExport.h
@@ -0,0 +1,33 @@
+#ifndef QPID_BROKER_IMPORT_EXPORT_H
+#define QPID_BROKER_IMPORT_EXPORT_H
+
+/*
+ * 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.
+ */
+
+#if defined(WIN32) && !defined(QPID_BROKER_STATIC)
+#if defined(BROKER_EXPORT)
+#define QPID_BROKER_EXTERN __declspec(dllexport)
+#else
+#define QPID_BROKER_EXTERN __declspec(dllimport)
+#endif
+#else
+#define QPID_BROKER_EXTERN
+#endif
+
+#endif
diff --git a/qpid/cpp/src/qpid/broker/BrokerSingleton.h b/qpid/cpp/src/qpid/broker/BrokerSingleton.h
index 22b707506b..3a842ee05a 100644
--- a/qpid/cpp/src/qpid/broker/BrokerSingleton.h
+++ b/qpid/cpp/src/qpid/broker/BrokerSingleton.h
@@ -20,6 +20,7 @@
*/
#include "Broker.h"
+#include "BrokerImportExport.h"
namespace qpid {
namespace broker {
@@ -36,7 +37,7 @@ namespace broker {
*
* THREAD UNSAFE.
*/
-class BrokerSingleton : public boost::intrusive_ptr<Broker>
+class QPID_BROKER_EXTERN BrokerSingleton : public boost::intrusive_ptr<Broker>
{
public:
BrokerSingleton();
diff --git a/qpid/cpp/src/qpid/broker/Connection.cpp b/qpid/cpp/src/qpid/broker/Connection.cpp
index b7446a2220..b06e06d353 100644
--- a/qpid/cpp/src/qpid/broker/Connection.cpp
+++ b/qpid/cpp/src/qpid/broker/Connection.cpp
@@ -80,7 +80,8 @@ Connection::Connection(ConnectionOutputHandler* out_, Broker& broker_, const std
void Connection::requestIOProcessing(boost::function0<void> callback)
{
- ioCallback = callback;
+ ScopedLock<Mutex> l(ioCallbackLock);
+ ioCallbacks.push(callback);
out.activateOutput();
}
@@ -221,10 +222,13 @@ bool Connection::hasOutput() { return outputTasks.hasOutput(); }
bool Connection::doOutput() {
try{
- if (ioCallback)
- ioCallback(); // Lend the IO thread for management processing
- ioCallback = 0;
-
+ {
+ ScopedLock<Mutex> l(ioCallbackLock);
+ while (!ioCallbacks.empty()) {
+ ioCallbacks.front()(); // Lend the IO thread for management processing
+ ioCallbacks.pop();
+ }
+ }
if (mgmtClosing)
close(connection::CLOSE_CODE_CONNECTION_FORCED, "Closed by Management Request");
else
diff --git a/qpid/cpp/src/qpid/broker/Connection.h b/qpid/cpp/src/qpid/broker/Connection.h
index 71e03d76d4..b659fe6468 100644
--- a/qpid/cpp/src/qpid/broker/Connection.h
+++ b/qpid/cpp/src/qpid/broker/Connection.h
@@ -25,6 +25,7 @@
#include <memory>
#include <sstream>
#include <vector>
+#include <queue>
#include <boost/ptr_container/ptr_map.hpp>
@@ -47,6 +48,7 @@
#include "qpid/sys/ConnectionOutputHandler.h"
#include "qpid/sys/Socket.h"
#include "qpid/sys/TimeoutHandler.h"
+#include "qpid/sys/Mutex.h"
#include <boost/ptr_container/ptr_map.hpp>
#include <boost/bind.hpp>
@@ -119,12 +121,15 @@ class Connection : public sys::ConnectionInputHandler,
const bool isLink;
bool mgmtClosing;
const std::string mgmtId;
- boost::function0<void> ioCallback;
+ sys::Mutex ioCallbackLock;
+ std::queue<boost::function0<void> > ioCallbacks;
qmf::org::apache::qpid::broker::Connection* mgmtObject;
LinkRegistry& links;
management::ManagementAgent* agent;
Timer& timer;
boost::intrusive_ptr<TimerTask> heartbeatTimer;
+ public:
+ qmf::org::apache::qpid::broker::Connection* getMgmtObject() { return mgmtObject; }
};
}}
diff --git a/qpid/cpp/src/qpid/broker/ConnectionHandler.cpp b/qpid/cpp/src/qpid/broker/ConnectionHandler.cpp
index f136d61462..63212c7794 100644
--- a/qpid/cpp/src/qpid/broker/ConnectionHandler.cpp
+++ b/qpid/cpp/src/qpid/broker/ConnectionHandler.cpp
@@ -24,8 +24,7 @@
#include "Connection.h"
#include "SecureConnection.h"
#include "qpid/Url.h"
-#include "qpid/framing/ClientInvoker.h"
-#include "qpid/framing/ServerInvoker.h"
+#include "qpid/framing/AllInvoker.h"
#include "qpid/framing/enum.h"
#include "qpid/log/Statement.h"
#include "qpid/sys/SecurityLayer.h"
@@ -46,37 +45,33 @@ const std::string en_US = "en_US";
const std::string QPID_FED_LINK = "qpid.fed_link";
const std::string QPID_FED_TAG = "qpid.federation_tag";
const std::string SESSION_FLOW_CONTROL("qpid.session_flow");
+const std::string CLIENT_PROCESS_NAME("qpid.client_process");
+const std::string CLIENT_PID("qpid.client_pid");
+const std::string CLIENT_PPID("qpid.client_ppid");
const int SESSION_FLOW_CONTROL_VER = 1;
}
void ConnectionHandler::close(connection::CloseCode code, const string& text)
{
- handler->client.close(code, text);
+ handler->proxy.close(code, text);
}
void ConnectionHandler::heartbeat()
{
- handler->client.heartbeat();
+ handler->proxy.heartbeat();
}
void ConnectionHandler::handle(framing::AMQFrame& frame)
{
AMQMethodBody* method=frame.getBody()->getMethod();
try{
- bool handled = false;
- if (handler->serverMode) {
- handled = invoke(static_cast<AMQP_ServerOperations::ConnectionHandler&>(*handler.get()), *method);
- } else {
- handled = invoke(static_cast<AMQP_ClientOperations::ConnectionHandler&>(*handler.get()), *method);
- }
- if (!handled) {
+ if (!invoke(static_cast<AMQP_AllOperations::ConnectionHandler&>(*handler.get()), *method)) {
handler->connection.getChannel(frame.getChannel()).in(frame);
}
-
}catch(ConnectionException& e){
- handler->client.close(e.code, e.what());
+ handler->proxy.close(e.code, e.what());
}catch(std::exception& e){
- handler->client.close(541/*internal error*/, e.what());
+ handler->proxy.close(541/*internal error*/, e.what());
}
}
@@ -88,7 +83,7 @@ void ConnectionHandler::setSecureConnection(SecureConnection* secured)
ConnectionHandler::ConnectionHandler(Connection& connection, bool isClient) : handler(new Handler(connection, isClient)) {}
ConnectionHandler::Handler::Handler(Connection& c, bool isClient) :
- client(c.getOutput()), server(c.getOutput()),
+ proxy(c.getOutput()),
connection(c), serverMode(!isClient), acl(0), secured(0)
{
if (serverMode) {
@@ -106,7 +101,7 @@ ConnectionHandler::Handler::Handler(Connection& c, bool isClient) :
Array locales(0x95);
boost::shared_ptr<FieldValue> l(new Str16Value(en_US));
locales.add(l);
- client.start(properties, mechanisms, locales);
+ proxy.start(properties, mechanisms, locales);
}
}
@@ -136,14 +131,27 @@ void ConnectionHandler::Handler::startOk(const framing::FieldTable& clientProper
connection.setFederationPeerTag(clientProperties.getAsString(QPID_FED_TAG));
if (connection.isFederationLink()) {
if (acl && !acl->authorise(connection.getUserId(),acl::ACT_CREATE,acl::OBJ_LINK,"")){
- client.close(framing::connection::CLOSE_CODE_CONNECTION_FORCED,"ACL denied creating a federation link");
+ proxy.close(framing::connection::CLOSE_CODE_CONNECTION_FORCED,"ACL denied creating a federation link");
return;
}
QPID_LOG(info, "Connection is a federation link");
}
- if ( clientProperties.getAsInt(SESSION_FLOW_CONTROL) == SESSION_FLOW_CONTROL_VER ) {
+ if (clientProperties.getAsInt(SESSION_FLOW_CONTROL) == SESSION_FLOW_CONTROL_VER) {
connection.setClientThrottling();
}
+
+ if (connection.getMgmtObject() != 0) {
+ string procName = clientProperties.getAsString(CLIENT_PROCESS_NAME);
+ uint32_t pid = clientProperties.getAsInt(CLIENT_PID);
+ uint32_t ppid = clientProperties.getAsInt(CLIENT_PPID);
+
+ if (!procName.empty())
+ connection.getMgmtObject()->set_remoteProcessName(procName);
+ if (pid != 0)
+ connection.getMgmtObject()->set_remotePid(pid);
+ if (ppid != 0)
+ connection.getMgmtObject()->set_remoteParentPid(ppid);
+ }
}
void ConnectionHandler::Handler::secureOk(const string& response)
@@ -177,7 +185,7 @@ void ConnectionHandler::Handler::open(const string& /*virtualHost*/,
framing::Array array(0x95); // str16 array
for (std::vector<Url>::iterator i = urls.begin(); i < urls.end(); ++i)
array.add(boost::shared_ptr<Str16Value>(new Str16Value(i->str())));
- client.openOk(array);
+ proxy.openOk(array);
//install security layer if one has been negotiated:
if (secured) {
@@ -196,7 +204,7 @@ void ConnectionHandler::Handler::close(uint16_t replyCode, const string& replyTe
if (replyCode == framing::connection::CLOSE_CODE_CONNECTION_FORCED)
connection.notifyConnectionForced(replyText);
- client.closeOk();
+ proxy.closeOk();
connection.getOutput().close();
}
@@ -222,12 +230,12 @@ void ConnectionHandler::Handler::start(const FieldTable& serverProperties,
FieldTable ft;
ft.setInt(QPID_FED_LINK,1);
ft.setString(QPID_FED_TAG, connection.getBroker().getFederationTag());
- server.startOk(ft, mechanism, response, en_US);
+ proxy.startOk(ft, mechanism, response, en_US);
}
void ConnectionHandler::Handler::secure(const string& /*challenge*/)
{
- server.secureOk("");
+ proxy.secureOk("");
}
void ConnectionHandler::Handler::tune(uint16_t channelMax,
@@ -237,8 +245,8 @@ void ConnectionHandler::Handler::tune(uint16_t channelMax,
{
connection.setFrameMax(frameMax);
connection.setHeartbeat(heartbeatMax);
- server.tuneOk(channelMax, frameMax, heartbeatMax);
- server.open("/", Array(), true);
+ proxy.tuneOk(channelMax, frameMax, heartbeatMax);
+ proxy.open("/", Array(), true);
}
void ConnectionHandler::Handler::openOk(const framing::Array& knownHosts)
diff --git a/qpid/cpp/src/qpid/broker/ConnectionHandler.h b/qpid/cpp/src/qpid/broker/ConnectionHandler.h
index b24c10e9e8..ac4816dafa 100644
--- a/qpid/cpp/src/qpid/broker/ConnectionHandler.h
+++ b/qpid/cpp/src/qpid/broker/ConnectionHandler.h
@@ -25,10 +25,8 @@
#include "SaslAuthenticator.h"
#include "qpid/framing/amqp_types.h"
#include "qpid/framing/AMQFrame.h"
-#include "qpid/framing/AMQP_ClientOperations.h"
-#include "qpid/framing/AMQP_ClientProxy.h"
-#include "qpid/framing/AMQP_ServerOperations.h"
-#include "qpid/framing/AMQP_ServerProxy.h"
+#include "qpid/framing/AMQP_AllOperations.h"
+#include "qpid/framing/AMQP_AllProxy.h"
#include "qpid/framing/enum.h"
#include "qpid/framing/FrameHandler.h"
#include "qpid/framing/ProtocolInitiation.h"
@@ -44,11 +42,9 @@ class SecureConnection;
class ConnectionHandler : public framing::FrameHandler
{
- struct Handler : public framing::AMQP_ServerOperations::ConnectionHandler,
- public framing::AMQP_ClientOperations::ConnectionHandler
+ struct Handler : public framing::AMQP_AllOperations::ConnectionHandler
{
- framing::AMQP_ClientProxy::Connection client;
- framing::AMQP_ServerProxy::Connection server;
+ framing::AMQP_AllProxy::Connection proxy;
Connection& connection;
bool serverMode;
std::auto_ptr<SaslAuthenticator> authenticator;
diff --git a/qpid/cpp/src/qpid/broker/ConnectionState.h b/qpid/cpp/src/qpid/broker/ConnectionState.h
index 0e9d211b56..b712af11f5 100644
--- a/qpid/cpp/src/qpid/broker/ConnectionState.h
+++ b/qpid/cpp/src/qpid/broker/ConnectionState.h
@@ -48,8 +48,9 @@ class ConnectionState : public ConnectionToken, public management::Manageable
heartbeatmax(120),
stagingThreshold(broker.getStagingThreshold()),
federationLink(true),
- clientSupportsThrottling(false)
- {}
+ clientSupportsThrottling(false),
+ clusterOrderOut(0)
+ {}
virtual ~ConnectionState () {}
@@ -75,7 +76,7 @@ class ConnectionState : public ConnectionToken, public management::Manageable
const string& getFederationPeerTag() const { return federationPeerTag; }
std::vector<Url>& getKnownHosts() { return knownHosts; }
- void setClientThrottling() { clientSupportsThrottling = true; }
+ void setClientThrottling(bool set=true) { clientSupportsThrottling = set; }
bool getClientThrottling() const { return clientSupportsThrottling; }
Broker& getBroker() { return broker; }
@@ -86,11 +87,21 @@ class ConnectionState : public ConnectionToken, public management::Manageable
//contained output tasks
sys::AggregateOutput outputTasks;
- sys::ConnectionOutputHandlerPtr& getOutput() { return out; }
+ sys::ConnectionOutputHandler& getOutput() { return out; }
framing::ProtocolVersion getVersion() const { return version; }
-
void setOutputHandler(qpid::sys::ConnectionOutputHandler* o) { out.set(o); }
+ /**
+ * If the broker is part of a cluster, this is a handler provided
+ * by cluster code. It ensures consistent ordering of commands
+ * that are sent based on criteria that are not predictably
+ * ordered cluster-wide, e.g. a timer firing.
+ */
+ framing::FrameHandler* getClusterOrderOutput() { return clusterOrderOut; }
+ void setClusterOrderOutput(framing::FrameHandler& fh) { clusterOrderOut = &fh; }
+
+ virtual void requestIOProcessing (boost::function0<void>) = 0;
+
protected:
framing::ProtocolVersion version;
uint32_t framemax;
@@ -103,6 +114,7 @@ class ConnectionState : public ConnectionToken, public management::Manageable
string federationPeerTag;
std::vector<Url> knownHosts;
bool clientSupportsThrottling;
+ framing::FrameHandler* clusterOrderOut;
};
}}
diff --git a/qpid/cpp/src/qpid/broker/Daemon.h b/qpid/cpp/src/qpid/broker/Daemon.h
index 98468debb7..a9cd98bce2 100644
--- a/qpid/cpp/src/qpid/broker/Daemon.h
+++ b/qpid/cpp/src/qpid/broker/Daemon.h
@@ -19,10 +19,12 @@
*
*/
-#include <string>
+#include "qpid/sys/IntegerTypes.h"
#include <boost/scoped_ptr.hpp>
#include <boost/function.hpp>
#include <boost/noncopyable.hpp>
+#include <string>
+
namespace qpid {
namespace broker {
diff --git a/qpid/cpp/src/qpid/broker/DeliverableMessage.h b/qpid/cpp/src/qpid/broker/DeliverableMessage.h
index f5db473c22..ad944c746b 100644
--- a/qpid/cpp/src/qpid/broker/DeliverableMessage.h
+++ b/qpid/cpp/src/qpid/broker/DeliverableMessage.h
@@ -21,6 +21,7 @@
#ifndef _DeliverableMessage_
#define _DeliverableMessage_
+#include "BrokerImportExport.h"
#include "Deliverable.h"
#include "Queue.h"
#include "Message.h"
@@ -32,10 +33,10 @@ namespace qpid {
class DeliverableMessage : public Deliverable{
boost::intrusive_ptr<Message> msg;
public:
- DeliverableMessage(const boost::intrusive_ptr<Message>& msg);
- virtual void deliverTo(const boost::shared_ptr<Queue>& queue);
- Message& getMessage();
- uint64_t contentSize();
+ QPID_BROKER_EXTERN DeliverableMessage(const boost::intrusive_ptr<Message>& msg);
+ QPID_BROKER_EXTERN virtual void deliverTo(const boost::shared_ptr<Queue>& queue);
+ QPID_BROKER_EXTERN Message& getMessage();
+ QPID_BROKER_EXTERN uint64_t contentSize();
virtual ~DeliverableMessage(){}
};
}
diff --git a/qpid/cpp/src/qpid/broker/DeliveryRecord.h b/qpid/cpp/src/qpid/broker/DeliveryRecord.h
index d7ccab0726..2b2d4d0515 100644
--- a/qpid/cpp/src/qpid/broker/DeliveryRecord.h
+++ b/qpid/cpp/src/qpid/broker/DeliveryRecord.h
@@ -26,6 +26,7 @@
#include <vector>
#include <ostream>
#include "qpid/framing/SequenceSet.h"
+#include "BrokerImportExport.h"
#include "Queue.h"
#include "QueuedMessage.h"
#include "DeliveryId.h"
@@ -74,17 +75,16 @@ class DeliveryRecord
const uint32_t credit;
public:
- DeliveryRecord(
- const QueuedMessage& msg,
- const Queue::shared_ptr& queue,
- const std::string& tag,
- bool acquired,
- bool accepted,
- bool windowing,
- uint32_t credit=0 // Only used if msg is empty.
+ QPID_BROKER_EXTERN DeliveryRecord(const QueuedMessage& msg,
+ const Queue::shared_ptr& queue,
+ const std::string& tag,
+ bool acquired,
+ bool accepted,
+ bool windowing,
+ uint32_t credit=0 // Only used if msg is empty.
);
- bool matches(DeliveryId tag) const;
+ QPID_BROKER_EXTERN bool matches(DeliveryId tag) const;
bool matchOrAfter(DeliveryId tag) const;
bool after(DeliveryId tag) const;
bool coveredBy(const framing::SequenceSet* const range) const;
@@ -119,7 +119,7 @@ class DeliveryRecord
const QueuedMessage& getMessage() const { return msg; }
framing::SequenceNumber getId() const { return id; }
Queue::shared_ptr getQueue() const { return queue; }
- friend bool operator<(const DeliveryRecord&, const DeliveryRecord&);
+ friend QPID_BROKER_EXTERN bool operator<(const DeliveryRecord&, const DeliveryRecord&);
friend std::ostream& operator<<(std::ostream&, const DeliveryRecord&);
};
diff --git a/qpid/cpp/src/qpid/broker/DirectExchange.h b/qpid/cpp/src/qpid/broker/DirectExchange.h
index ba60469df8..27d101c4fe 100644
--- a/qpid/cpp/src/qpid/broker/DirectExchange.h
+++ b/qpid/cpp/src/qpid/broker/DirectExchange.h
@@ -23,6 +23,7 @@
#include <map>
#include <vector>
+#include "BrokerImportExport.h"
#include "Exchange.h"
#include "qpid/framing/FieldTable.h"
#include "qpid/sys/CopyOnWriteArray.h"
@@ -44,18 +45,27 @@ class DirectExchange : public virtual Exchange {
public:
static const std::string typeName;
- DirectExchange(const std::string& name, management::Manageable* parent = 0);
- DirectExchange(const string& _name, bool _durable,
- const qpid::framing::FieldTable& _args, management::Manageable* parent = 0);
+ QPID_BROKER_EXTERN DirectExchange(const std::string& name,
+ management::Manageable* parent = 0);
+ QPID_BROKER_EXTERN DirectExchange(const string& _name,
+ bool _durable,
+ const qpid::framing::FieldTable& _args,
+ management::Manageable* parent = 0);
virtual std::string getType() const { return typeName; }
- virtual bool bind(Queue::shared_ptr queue, const std::string& routingKey, const qpid::framing::FieldTable* args);
+ QPID_BROKER_EXTERN virtual bool bind(Queue::shared_ptr queue,
+ const std::string& routingKey,
+ const qpid::framing::FieldTable* args);
virtual bool unbind(Queue::shared_ptr queue, const std::string& routingKey, const qpid::framing::FieldTable* args);
- virtual void route(Deliverable& msg, const std::string& routingKey, const qpid::framing::FieldTable* args);
- virtual bool isBound(Queue::shared_ptr queue, const string* const routingKey, const qpid::framing::FieldTable* const args);
+ QPID_BROKER_EXTERN virtual void route(Deliverable& msg,
+ const std::string& routingKey,
+ const qpid::framing::FieldTable* args);
+ QPID_BROKER_EXTERN virtual bool isBound(Queue::shared_ptr queue,
+ const string* const routingKey,
+ const qpid::framing::FieldTable* const args);
- virtual ~DirectExchange();
+ QPID_BROKER_EXTERN virtual ~DirectExchange();
virtual bool supportsDynamicBinding() { return true; }
};
diff --git a/qpid/cpp/src/qpid/broker/DtxBuffer.h b/qpid/cpp/src/qpid/broker/DtxBuffer.h
index b302632037..ce37d09b7a 100644
--- a/qpid/cpp/src/qpid/broker/DtxBuffer.h
+++ b/qpid/cpp/src/qpid/broker/DtxBuffer.h
@@ -21,6 +21,7 @@
#ifndef _DtxBuffer_
#define _DtxBuffer_
+#include "BrokerImportExport.h"
#include "TxBuffer.h"
#include "qpid/sys/Mutex.h"
@@ -37,9 +38,9 @@ namespace qpid {
public:
typedef boost::shared_ptr<DtxBuffer> shared_ptr;
- DtxBuffer(const std::string& xid = "");
- ~DtxBuffer();
- void markEnded();
+ QPID_BROKER_EXTERN DtxBuffer(const std::string& xid = "");
+ QPID_BROKER_EXTERN ~DtxBuffer();
+ QPID_BROKER_EXTERN void markEnded();
bool isEnded();
void setSuspended(bool suspended);
bool isSuspended();
diff --git a/qpid/cpp/src/qpid/broker/DtxWorkRecord.h b/qpid/cpp/src/qpid/broker/DtxWorkRecord.h
index 6677784c32..21fc759d66 100644
--- a/qpid/cpp/src/qpid/broker/DtxWorkRecord.h
+++ b/qpid/cpp/src/qpid/broker/DtxWorkRecord.h
@@ -21,6 +21,7 @@
#ifndef _DtxWorkRecord_
#define _DtxWorkRecord_
+#include "BrokerImportExport.h"
#include "DtxBuffer.h"
#include "DtxTimeout.h"
#include "TransactionalStore.h"
@@ -61,12 +62,13 @@ class DtxWorkRecord
void abort();
bool prepare(TransactionContext* txn);
public:
- DtxWorkRecord(const std::string& xid, TransactionalStore* const store);
- ~DtxWorkRecord();
- bool prepare();
- bool commit(bool onePhase);
- void rollback();
- void add(DtxBuffer::shared_ptr ops);
+ QPID_BROKER_EXTERN DtxWorkRecord(const std::string& xid,
+ TransactionalStore* const store);
+ QPID_BROKER_EXTERN ~DtxWorkRecord();
+ QPID_BROKER_EXTERN bool prepare();
+ QPID_BROKER_EXTERN bool commit(bool onePhase);
+ QPID_BROKER_EXTERN void rollback();
+ QPID_BROKER_EXTERN void add(DtxBuffer::shared_ptr ops);
void recover(std::auto_ptr<TPCTransactionContext> txn, DtxBuffer::shared_ptr ops);
void timedout();
void setTimeout(boost::intrusive_ptr<DtxTimeout> t) { timeout = t; }
diff --git a/qpid/cpp/src/qpid/broker/Exchange.cpp b/qpid/cpp/src/qpid/broker/Exchange.cpp
index f8b9e4b183..dd1fe98b2c 100644
--- a/qpid/cpp/src/qpid/broker/Exchange.cpp
+++ b/qpid/cpp/src/qpid/broker/Exchange.cpp
@@ -102,8 +102,8 @@ static const std::string QPID_MANAGEMENT("qpid.management");
Exchange::Exchange(const string& _name, bool _durable, const qpid::framing::FieldTable& _args,
Manageable* parent)
- : name(_name), durable(_durable), args(_args), alternateUsers(0), persistenceId(0),
- sequence(false), sequenceNo(0), ive(false), mgmtExchange(0)
+ : name(_name), durable(_durable), alternateUsers(0), persistenceId(0),
+ args(_args), sequence(false), sequenceNo(0), ive(false), mgmtExchange(0)
{
if (parent != 0)
{
@@ -275,3 +275,7 @@ bool Exchange::MatchQueue::operator()(Exchange::Binding::shared_ptr b)
{
return b->queue == queue;
}
+
+void Exchange::setProperties(const boost::intrusive_ptr<Message>& msg) {
+ msg->getProperties<DeliveryProperties>()->setExchange(getName());
+}
diff --git a/qpid/cpp/src/qpid/broker/Exchange.h b/qpid/cpp/src/qpid/broker/Exchange.h
index 488549bbf6..9260222342 100644
--- a/qpid/cpp/src/qpid/broker/Exchange.h
+++ b/qpid/cpp/src/qpid/broker/Exchange.h
@@ -23,6 +23,7 @@
*/
#include <boost/shared_ptr.hpp>
+#include "BrokerImportExport.h"
#include "Deliverable.h"
#include "Queue.h"
#include "MessageStore.h"
@@ -58,12 +59,12 @@ public:
private:
const std::string name;
const bool durable;
- mutable qpid::framing::FieldTable args;
boost::shared_ptr<Exchange> alternate;
uint32_t alternateUsers;
mutable uint64_t persistenceId;
protected:
+ mutable qpid::framing::FieldTable args;
bool sequence;
mutable qpid::sys::Mutex sequenceLock;
int64_t sequenceNo;
@@ -123,7 +124,7 @@ public:
explicit Exchange(const std::string& name, management::Manageable* parent = 0);
Exchange(const std::string& _name, bool _durable, const qpid::framing::FieldTable& _args,
management::Manageable* parent = 0);
- virtual ~Exchange();
+ QPID_BROKER_EXTERN virtual ~Exchange();
const std::string& getName() const { return name; }
bool isDurable() { return durable; }
@@ -139,15 +140,16 @@ public:
virtual bool bind(Queue::shared_ptr queue, const std::string& routingKey, const qpid::framing::FieldTable* args) = 0;
virtual bool unbind(Queue::shared_ptr queue, const std::string& routingKey, const qpid::framing::FieldTable* args) = 0;
virtual bool isBound(Queue::shared_ptr queue, const std::string* const routingKey, const qpid::framing::FieldTable* const args) = 0;
+ virtual void setProperties(const boost::intrusive_ptr<Message>&);
virtual void route(Deliverable& msg, const std::string& routingKey, const qpid::framing::FieldTable* args) = 0;
-
+
//PersistableExchange:
void setPersistenceId(uint64_t id) const;
uint64_t getPersistenceId() const { return persistenceId; }
uint32_t encodedSize() const;
- void encode(framing::Buffer& buffer) const;
+ QPID_BROKER_EXTERN virtual void encode(framing::Buffer& buffer) const;
- static Exchange::shared_ptr decode(ExchangeRegistry& exchanges, framing::Buffer& buffer);
+ static QPID_BROKER_EXTERN Exchange::shared_ptr decode(ExchangeRegistry& exchanges, framing::Buffer& buffer);
// Manageable entry points
management::ManagementObject* GetManagementObject(void) const;
diff --git a/qpid/cpp/src/qpid/broker/ExchangeRegistry.h b/qpid/cpp/src/qpid/broker/ExchangeRegistry.h
index 787b7896f0..9ca432e41c 100644
--- a/qpid/cpp/src/qpid/broker/ExchangeRegistry.h
+++ b/qpid/cpp/src/qpid/broker/ExchangeRegistry.h
@@ -22,6 +22,7 @@
*
*/
+#include "BrokerImportExport.h"
#include "Exchange.h"
#include "MessageStore.h"
#include "qpid/framing/FieldTable.h"
@@ -45,13 +46,17 @@ class ExchangeRegistry{
bool, const qpid::framing::FieldTable&, qpid::management::Manageable*> FactoryFunction;
ExchangeRegistry () : parent(0) {}
- std::pair<Exchange::shared_ptr, bool> declare(const std::string& name, const std::string& type)
+ QPID_BROKER_EXTERN std::pair<Exchange::shared_ptr, bool> declare
+ (const std::string& name, const std::string& type)
throw(UnknownExchangeTypeException);
- std::pair<Exchange::shared_ptr, bool> declare(const std::string& name, const std::string& type,
- bool durable, const qpid::framing::FieldTable& args = framing::FieldTable())
- throw(UnknownExchangeTypeException);
- void destroy(const std::string& name);
- Exchange::shared_ptr get(const std::string& name);
+ QPID_BROKER_EXTERN std::pair<Exchange::shared_ptr, bool> declare
+ (const std::string& name,
+ const std::string& type,
+ bool durable,
+ const qpid::framing::FieldTable& args = framing::FieldTable())
+ throw(UnknownExchangeTypeException);
+ QPID_BROKER_EXTERN void destroy(const std::string& name);
+ QPID_BROKER_EXTERN Exchange::shared_ptr get(const std::string& name);
Exchange::shared_ptr getDefault();
/**
diff --git a/qpid/cpp/src/qpid/broker/ExpiryPolicy.h b/qpid/cpp/src/qpid/broker/ExpiryPolicy.h
index 1b7316f6f9..cefe9b7552 100644
--- a/qpid/cpp/src/qpid/broker/ExpiryPolicy.h
+++ b/qpid/cpp/src/qpid/broker/ExpiryPolicy.h
@@ -23,6 +23,7 @@
*/
#include "qpid/RefCounted.h"
+#include "BrokerImportExport.h"
namespace qpid {
namespace broker {
@@ -35,9 +36,9 @@ class Message;
class ExpiryPolicy : public RefCounted
{
public:
- virtual ~ExpiryPolicy();
- virtual void willExpire(Message&);
- virtual bool hasExpired(Message&);
+ QPID_BROKER_EXTERN virtual ~ExpiryPolicy();
+ QPID_BROKER_EXTERN virtual void willExpire(Message&);
+ QPID_BROKER_EXTERN virtual bool hasExpired(Message&);
};
}} // namespace qpid::broker
diff --git a/qpid/cpp/src/qpid/broker/FanOutExchange.h b/qpid/cpp/src/qpid/broker/FanOutExchange.h
index 5884a19732..edfc4395f4 100644
--- a/qpid/cpp/src/qpid/broker/FanOutExchange.h
+++ b/qpid/cpp/src/qpid/broker/FanOutExchange.h
@@ -23,6 +23,7 @@
#include <map>
#include <vector>
+#include "BrokerImportExport.h"
#include "Exchange.h"
#include "qpid/framing/FieldTable.h"
#include "qpid/sys/CopyOnWriteArray.h"
@@ -38,22 +39,30 @@ class FanOutExchange : public virtual Exchange {
public:
static const std::string typeName;
- FanOutExchange(const std::string& name, management::Manageable* parent = 0);
- FanOutExchange(const string& _name, bool _durable,
- const qpid::framing::FieldTable& _args,
- management::Manageable* parent = 0);
+ QPID_BROKER_EXTERN FanOutExchange(const std::string& name,
+ management::Manageable* parent = 0);
+ QPID_BROKER_EXTERN FanOutExchange(const string& _name,
+ bool _durable,
+ const qpid::framing::FieldTable& _args,
+ management::Manageable* parent = 0);
virtual std::string getType() const { return typeName; }
- virtual bool bind(Queue::shared_ptr queue, const std::string& routingKey, const qpid::framing::FieldTable* args);
+ QPID_BROKER_EXTERN virtual bool bind(Queue::shared_ptr queue,
+ const std::string& routingKey,
+ const qpid::framing::FieldTable* args);
virtual bool unbind(Queue::shared_ptr queue, const std::string& routingKey, const qpid::framing::FieldTable* args);
- virtual void route(Deliverable& msg, const std::string& routingKey, const qpid::framing::FieldTable* args);
+ QPID_BROKER_EXTERN virtual void route(Deliverable& msg,
+ const std::string& routingKey,
+ const qpid::framing::FieldTable* args);
- virtual bool isBound(Queue::shared_ptr queue, const string* const routingKey, const qpid::framing::FieldTable* const args);
+ QPID_BROKER_EXTERN virtual bool isBound(Queue::shared_ptr queue,
+ const string* const routingKey,
+ const qpid::framing::FieldTable* const args);
- virtual ~FanOutExchange();
+ QPID_BROKER_EXTERN virtual ~FanOutExchange();
virtual bool supportsDynamicBinding() { return true; }
};
diff --git a/qpid/cpp/src/qpid/broker/HeadersExchange.cpp b/qpid/cpp/src/qpid/broker/HeadersExchange.cpp
index 104b34da8b..09fb2d9bef 100644
--- a/qpid/cpp/src/qpid/broker/HeadersExchange.cpp
+++ b/qpid/cpp/src/qpid/broker/HeadersExchange.cpp
@@ -105,33 +105,42 @@ bool HeadersExchange::unbind(Queue::shared_ptr queue, const string& bindingKey,
void HeadersExchange::route(Deliverable& msg, const string& /*routingKey*/, const FieldTable* args){
- if (!args) return;//can't match if there were no headers passed in
+ if (!args) {
+ //can't match if there were no headers passed in
+ if (mgmtExchange != 0) {
+ mgmtExchange->inc_msgReceives();
+ mgmtExchange->inc_byteReceives(msg.contentSize());
+ mgmtExchange->inc_msgDrops();
+ mgmtExchange->inc_byteDrops(msg.contentSize());
+ }
+ return;
+ }
+
PreRoute pr(msg, this);
uint32_t count(0);
Bindings::ConstPtr p = bindings.snapshot();
if (p.get()){
- for (std::vector<Binding::shared_ptr>::const_iterator i = p->begin(); i != p->end(); ++i, count++) {
- if (match((*i)->args, *args)) msg.deliverTo((*i)->queue);
- if ((*i)->mgmtBinding != 0)
- (*i)->mgmtBinding->inc_msgMatched ();
+ for (std::vector<Binding::shared_ptr>::const_iterator i = p->begin(); i != p->end(); ++i) {
+ if (match((*i)->args, *args)) {
+ msg.deliverTo((*i)->queue);
+ count++;
+ if ((*i)->mgmtBinding != 0)
+ (*i)->mgmtBinding->inc_msgMatched();
+ }
}
}
- if (mgmtExchange != 0)
- {
- mgmtExchange->inc_msgReceives ();
- mgmtExchange->inc_byteReceives (msg.contentSize ());
- if (count == 0)
- {
- mgmtExchange->inc_msgDrops ();
- mgmtExchange->inc_byteDrops (msg.contentSize ());
- }
- else
- {
- mgmtExchange->inc_msgRoutes (count);
- mgmtExchange->inc_byteRoutes (count * msg.contentSize ());
+ if (mgmtExchange != 0) {
+ mgmtExchange->inc_msgReceives();
+ mgmtExchange->inc_byteReceives(msg.contentSize());
+ if (count == 0) {
+ mgmtExchange->inc_msgDrops();
+ mgmtExchange->inc_byteDrops(msg.contentSize());
+ } else {
+ mgmtExchange->inc_msgRoutes(count);
+ mgmtExchange->inc_byteRoutes(count * msg.contentSize());
}
}
}
diff --git a/qpid/cpp/src/qpid/broker/HeadersExchange.h b/qpid/cpp/src/qpid/broker/HeadersExchange.h
index e10fab2250..2b01f9ecae 100644
--- a/qpid/cpp/src/qpid/broker/HeadersExchange.h
+++ b/qpid/cpp/src/qpid/broker/HeadersExchange.h
@@ -22,6 +22,7 @@
#define _HeadersExchange_
#include <vector>
+#include "BrokerImportExport.h"
#include "Exchange.h"
#include "qpid/framing/FieldTable.h"
#include "qpid/sys/CopyOnWriteArray.h"
@@ -59,24 +60,32 @@ class HeadersExchange : public virtual Exchange {
public:
static const std::string typeName;
- HeadersExchange(const string& name, management::Manageable* parent = 0);
- HeadersExchange(const string& _name, bool _durable,
- const qpid::framing::FieldTable& _args,
- management::Manageable* parent = 0);
+ QPID_BROKER_EXTERN HeadersExchange(const string& name,
+ management::Manageable* parent = 0);
+ QPID_BROKER_EXTERN HeadersExchange(const string& _name,
+ bool _durable,
+ const qpid::framing::FieldTable& _args,
+ management::Manageable* parent = 0);
virtual std::string getType() const { return typeName; }
- virtual bool bind(Queue::shared_ptr queue, const string& routingKey, const qpid::framing::FieldTable* args);
+ QPID_BROKER_EXTERN virtual bool bind(Queue::shared_ptr queue,
+ const string& routingKey,
+ const qpid::framing::FieldTable* args);
virtual bool unbind(Queue::shared_ptr queue, const string& routingKey, const qpid::framing::FieldTable* args);
- virtual void route(Deliverable& msg, const string& routingKey, const qpid::framing::FieldTable* args);
+ QPID_BROKER_EXTERN virtual void route(Deliverable& msg,
+ const string& routingKey,
+ const qpid::framing::FieldTable* args);
- virtual bool isBound(Queue::shared_ptr queue, const string* const routingKey, const qpid::framing::FieldTable* const args);
+ QPID_BROKER_EXTERN virtual bool isBound(Queue::shared_ptr queue,
+ const string* const routingKey,
+ const qpid::framing::FieldTable* const args);
- virtual ~HeadersExchange();
+ QPID_BROKER_EXTERN virtual ~HeadersExchange();
- static bool match(const qpid::framing::FieldTable& bindArgs, const qpid::framing::FieldTable& msgArgs);
+ static QPID_BROKER_EXTERN bool match(const qpid::framing::FieldTable& bindArgs, const qpid::framing::FieldTable& msgArgs);
static bool equal(const qpid::framing::FieldTable& bindArgs, const qpid::framing::FieldTable& msgArgs);
};
diff --git a/qpid/cpp/src/qpid/broker/IncompleteMessageList.h b/qpid/cpp/src/qpid/broker/IncompleteMessageList.h
index f89c0023b0..449194d571 100644
--- a/qpid/cpp/src/qpid/broker/IncompleteMessageList.h
+++ b/qpid/cpp/src/qpid/broker/IncompleteMessageList.h
@@ -21,6 +21,7 @@
#ifndef _IncompleteMessageList_
#define _IncompleteMessageList_
+#include "BrokerImportExport.h"
#include "qpid/sys/Monitor.h"
#include "qpid/broker/Message.h"
#include <boost/intrusive_ptr.hpp>
@@ -43,11 +44,11 @@ class IncompleteMessageList
public:
typedef Message::MessageCallback CompletionListener;
- IncompleteMessageList();
- ~IncompleteMessageList();
+ QPID_BROKER_EXTERN IncompleteMessageList();
+ QPID_BROKER_EXTERN ~IncompleteMessageList();
- void add(boost::intrusive_ptr<Message> msg);
- void process(const CompletionListener& l, bool sync);
+ QPID_BROKER_EXTERN void add(boost::intrusive_ptr<Message> msg);
+ QPID_BROKER_EXTERN void process(const CompletionListener& l, bool sync);
void each(const CompletionListener& l);
};
diff --git a/qpid/cpp/src/qpid/broker/Link.cpp b/qpid/cpp/src/qpid/broker/Link.cpp
index e36635831b..dd1a1fa0b4 100644
--- a/qpid/cpp/src/qpid/broker/Link.cpp
+++ b/qpid/cpp/src/qpid/broker/Link.cpp
@@ -158,7 +158,7 @@ void Link::closed (int, std::string text)
}
for (Bridges::iterator i = active.begin(); i != active.end(); i++) {
- (*i)->cancel();
+ (*i)->closed();
created.push_back(*i);
}
active.clear();
@@ -217,21 +217,27 @@ void Link::add(Bridge::shared_ptr bridge)
void Link::cancel(Bridge::shared_ptr bridge)
{
- Mutex::ScopedLock mutex(lock);
-
- for (Bridges::iterator i = created.begin(); i != created.end(); i++) {
- if ((*i).get() == bridge.get()) {
- created.erase(i);
- break;
+ {
+ Mutex::ScopedLock mutex(lock);
+
+ for (Bridges::iterator i = created.begin(); i != created.end(); i++) {
+ if ((*i).get() == bridge.get()) {
+ created.erase(i);
+ break;
+ }
}
- }
- for (Bridges::iterator i = active.begin(); i != active.end(); i++) {
- if ((*i).get() == bridge.get()) {
- bridge->cancel();
- active.erase(i);
- break;
+ for (Bridges::iterator i = active.begin(); i != active.end(); i++) {
+ if ((*i).get() == bridge.get()) {
+ cancellations.push_back(bridge);
+ bridge->closed();
+ active.erase(i);
+ break;
+ }
}
}
+ if (!cancellations.empty()) {
+ connection->requestIOProcessing (boost::bind(&Link::ioThreadProcessing, this));
+ }
}
void Link::ioThreadProcessing()
@@ -242,7 +248,7 @@ void Link::ioThreadProcessing()
return;
QPID_LOG(debug, "Link::ioThreadProcessing()");
- //process any pending creates
+ //process any pending creates and/or cancellations
if (!created.empty()) {
for (Bridges::iterator i = created.begin(); i != created.end(); ++i) {
active.push_back(*i);
@@ -250,6 +256,13 @@ void Link::ioThreadProcessing()
}
created.clear();
}
+ if (!cancellations.empty()) {
+ for (Bridges::iterator i = cancellations.begin(); i != cancellations.end(); ++i) {
+ active.push_back(*i);
+ (*i)->cancel(*connection);
+ }
+ cancellations.clear();
+ }
}
void Link::setConnection(Connection* c)
@@ -284,7 +297,7 @@ void Link::maintenanceVisit ()
}
}
}
- else if (state == STATE_OPERATIONAL && !created.empty() && connection != 0)
+ else if (state == STATE_OPERATIONAL && (!created.empty() || !cancellations.empty()) && connection != 0)
connection->requestIOProcessing (boost::bind(&Link::ioThreadProcessing, this));
}
diff --git a/qpid/cpp/src/qpid/broker/Link.h b/qpid/cpp/src/qpid/broker/Link.h
index 8e741c6eb7..39014b0ec0 100644
--- a/qpid/cpp/src/qpid/broker/Link.h
+++ b/qpid/cpp/src/qpid/broker/Link.h
@@ -67,6 +67,7 @@ namespace qpid {
typedef std::vector<Bridge::shared_ptr> Bridges;
Bridges created; // Bridges pending creation
Bridges active; // Bridges active
+ Bridges cancellations; // Bridges pending cancellation
uint channelCounter;
Connection* connection;
management::ManagementAgent* agent;
diff --git a/qpid/cpp/src/qpid/broker/LinkRegistry.cpp b/qpid/cpp/src/qpid/broker/LinkRegistry.cpp
index 97b1c32d64..7d4ab7548e 100644
--- a/qpid/cpp/src/qpid/broker/LinkRegistry.cpp
+++ b/qpid/cpp/src/qpid/broker/LinkRegistry.cpp
@@ -19,19 +19,24 @@
*
*/
#include "LinkRegistry.h"
+#include "Connection.h"
#include "qpid/log/Statement.h"
#include <iostream>
+#include <boost/format.hpp>
using namespace qpid::broker;
using namespace qpid::sys;
using std::pair;
using std::stringstream;
using boost::intrusive_ptr;
+using boost::format;
+using boost::str;
namespace _qmf = qmf::org::apache::qpid::broker;
#define LINK_MAINT_INTERVAL 2
-LinkRegistry::LinkRegistry (Broker* _broker) : broker(_broker), parent(0), store(0), passive(false), passiveChanged(false)
+LinkRegistry::LinkRegistry (Broker* _broker) : broker(_broker), parent(0), store(0), passive(false), passiveChanged(false),
+ realm(broker ? broker->getOptions().realm : "")
{
timer.add (intrusive_ptr<TimerTask> (new Periodic(*this)));
}
@@ -233,66 +238,70 @@ MessageStore* LinkRegistry::getStore() const {
return store;
}
-void LinkRegistry::notifyConnection(const std::string& key, Connection* c)
+Link::shared_ptr LinkRegistry::findLink(const std::string& key)
{
Mutex::ScopedLock locker(lock);
LinkMap::iterator l = links.find(key);
- if (l != links.end())
- {
- l->second->established();
- l->second->setConnection(c);
+ if (l != links.end()) return l->second;
+ else return Link::shared_ptr();
+}
+
+void LinkRegistry::notifyConnection(const std::string& key, Connection* c)
+{
+ Link::shared_ptr link = findLink(key);
+ if (link) {
+ link->established();
+ link->setConnection(c);
+ c->setUserId(str(format("%1%@%2%") % link->getUsername() % realm));
}
}
void LinkRegistry::notifyClosed(const std::string& key)
{
- Mutex::ScopedLock locker(lock);
- LinkMap::iterator l = links.find(key);
- if (l != links.end())
- l->second->closed(0, "Closed by peer");
+ Link::shared_ptr link = findLink(key);
+ if (link) {
+ link->closed(0, "Closed by peer");
+ }
}
void LinkRegistry::notifyConnectionForced(const std::string& key, const std::string& text)
{
- Mutex::ScopedLock locker(lock);
- LinkMap::iterator l = links.find(key);
- if (l != links.end())
- l->second->notifyConnectionForced(text);
+ Link::shared_ptr link = findLink(key);
+ if (link) {
+ link->notifyConnectionForced(text);
+ }
}
std::string LinkRegistry::getAuthMechanism(const std::string& key)
{
- Mutex::ScopedLock locker(lock);
- LinkMap::iterator l = links.find(key);
- if (l != links.end())
- return l->second->getAuthMechanism();
+ Link::shared_ptr link = findLink(key);
+ if (link)
+ return link->getAuthMechanism();
return string("ANONYMOUS");
}
std::string LinkRegistry::getAuthCredentials(const std::string& key)
{
- Mutex::ScopedLock locker(lock);
- LinkMap::iterator l = links.find(key);
- if (l == links.end())
+ Link::shared_ptr link = findLink(key);
+ if (!link)
return string();
string result;
result += '\0';
- result += l->second->getUsername();
+ result += link->getUsername();
result += '\0';
- result += l->second->getPassword();
+ result += link->getPassword();
return result;
}
std::string LinkRegistry::getAuthIdentity(const std::string& key)
{
- Mutex::ScopedLock locker(lock);
- LinkMap::iterator l = links.find(key);
- if (l == links.end())
+ Link::shared_ptr link = findLink(key);
+ if (!link)
return string();
- return l->second->getUsername();
+ return link->getUsername();
}
diff --git a/qpid/cpp/src/qpid/broker/LinkRegistry.h b/qpid/cpp/src/qpid/broker/LinkRegistry.h
index 884228bd63..2397dbc6f3 100644
--- a/qpid/cpp/src/qpid/broker/LinkRegistry.h
+++ b/qpid/cpp/src/qpid/broker/LinkRegistry.h
@@ -66,9 +66,11 @@ namespace broker {
MessageStore* store;
bool passive;
bool passiveChanged;
+ std::string realm;
void periodicMaintenance ();
bool updateAddress(const std::string& oldKey, const TcpAddress& newAddress);
+ Link::shared_ptr findLink(const std::string& key);
static std::string createKey(const TcpAddress& address);
public:
diff --git a/qpid/cpp/src/qpid/broker/Message.cpp b/qpid/cpp/src/qpid/broker/Message.cpp
index 133e2b5ad1..40b5515829 100644
--- a/qpid/cpp/src/qpid/broker/Message.cpp
+++ b/qpid/cpp/src/qpid/broker/Message.cpp
@@ -160,6 +160,7 @@ void Message::decodeContent(framing::Buffer& buffer)
//body on a frame then add that frame to the frameset
AMQFrame frame((AMQContentBody()));
frame.castBody<AMQContentBody>()->decode(buffer, buffer.available());
+ frame.setFirstSegment(false);
frames.append(frame);
} else {
//adjust header flags
@@ -382,4 +383,9 @@ void Message::resetEnqueueCompleteCallback() { enqueueCallback = 0; }
void Message::setDequeueCompleteCallback(MessageCallback& cb) { dequeueCallback = &cb; }
void Message::resetDequeueCompleteCallback() { dequeueCallback = 0; }
+framing::FieldTable& Message::getOrInsertHeaders()
+{
+ return getProperties<MessageProperties>()->getApplicationHeaders();
+}
+
}} // namespace qpid::broker
diff --git a/qpid/cpp/src/qpid/broker/Message.h b/qpid/cpp/src/qpid/broker/Message.h
index 96fcf61dfc..458c6c7d1a 100644
--- a/qpid/cpp/src/qpid/broker/Message.h
+++ b/qpid/cpp/src/qpid/broker/Message.h
@@ -22,6 +22,7 @@
*
*/
+#include "BrokerImportExport.h"
#include "PersistableMessage.h"
#include "MessageAdapter.h"
#include "qpid/framing/amqp_types.h"
@@ -51,8 +52,8 @@ class Message : public PersistableMessage {
public:
typedef boost::function<void (const boost::intrusive_ptr<Message>&)> MessageCallback;
- Message(const framing::SequenceNumber& id = framing::SequenceNumber());
- ~Message();
+ QPID_BROKER_EXTERN Message(const framing::SequenceNumber& id = framing::SequenceNumber());
+ QPID_BROKER_EXTERN ~Message();
uint64_t getPersistenceId() const { return persistenceId; }
void setPersistenceId(uint64_t _persistenceId) const { persistenceId = _persistenceId; }
@@ -65,17 +66,18 @@ public:
const framing::SequenceNumber& getCommandId() { return frames.getId(); }
- uint64_t contentSize() const;
+ QPID_BROKER_EXTERN uint64_t contentSize() const;
- std::string getRoutingKey() const;
+ QPID_BROKER_EXTERN std::string getRoutingKey() const;
const boost::shared_ptr<Exchange> getExchange(ExchangeRegistry&) const;
- std::string getExchangeName() const;
+ QPID_BROKER_EXTERN std::string getExchangeName() const;
bool isImmediate() const;
- const framing::FieldTable* getApplicationHeaders() const;
- bool isPersistent();
+ QPID_BROKER_EXTERN const framing::FieldTable* getApplicationHeaders() const;
+ framing::FieldTable& getOrInsertHeaders();
+ QPID_BROKER_EXTERN bool isPersistent();
bool requiresAccept();
- void setTimestamp(const boost::intrusive_ptr<ExpiryPolicy>& e);
+ QPID_BROKER_EXTERN void setTimestamp(const boost::intrusive_ptr<ExpiryPolicy>& e);
void setExpiryPolicy(const boost::intrusive_ptr<ExpiryPolicy>& e);
bool hasExpired();
sys::AbsTime getExpiration() const { return expiration; }
@@ -124,8 +126,8 @@ public:
uint32_t encodedHeaderSize() const;
uint32_t encodedContentSize() const;
- void decodeHeader(framing::Buffer& buffer);
- void decodeContent(framing::Buffer& buffer);
+ QPID_BROKER_EXTERN void decodeHeader(framing::Buffer& buffer);
+ QPID_BROKER_EXTERN void decodeContent(framing::Buffer& buffer);
/**
* Releases the in-memory content data held by this
@@ -139,7 +141,7 @@ public:
void sendContent(const Queue& queue, framing::FrameHandler& out, uint16_t maxFrameSize) const;
void sendHeader(framing::FrameHandler& out, uint16_t maxFrameSize) const;
- bool isContentLoaded() const;
+ QPID_BROKER_EXTERN bool isContentLoaded() const;
bool isExcluded(const std::vector<std::string>& excludes) const;
void addTraceId(const std::string& id);
diff --git a/qpid/cpp/src/qpid/broker/MessageBuilder.h b/qpid/cpp/src/qpid/broker/MessageBuilder.h
index 395de024ab..1f5a2a8b84 100644
--- a/qpid/cpp/src/qpid/broker/MessageBuilder.h
+++ b/qpid/cpp/src/qpid/broker/MessageBuilder.h
@@ -21,6 +21,7 @@
#ifndef _MessageBuilder_
#define _MessageBuilder_
+#include "BrokerImportExport.h"
#include "qpid/framing/FrameHandler.h"
#include "qpid/framing/SequenceNumber.h"
#include "qpid/RefCounted.h"
@@ -34,10 +35,11 @@ namespace qpid {
class MessageBuilder : public framing::FrameHandler{
public:
- MessageBuilder(MessageStore* const store, uint64_t stagingThreshold);
- void handle(framing::AMQFrame& frame);
+ QPID_BROKER_EXTERN MessageBuilder(MessageStore* const store,
+ uint64_t stagingThreshold);
+ QPID_BROKER_EXTERN void handle(framing::AMQFrame& frame);
boost::intrusive_ptr<Message> getMessage() { return message; }
- void start(const framing::SequenceNumber& id);
+ QPID_BROKER_EXTERN void start(const framing::SequenceNumber& id);
void end();
private:
enum State {DORMANT, METHOD, HEADER, CONTENT};
diff --git a/qpid/cpp/src/qpid/broker/NullMessageStore.h b/qpid/cpp/src/qpid/broker/NullMessageStore.h
index d99c751d26..a44f8d2804 100644
--- a/qpid/cpp/src/qpid/broker/NullMessageStore.h
+++ b/qpid/cpp/src/qpid/broker/NullMessageStore.h
@@ -22,6 +22,7 @@
#define _NullMessageStore_
#include <set>
+#include "BrokerImportExport.h"
#include "MessageStore.h"
#include "Queue.h"
@@ -38,46 +39,54 @@ class NullMessageStore : public MessageStore
std::set<std::string> prepared;
uint64_t nextPersistenceId;
public:
- NullMessageStore();
+ QPID_BROKER_EXTERN NullMessageStore();
- virtual bool init(const Options* options);
- virtual std::auto_ptr<TransactionContext> begin();
- virtual std::auto_ptr<TPCTransactionContext> begin(const std::string& xid);
- virtual void prepare(TPCTransactionContext& txn);
- virtual void commit(TransactionContext& txn);
- virtual void abort(TransactionContext& txn);
- virtual void collectPreparedXids(std::set<std::string>& xids);
+ QPID_BROKER_EXTERN virtual bool init(const Options* options);
+ QPID_BROKER_EXTERN virtual std::auto_ptr<TransactionContext> begin();
+ QPID_BROKER_EXTERN virtual std::auto_ptr<TPCTransactionContext> begin(const std::string& xid);
+ QPID_BROKER_EXTERN virtual void prepare(TPCTransactionContext& txn);
+ QPID_BROKER_EXTERN virtual void commit(TransactionContext& txn);
+ QPID_BROKER_EXTERN virtual void abort(TransactionContext& txn);
+ QPID_BROKER_EXTERN virtual void collectPreparedXids(std::set<std::string>& xids);
- virtual void create(PersistableQueue& queue, const framing::FieldTable& args);
- virtual void destroy(PersistableQueue& queue);
- virtual void create(const PersistableExchange& exchange, const framing::FieldTable& args);
- virtual void destroy(const PersistableExchange& exchange);
+ QPID_BROKER_EXTERN virtual void create(PersistableQueue& queue,
+ const framing::FieldTable& args);
+ QPID_BROKER_EXTERN virtual void destroy(PersistableQueue& queue);
+ QPID_BROKER_EXTERN virtual void create(const PersistableExchange& exchange,
+ const framing::FieldTable& args);
+ QPID_BROKER_EXTERN virtual void destroy(const PersistableExchange& exchange);
- virtual void bind(const PersistableExchange& exchange, const PersistableQueue& queue,
- const std::string& key, const framing::FieldTable& args);
- virtual void unbind(const PersistableExchange& exchange, const PersistableQueue& queue,
- const std::string& key, const framing::FieldTable& args);
- virtual void create(const PersistableConfig& config);
- virtual void destroy(const PersistableConfig& config);
- virtual void recover(RecoveryManager& queues);
- virtual void stage(const boost::intrusive_ptr<PersistableMessage>& msg);
- virtual void destroy(PersistableMessage& msg);
- virtual void appendContent(const boost::intrusive_ptr<const PersistableMessage>& msg,
- const std::string& data);
- virtual void loadContent(const qpid::broker::PersistableQueue& queue,
- const boost::intrusive_ptr<const PersistableMessage>& msg, std::string& data,
- uint64_t offset, uint32_t length);
- virtual void enqueue(TransactionContext* ctxt,
- const boost::intrusive_ptr<PersistableMessage>& msg,
- const PersistableQueue& queue);
- virtual void dequeue(TransactionContext* ctxt,
- const boost::intrusive_ptr<PersistableMessage>& msg,
- const PersistableQueue& queue);
- virtual uint32_t outstandingQueueAIO(const PersistableQueue& queue);
- virtual void flush(const qpid::broker::PersistableQueue& queue);
+ QPID_BROKER_EXTERN virtual void bind(const PersistableExchange& exchange,
+ const PersistableQueue& queue,
+ const std::string& key,
+ const framing::FieldTable& args);
+ QPID_BROKER_EXTERN virtual void unbind(const PersistableExchange& exchange,
+ const PersistableQueue& queue,
+ const std::string& key,
+ const framing::FieldTable& args);
+ QPID_BROKER_EXTERN virtual void create(const PersistableConfig& config);
+ QPID_BROKER_EXTERN virtual void destroy(const PersistableConfig& config);
+ QPID_BROKER_EXTERN virtual void recover(RecoveryManager& queues);
+ QPID_BROKER_EXTERN virtual void stage(const boost::intrusive_ptr<PersistableMessage>& msg);
+ QPID_BROKER_EXTERN virtual void destroy(PersistableMessage& msg);
+ QPID_BROKER_EXTERN virtual void appendContent(const boost::intrusive_ptr<const PersistableMessage>& msg,
+ const std::string& data);
+ QPID_BROKER_EXTERN virtual void loadContent(const qpid::broker::PersistableQueue& queue,
+ const boost::intrusive_ptr<const PersistableMessage>& msg,
+ std::string& data,
+ uint64_t offset,
+ uint32_t length);
+ QPID_BROKER_EXTERN virtual void enqueue(TransactionContext* ctxt,
+ const boost::intrusive_ptr<PersistableMessage>& msg,
+ const PersistableQueue& queue);
+ QPID_BROKER_EXTERN virtual void dequeue(TransactionContext* ctxt,
+ const boost::intrusive_ptr<PersistableMessage>& msg,
+ const PersistableQueue& queue);
+ QPID_BROKER_EXTERN virtual uint32_t outstandingQueueAIO(const PersistableQueue& queue);
+ QPID_BROKER_EXTERN virtual void flush(const qpid::broker::PersistableQueue& queue);
~NullMessageStore(){}
- virtual bool isNull() const;
+ QPID_BROKER_EXTERN virtual bool isNull() const;
static bool isNullStore(const MessageStore*);
};
diff --git a/qpid/cpp/src/qpid/broker/PersistableMessage.h b/qpid/cpp/src/qpid/broker/PersistableMessage.h
index 4f2e3abafa..92f89ba578 100644
--- a/qpid/cpp/src/qpid/broker/PersistableMessage.h
+++ b/qpid/cpp/src/qpid/broker/PersistableMessage.h
@@ -26,6 +26,7 @@
#include <list>
#include <boost/shared_ptr.hpp>
#include <boost/weak_ptr.hpp>
+#include "BrokerImportExport.h"
#include "Persistable.h"
#include "qpid/framing/amqp_types.h"
#include "qpid/sys/Mutex.h"
@@ -93,21 +94,23 @@ class PersistableMessage : public Persistable
bool isContentReleased() const;
- bool isEnqueueComplete();
+ QPID_BROKER_EXTERN bool isEnqueueComplete();
- void enqueueComplete();
+ QPID_BROKER_EXTERN void enqueueComplete();
- void enqueueAsync(PersistableQueue::shared_ptr queue, MessageStore* _store);
+ QPID_BROKER_EXTERN void enqueueAsync(PersistableQueue::shared_ptr queue,
+ MessageStore* _store);
- void enqueueAsync();
+ QPID_BROKER_EXTERN void enqueueAsync();
- bool isDequeueComplete();
+ QPID_BROKER_EXTERN bool isDequeueComplete();
- void dequeueComplete();
+ QPID_BROKER_EXTERN void dequeueComplete();
- void dequeueAsync(PersistableQueue::shared_ptr queue, MessageStore* _store);
+ QPID_BROKER_EXTERN void dequeueAsync(PersistableQueue::shared_ptr queue,
+ MessageStore* _store);
- void dequeueAsync();
+ QPID_BROKER_EXTERN void dequeueAsync();
};
}}
diff --git a/qpid/cpp/src/qpid/broker/Queue.cpp b/qpid/cpp/src/qpid/broker/Queue.cpp
index 3ae53c8ea9..aa0cd8ca31 100644
--- a/qpid/cpp/src/qpid/broker/Queue.cpp
+++ b/qpid/cpp/src/qpid/broker/Queue.cpp
@@ -32,6 +32,7 @@
#include "qpid/log/Statement.h"
#include "qpid/management/ManagementBroker.h"
#include "qpid/framing/reply_exceptions.h"
+#include "qpid/framing/FieldTable.h"
#include "qpid/sys/Monitor.h"
#include "qpid/sys/Time.h"
#include "qmf/org/apache/qpid/broker/ArgsQueuePurge.h"
@@ -68,6 +69,9 @@ const std::string qpidLastValueQueueNoBrowse("qpid.last_value_queue_no_browse");
const std::string qpidPersistLastNode("qpid.persist_last_node");
const std::string qpidVQMatchProperty("qpid.LVQ_key");
const std::string qpidQueueEventGeneration("qpid.queue_event_generation");
+//following feature is not ready for general use as it doesn't handle
+//the case where a message is enqueued on more than one queue well enough:
+const std::string qpidInsertSequenceNumbers("qpid.insert_sequence_numbers");
const int ENQUEUE_ONLY=1;
const int ENQUEUE_AND_DEQUEUE=2;
@@ -93,7 +97,8 @@ Queue::Queue(const string& _name, bool _autodelete,
policyExceeded(false),
mgmtObject(0),
eventMode(0),
- eventMgr(0)
+ eventMgr(0),
+ insertSeqNo(0)
{
if (parent != 0)
{
@@ -176,7 +181,7 @@ void Queue::deliver(boost::intrusive_ptr<Message>& msg){
void Queue::recover(boost::intrusive_ptr<Message>& msg){
- push(msg);
+ push(msg, true);
msg->enqueueComplete(); // mark the message as enqueued
mgntEnqStats(msg);
@@ -545,12 +550,13 @@ void Queue::popMsg(QueuedMessage& qmsg)
++dequeueTracker;
}
-void Queue::push(boost::intrusive_ptr<Message>& msg){
+void Queue::push(boost::intrusive_ptr<Message>& msg, bool isRecovery){
QueueListeners::NotificationSet copy;
{
Mutex::ScopedLock locker(messageLock);
QueuedMessage qm(this, msg, ++sequence);
if (policy.get()) policy->tryEnqueue(qm);
+ if (insertSeqNo) msg->getOrInsertHeaders().setInt64(seqNoKey, sequence);
LVQ::iterator i;
const framing::FieldTable* ft = msg->getApplicationHeaders();
@@ -566,14 +572,21 @@ void Queue::push(boost::intrusive_ptr<Message>& msg){
boost::intrusive_ptr<Message> old = i->second->getReplacementMessage(this);
if (!old) old = i->second;
i->second->setReplacementMessage(msg,this);
- dequeued(QueuedMessage(qm.queue, old, qm.position));
+ if (isRecovery) {
+ //can't issue new requests for the store until
+ //recovery is complete
+ pendingDequeues.push_back(QueuedMessage(qm.queue, old, qm.position));
+ } else {
+ dequeue(0, QueuedMessage(qm.queue, old, qm.position));
+ }
}
}else {
messages.push_back(qm);
listeners.populate(copy);
}
- if (eventMode && eventMgr) {
- eventMgr->enqueued(qm);
+ if (eventMode) {
+ if (eventMgr) eventMgr->enqueued(qm);
+ else QPID_LOG(warning, "Enqueue manager not set, events not generated for " << getName());
}
}
copy.notify();
@@ -664,7 +677,7 @@ bool Queue::enqueue(TransactionContext* ctxt, boost::intrusive_ptr<Message> msg)
msg->addTraceId(traceId);
}
- if (msg->isPersistent() && store && !lastValueQueue) {
+ if (msg->isPersistent() && store) {
msg->enqueueAsync(shared_from_this(), store); //increment to async counter -- for message sent to more than one queue
boost::intrusive_ptr<PersistableMessage> pmsg = boost::static_pointer_cast<PersistableMessage>(msg);
store->enqueue(ctxt, pmsg, *this);
@@ -676,14 +689,14 @@ bool Queue::enqueue(TransactionContext* ctxt, boost::intrusive_ptr<Message> msg)
// return true if store exists,
bool Queue::dequeue(TransactionContext* ctxt, const QueuedMessage& msg)
{
- if (policy.get() && !policy->isEnqueued(msg)) return false;
{
Mutex::ScopedLock locker(messageLock);
+ if (policy.get() && !policy->isEnqueued(msg)) return false;
if (!ctxt) {
dequeued(msg);
}
}
- if (msg.payload->isPersistent() && store && !lastValueQueue) {
+ if (msg.payload->isPersistent() && store) {
msg.payload->dequeueAsync(shared_from_this(), store); //increment to async counter -- for message sent to more than one queue
boost::intrusive_ptr<PersistableMessage> pmsg = boost::static_pointer_cast<PersistableMessage>(msg.payload);
store->dequeue(ctxt, pmsg, *this);
@@ -765,6 +778,9 @@ void Queue::configure(const FieldTable& _settings, bool recovering)
eventMode = _settings.getAsInt(qpidQueueEventGeneration);
+ FieldTable::ValuePtr p =_settings.get(qpidInsertSequenceNumbers);
+ if (p && p->convertsTo<std::string>()) insertSequenceNumbers(p->get<std::string>());
+
if (mgmtObject != 0)
mgmtObject->set_arguments (_settings);
@@ -976,3 +992,17 @@ void Queue::setQueueEventManager(QueueEvents& mgr)
{
eventMgr = &mgr;
}
+
+void Queue::recoveryComplete()
+{
+ //process any pending dequeues
+ for_each(pendingDequeues.begin(), pendingDequeues.end(), boost::bind(&Queue::dequeue, this, (TransactionContext*) 0, _1));
+ pendingDequeues.clear();
+}
+
+void Queue::insertSequenceNumbers(const std::string& key)
+{
+ seqNoKey = key;
+ insertSeqNo = !seqNoKey.empty();
+ QPID_LOG(debug, "Inserting sequence numbers as " << key);
+}
diff --git a/qpid/cpp/src/qpid/broker/Queue.h b/qpid/cpp/src/qpid/broker/Queue.h
index 14849b3c8e..d1f71581d6 100644
--- a/qpid/cpp/src/qpid/broker/Queue.h
+++ b/qpid/cpp/src/qpid/broker/Queue.h
@@ -21,6 +21,8 @@
* under the License.
*
*/
+
+#include "BrokerImportExport.h"
#include "OwnershipToken.h"
#include "Consumer.h"
#include "Message.h"
@@ -85,6 +87,7 @@ namespace qpid {
std::vector<std::string> traceExclude;
QueueListeners listeners;
Messages messages;
+ Messages pendingDequeues;//used to avoid dequeuing during recovery
LVQ lvq;
mutable qpid::sys::Mutex consumerLock;
mutable qpid::sys::Mutex messageLock;
@@ -100,8 +103,10 @@ namespace qpid {
RateTracker dequeueTracker;
int eventMode;
QueueEvents* eventMgr;
+ bool insertSeqNo;
+ std::string seqNoKey;
- void push(boost::intrusive_ptr<Message>& msg);
+ void push(boost::intrusive_ptr<Message>& msg, bool isRecovery=false);
void setPolicy(std::auto_ptr<QueuePolicy> policy);
bool seek(QueuedMessage& msg, Consumer::shared_ptr position);
bool getNextMessage(QueuedMessage& msg, Consumer::shared_ptr c);
@@ -149,13 +154,14 @@ namespace qpid {
typedef std::vector<shared_ptr> vector;
- Queue(const string& name, bool autodelete = false,
- MessageStore* const store = 0,
- const OwnershipToken* const owner = 0,
- management::Manageable* parent = 0);
- ~Queue();
+ QPID_BROKER_EXTERN Queue(const string& name,
+ bool autodelete = false,
+ MessageStore* const store = 0,
+ const OwnershipToken* const owner = 0,
+ management::Manageable* parent = 0);
+ QPID_BROKER_EXTERN ~Queue();
- bool dispatch(Consumer::shared_ptr);
+ QPID_BROKER_EXTERN bool dispatch(Consumer::shared_ptr);
/**
* Check whether there would be a message available for
* dispatch to this consumer. If not, the consumer will be
@@ -167,24 +173,28 @@ namespace qpid {
void create(const qpid::framing::FieldTable& settings);
// "recovering" means we are doing a MessageStore recovery.
- void configure(const qpid::framing::FieldTable& settings, bool recovering = false);
+ QPID_BROKER_EXTERN void configure(const qpid::framing::FieldTable& settings,
+ bool recovering = false);
void destroy();
- void bound(const string& exchange, const string& key, const qpid::framing::FieldTable& args);
- void unbind(ExchangeRegistry& exchanges, Queue::shared_ptr shared_ref);
+ QPID_BROKER_EXTERN void bound(const string& exchange,
+ const string& key,
+ const qpid::framing::FieldTable& args);
+ QPID_BROKER_EXTERN void unbind(ExchangeRegistry& exchanges,
+ Queue::shared_ptr shared_ref);
- bool acquire(const QueuedMessage& msg);
+ QPID_BROKER_EXTERN bool acquire(const QueuedMessage& msg);
bool acquireMessageAt(const qpid::framing::SequenceNumber& position, QueuedMessage& message);
/**
* Delivers a message to the queue. Will record it as
* enqueued if persistent then process it.
*/
- void deliver(boost::intrusive_ptr<Message>& msg);
+ QPID_BROKER_EXTERN void deliver(boost::intrusive_ptr<Message>& msg);
/**
* Dispatches the messages immediately to a consumer if
* one is available or stores it for later if not.
*/
- void process(boost::intrusive_ptr<Message>& msg);
+ QPID_BROKER_EXTERN void process(boost::intrusive_ptr<Message>& msg);
/**
* Returns a message to the in-memory queue (due to lack
* of acknowledegement from a receiver). If a consumer is
@@ -197,17 +207,18 @@ namespace qpid {
*/
void recover(boost::intrusive_ptr<Message>& msg);
- void consume(Consumer::shared_ptr c, bool exclusive = false);
- void cancel(Consumer::shared_ptr c);
+ QPID_BROKER_EXTERN void consume(Consumer::shared_ptr c,
+ bool exclusive = false);
+ QPID_BROKER_EXTERN void cancel(Consumer::shared_ptr c);
uint32_t purge(const uint32_t purge_request = 0); //defaults to all messages
- void purgeExpired();
+ QPID_BROKER_EXTERN void purgeExpired();
//move qty # of messages to destination Queue destq
uint32_t move(const Queue::shared_ptr destq, uint32_t qty);
- uint32_t getMessageCount() const;
- uint32_t getConsumerCount() const;
+ QPID_BROKER_EXTERN uint32_t getMessageCount() const;
+ QPID_BROKER_EXTERN uint32_t getConsumerCount() const;
inline const string& getName() const { return name; }
bool isExclusiveOwner(const OwnershipToken* const o) const;
void releaseExclusiveOwnership();
@@ -223,8 +234,8 @@ namespace qpid {
/**
* used to take messages from in memory and flush down to disk.
*/
- void setLastNodeFailure();
- void clearLastNodeFailure();
+ QPID_BROKER_EXTERN void setLastNodeFailure();
+ QPID_BROKER_EXTERN void clearLastNodeFailure();
bool enqueue(TransactionContext* ctxt, boost::intrusive_ptr<Message> msg);
/**
@@ -240,7 +251,7 @@ namespace qpid {
/**
* Gets the next available message
*/
- QueuedMessage get();
+ QPID_BROKER_EXTERN QueuedMessage get();
/** Get the message at position pos */
QueuedMessage find(framing::SequenceNumber pos) const;
@@ -290,6 +301,11 @@ namespace qpid {
void setPosition(framing::SequenceNumber pos);
int getEventMode();
void setQueueEventManager(QueueEvents&);
+ void insertSequenceNumbers(const std::string& key);
+ /**
+ * Notify queue that recovery has completed.
+ */
+ void recoveryComplete();
};
}
}
diff --git a/qpid/cpp/src/qpid/broker/QueueCleaner.h b/qpid/cpp/src/qpid/broker/QueueCleaner.h
index 7903266f5f..007826f33e 100644
--- a/qpid/cpp/src/qpid/broker/QueueCleaner.h
+++ b/qpid/cpp/src/qpid/broker/QueueCleaner.h
@@ -22,6 +22,7 @@
*
*/
+#include "BrokerImportExport.h"
#include "Timer.h"
namespace qpid {
@@ -34,8 +35,8 @@ class QueueRegistry;
class QueueCleaner
{
public:
- QueueCleaner(QueueRegistry& queues, Timer& timer);
- void start(qpid::sys::Duration period);
+ QPID_BROKER_EXTERN QueueCleaner(QueueRegistry& queues, Timer& timer);
+ QPID_BROKER_EXTERN void start(qpid::sys::Duration period);
private:
class Task : public TimerTask
{
diff --git a/qpid/cpp/src/qpid/broker/QueueEvents.cpp b/qpid/cpp/src/qpid/broker/QueueEvents.cpp
index a6517e1bfe..7525e4cb76 100644
--- a/qpid/cpp/src/qpid/broker/QueueEvents.cpp
+++ b/qpid/cpp/src/qpid/broker/QueueEvents.cpp
@@ -20,12 +20,13 @@
*/
#include "QueueEvents.h"
#include "qpid/Exception.h"
+#include "qpid/log/Statement.h"
namespace qpid {
namespace broker {
QueueEvents::QueueEvents(const boost::shared_ptr<sys::Poller>& poller) :
- eventQueue(boost::bind(&QueueEvents::handle, this, _1), poller)
+ eventQueue(boost::bind(&QueueEvents::handle, this, _1), poller), enabled(true)
{
eventQueue.start();
}
@@ -37,12 +38,12 @@ QueueEvents::~QueueEvents()
void QueueEvents::enqueued(const QueuedMessage& m)
{
- eventQueue.push(Event(ENQUEUE, m));
+ if (enabled) eventQueue.push(Event(ENQUEUE, m));
}
void QueueEvents::dequeued(const QueuedMessage& m)
{
- eventQueue.push(Event(DEQUEUE, m));
+ if (enabled) eventQueue.push(Event(DEQUEUE, m));
}
void QueueEvents::registerListener(const std::string& id, const EventListener& listener)
@@ -81,6 +82,18 @@ void QueueEvents::shutdown()
if (!eventQueue.empty() && !listeners.empty()) eventQueue.shutdown();
}
+void QueueEvents::enable()
+{
+ enabled = true;
+ QPID_LOG(debug, "Queue events enabled");
+}
+
+void QueueEvents::disable()
+{
+ enabled = false;
+ QPID_LOG(debug, "Queue events disabled");
+}
+
QueueEvents::Event::Event(EventType t, const QueuedMessage& m) : type(t), msg(m) {}
diff --git a/qpid/cpp/src/qpid/broker/QueueEvents.h b/qpid/cpp/src/qpid/broker/QueueEvents.h
index 2ba69e33e6..82abd3d20a 100644
--- a/qpid/cpp/src/qpid/broker/QueueEvents.h
+++ b/qpid/cpp/src/qpid/broker/QueueEvents.h
@@ -22,6 +22,7 @@
*
*/
+#include "BrokerImportExport.h"
#include "QueuedMessage.h"
#include "qpid/sys/Mutex.h"
#include "qpid/sys/PollableQueue.h"
@@ -48,25 +49,29 @@ class QueueEvents
EventType type;
QueuedMessage msg;
- Event(EventType, const QueuedMessage&);
+ QPID_BROKER_EXTERN Event(EventType, const QueuedMessage&);
};
typedef boost::function<void (Event)> EventListener;
- QueueEvents(const boost::shared_ptr<sys::Poller>& poller);
- ~QueueEvents();
- void enqueued(const QueuedMessage&);
- void dequeued(const QueuedMessage&);
- void registerListener(const std::string& id, const EventListener&);
- void unregisterListener(const std::string& id);
+ QPID_BROKER_EXTERN QueueEvents(const boost::shared_ptr<sys::Poller>& poller);
+ QPID_BROKER_EXTERN ~QueueEvents();
+ QPID_BROKER_EXTERN void enqueued(const QueuedMessage&);
+ QPID_BROKER_EXTERN void dequeued(const QueuedMessage&);
+ QPID_BROKER_EXTERN void registerListener(const std::string& id,
+ const EventListener&);
+ QPID_BROKER_EXTERN void unregisterListener(const std::string& id);
+ void enable();
+ void disable();
//process all outstanding events
- void shutdown();
+ QPID_BROKER_EXTERN void shutdown();
private:
typedef qpid::sys::PollableQueue<Event> EventQueue;
typedef std::map<std::string, EventListener> Listeners;
EventQueue eventQueue;
Listeners listeners;
+ volatile bool enabled;
qpid::sys::Mutex lock;//protect listeners from concurrent access
void handle(EventQueue::Queue& e);
diff --git a/qpid/cpp/src/qpid/broker/QueuePolicy.cpp b/qpid/cpp/src/qpid/broker/QueuePolicy.cpp
index 41a6709d27..c59736969f 100644
--- a/qpid/cpp/src/qpid/broker/QueuePolicy.cpp
+++ b/qpid/cpp/src/qpid/broker/QueuePolicy.cpp
@@ -126,7 +126,7 @@ std::string QueuePolicy::getType(const FieldTable& settings)
FieldTable::ValuePtr v = settings.get(typeKey);
if (v && v->convertsTo<std::string>()) {
std::string t = v->get<std::string>();
- transform(t.begin(), t.end(), t.begin(), tolower);
+ std::transform(t.begin(), t.end(), t.begin(), tolower);
if (t == REJECT || t == FLOW_TO_DISK || t == RING || t == RING_STRICT) return t;
}
return FLOW_TO_DISK;
@@ -197,11 +197,12 @@ void RingQueuePolicy::enqueued(const QueuedMessage& m)
void RingQueuePolicy::dequeued(const QueuedMessage& m)
{
qpid::sys::Mutex::ScopedLock l(lock);
- QueuePolicy::dequeued(m);
//find and remove m from queue
- for (Messages::iterator i = queue.begin(); i != queue.end() && m.position <= i->position; i++) {
- if (i->position == m.position) {
+ for (Messages::iterator i = queue.begin(); i != queue.end(); i++) {
+ if (i->payload == m.payload) {
queue.erase(i);
+ //now update count and size
+ QueuePolicy::dequeued(m);
break;
}
}
@@ -210,9 +211,11 @@ void RingQueuePolicy::dequeued(const QueuedMessage& m)
bool RingQueuePolicy::isEnqueued(const QueuedMessage& m)
{
qpid::sys::Mutex::ScopedLock l(lock);
- //for non-strict ring policy, a message can be dequeued before acked; need to detect this
- for (Messages::iterator i = queue.begin(); i != queue.end() && m.position <= i->position; i++) {
- if (i->position == m.position) {
+ //for non-strict ring policy, a message can be replaced (and
+ //therefore dequeued) before it is accepted or released by
+ //subscriber; need to detect this
+ for (Messages::const_iterator i = queue.begin(); i != queue.end(); i++) {
+ if (i->payload == m.payload) {
return true;
}
}
@@ -236,13 +239,10 @@ bool RingQueuePolicy::checkLimit(const QueuedMessage& m)
oldest = queue.front();
}
if (oldest.queue->acquire(oldest) || !strict) {
- qpid::sys::Mutex::ScopedLock l(lock);
- if (oldest.position == queue.front().position) {
- queue.pop_front();
- QPID_LOG(debug, "Ring policy triggered in queue "
- << (m.queue ? m.queue->getName() : std::string("unknown queue"))
- << ": removed message " << oldest.position << " to make way for " << m.position);
- }
+ oldest.queue->dequeue(0, oldest);
+ QPID_LOG(debug, "Ring policy triggered in queue "
+ << (m.queue ? m.queue->getName() : std::string("unknown queue"))
+ << ": removed message " << oldest.position << " to make way for " << m.position);
return true;
} else {
QPID_LOG(debug, "Ring policy could not be triggered in queue "
diff --git a/qpid/cpp/src/qpid/broker/QueuePolicy.h b/qpid/cpp/src/qpid/broker/QueuePolicy.h
index 0e8c15aa0e..45992f87ac 100644
--- a/qpid/cpp/src/qpid/broker/QueuePolicy.h
+++ b/qpid/cpp/src/qpid/broker/QueuePolicy.h
@@ -24,6 +24,7 @@
#include <deque>
#include <iostream>
#include <memory>
+#include "BrokerImportExport.h"
#include "QueuedMessage.h"
#include "qpid/framing/FieldTable.h"
#include "qpid/sys/AtomicValue.h"
@@ -47,20 +48,20 @@ class QueuePolicy
static std::string getType(const qpid::framing::FieldTable& settings);
public:
- static const std::string maxCountKey;
- static const std::string maxSizeKey;
- static const std::string typeKey;
- static const std::string REJECT;
- static const std::string FLOW_TO_DISK;
- static const std::string RING;
- static const std::string RING_STRICT;
+ static QPID_BROKER_EXTERN const std::string maxCountKey;
+ static QPID_BROKER_EXTERN const std::string maxSizeKey;
+ static QPID_BROKER_EXTERN const std::string typeKey;
+ static QPID_BROKER_EXTERN const std::string REJECT;
+ static QPID_BROKER_EXTERN const std::string FLOW_TO_DISK;
+ static QPID_BROKER_EXTERN const std::string RING;
+ static QPID_BROKER_EXTERN const std::string RING_STRICT;
virtual ~QueuePolicy() {}
- void tryEnqueue(const QueuedMessage&);
+ QPID_BROKER_EXTERN void tryEnqueue(const QueuedMessage&);
virtual void dequeued(const QueuedMessage&);
virtual bool isEnqueued(const QueuedMessage&);
virtual bool checkLimit(const QueuedMessage&);
- void update(qpid::framing::FieldTable& settings);
+ QPID_BROKER_EXTERN void update(qpid::framing::FieldTable& settings);
uint32_t getMaxCount() const { return maxCount; }
uint64_t getMaxSize() const { return maxSize; }
void encode(framing::Buffer& buffer) const;
@@ -68,10 +69,11 @@ class QueuePolicy
uint32_t encodedSize() const;
- static std::auto_ptr<QueuePolicy> createQueuePolicy(const qpid::framing::FieldTable& settings);
- static std::auto_ptr<QueuePolicy> createQueuePolicy(uint32_t maxCount, uint64_t maxSize, const std::string& type = REJECT);
+ static QPID_BROKER_EXTERN std::auto_ptr<QueuePolicy> createQueuePolicy(const qpid::framing::FieldTable& settings);
+ static QPID_BROKER_EXTERN std::auto_ptr<QueuePolicy> createQueuePolicy(uint32_t maxCount, uint64_t maxSize, const std::string& type = REJECT);
static void setDefaultMaxSize(uint64_t);
- friend std::ostream& operator<<(std::ostream&, const QueuePolicy&);
+ friend QPID_BROKER_EXTERN std::ostream& operator<<(std::ostream&,
+ const QueuePolicy&);
protected:
QueuePolicy(uint32_t maxCount, uint64_t maxSize, const std::string& type = REJECT);
diff --git a/qpid/cpp/src/qpid/broker/QueueRegistry.cpp b/qpid/cpp/src/qpid/broker/QueueRegistry.cpp
index 2cb801bf83..d079e543c4 100644
--- a/qpid/cpp/src/qpid/broker/QueueRegistry.cpp
+++ b/qpid/cpp/src/qpid/broker/QueueRegistry.cpp
@@ -19,6 +19,7 @@
*
*/
#include "QueueRegistry.h"
+#include "QueueEvents.h"
#include "qpid/log/Statement.h"
#include <sstream>
#include <assert.h>
@@ -27,7 +28,7 @@ using namespace qpid::broker;
using namespace qpid::sys;
QueueRegistry::QueueRegistry() :
- counter(1), store(0), parent(0), lastNode(false) {}
+ counter(1), store(0), events(0), parent(0), lastNode(false) {}
QueueRegistry::~QueueRegistry(){}
@@ -43,7 +44,8 @@ QueueRegistry::declare(const string& declareName, bool durable,
if (i == queues.end()) {
Queue::shared_ptr queue(new Queue(name, autoDelete, durable ? store : 0, owner, parent));
queues[name] = queue;
- if (lastNode) queue->setLastNodeFailure();
+ if (lastNode) queue->setLastNodeFailure();
+ if (events) queue->setQueueEventManager(*events);
return std::pair<Queue::shared_ptr, bool>(queue, true);
} else {
@@ -105,3 +107,7 @@ void QueueRegistry::updateQueueClusterState(bool _lastNode)
lastNode = _lastNode;
}
+void QueueRegistry::setQueueEvents(QueueEvents* e)
+{
+ events = e;
+}
diff --git a/qpid/cpp/src/qpid/broker/QueueRegistry.h b/qpid/cpp/src/qpid/broker/QueueRegistry.h
index c53ba668cc..3c02afedc4 100644
--- a/qpid/cpp/src/qpid/broker/QueueRegistry.h
+++ b/qpid/cpp/src/qpid/broker/QueueRegistry.h
@@ -21,6 +21,7 @@
#ifndef _QueueRegistry_
#define _QueueRegistry_
+#include "BrokerImportExport.h"
#include "Queue.h"
#include "qpid/sys/Mutex.h"
#include "qpid/management/Manageable.h"
@@ -31,6 +32,8 @@
namespace qpid {
namespace broker {
+class QueueEvents;
+
/**
* A registry of queues indexed by queue name.
*
@@ -38,10 +41,10 @@ namespace broker {
* are deleted when and only when they are no longer in use.
*
*/
-class QueueRegistry{
+class QueueRegistry {
public:
- QueueRegistry();
- ~QueueRegistry();
+ QPID_BROKER_EXTERN QueueRegistry();
+ QPID_BROKER_EXTERN ~QueueRegistry();
/**
* Declare a queue.
@@ -49,8 +52,11 @@ class QueueRegistry{
* @return The queue and a boolean flag which is true if the queue
* was created by this declare call false if it already existed.
*/
- std::pair<Queue::shared_ptr, bool> declare(const string& name, bool durable = false, bool autodelete = false,
- const OwnershipToken* owner = 0);
+ QPID_BROKER_EXTERN std::pair<Queue::shared_ptr, bool> declare
+ (const string& name,
+ bool durable = false,
+ bool autodelete = false,
+ const OwnershipToken* owner = 0);
/**
* Destroy the named queue.
@@ -64,7 +70,7 @@ class QueueRegistry{
* subsequent calls to find or declare with the same name.
*
*/
- void destroy (const string& name);
+ QPID_BROKER_EXTERN void destroy(const string& name);
template <class Test> bool destroyIf(const string& name, Test test)
{
qpid::sys::RWlock::ScopedWlock locker(lock);
@@ -79,13 +85,15 @@ class QueueRegistry{
/**
* Find the named queue. Return 0 if not found.
*/
- Queue::shared_ptr find(const string& name);
+ QPID_BROKER_EXTERN Queue::shared_ptr find(const string& name);
/**
* Generate unique queue name.
*/
string generateName();
+ void setQueueEvents(QueueEvents*);
+
/**
* Set the store to use. May only be called once.
*/
@@ -120,6 +128,7 @@ private:
mutable qpid::sys::RWlock lock;
int counter;
MessageStore* store;
+ QueueEvents* events;
management::Manageable* parent;
bool lastNode; //used to set mode on queue declare
diff --git a/qpid/cpp/src/qpid/broker/RecoveryManagerImpl.cpp b/qpid/cpp/src/qpid/broker/RecoveryManagerImpl.cpp
index 8030cf7d0e..5f8b57fa0b 100644
--- a/qpid/cpp/src/qpid/broker/RecoveryManagerImpl.cpp
+++ b/qpid/cpp/src/qpid/broker/RecoveryManagerImpl.cpp
@@ -149,7 +149,8 @@ RecoverableConfig::shared_ptr RecoveryManagerImpl::recoverConfig(framing::Buffer
void RecoveryManagerImpl::recoveryComplete()
{
- //TODO (finalise binding setup etc)
+ //notify all queues
+ queues.eachQueue(boost::bind(&Queue::recoveryComplete, _1));
}
bool RecoverableMessageImpl::loadContent(uint64_t available)
diff --git a/qpid/cpp/src/qpid/broker/RetryList.h b/qpid/cpp/src/qpid/broker/RetryList.h
index 013233ef00..3cdba72ecf 100644
--- a/qpid/cpp/src/qpid/broker/RetryList.h
+++ b/qpid/cpp/src/qpid/broker/RetryList.h
@@ -22,6 +22,7 @@
*
*/
+#include "BrokerImportExport.h"
#include "qpid/Address.h"
#include "qpid/Url.h"
@@ -35,9 +36,9 @@ namespace broker {
class RetryList
{
public:
- RetryList();
- void reset(const std::vector<Url>& urls);
- bool next(TcpAddress& address);
+ QPID_BROKER_EXTERN RetryList();
+ QPID_BROKER_EXTERN void reset(const std::vector<Url>& urls);
+ QPID_BROKER_EXTERN bool next(TcpAddress& address);
private:
std::vector<Url> urls;
size_t urlIndex;
diff --git a/qpid/cpp/src/qpid/broker/SaslAuthenticator.cpp b/qpid/cpp/src/qpid/broker/SaslAuthenticator.cpp
index 736b051945..edc66444ec 100644
--- a/qpid/cpp/src/qpid/broker/SaslAuthenticator.cpp
+++ b/qpid/cpp/src/qpid/broker/SaslAuthenticator.cpp
@@ -141,21 +141,31 @@ NullAuthenticator::~NullAuthenticator() {}
void NullAuthenticator::getMechanisms(Array& mechanisms)
{
mechanisms.add(boost::shared_ptr<FieldValue>(new Str16Value("ANONYMOUS")));
+ mechanisms.add(boost::shared_ptr<FieldValue>(new Str16Value("PLAIN")));//useful for testing
}
void NullAuthenticator::start(const string& mechanism, const string& response)
{
if (mechanism == "PLAIN") { // Old behavior
- if (response.size() > 0 && response[0] == (char) 0) {
- string temp = response.substr(1);
- string::size_type i = temp.find((char)0);
- string uid = temp.substr(0, i);
- string pwd = temp.substr(i + 1);
- i = uid.find_last_of(realm);
- if (i == string::npos || i != (uid.size() - 1)) {
- uid = str(format("%1%@%2%") % uid % realm);
+ if (response.size() > 0) {
+ string uid;
+ string::size_type i = response.find((char)0);
+ if (i == 0 && response.size() > 1) {
+ //no authorization id; use authentication id
+ i = response.find((char)0, 1);
+ if (i != string::npos) uid = response.substr(1, i-1);
+ } else if (i != string::npos) {
+ //authorization id is first null delimited field
+ uid = response.substr(0, i);
+ }//else not a valid SASL PLAIN response, throw error?
+ if (!uid.empty()) {
+ //append realm if it has not already been added
+ i = uid.find(realm);
+ if (i == string::npos || realm.size() + i < uid.size()) {
+ uid = str(format("%1%@%2%") % uid % realm);
+ }
+ connection.setUserId(uid);
}
- connection.setUserId(uid);
}
} else {
connection.setUserId("anonymous");
diff --git a/qpid/cpp/src/qpid/broker/SemanticState.cpp b/qpid/cpp/src/qpid/broker/SemanticState.cpp
index 4f751e43b7..3c7c6d9afa 100644
--- a/qpid/cpp/src/qpid/broker/SemanticState.cpp
+++ b/qpid/cpp/src/qpid/broker/SemanticState.cpp
@@ -355,20 +355,12 @@ const std::string nullstring;
}
void SemanticState::route(intrusive_ptr<Message> msg, Deliverable& strategy) {
+ msg->setTimestamp(getSession().getBroker().getExpiryPolicy());
+
std::string exchangeName = msg->getExchangeName();
- //TODO: the following should be hidden behind message (using MessageAdapter or similar)
-
- if (msg->isA<MessageTransferBody>()) {
- // Do not replace the delivery-properties.exchange if it is is already set.
- // This is used internally (by the cluster) to force the exchange name on a message.
- // The client library ensures this is always empty for messages from normal clients.
- if (!msg->hasProperties<DeliveryProperties>() || msg->getProperties<DeliveryProperties>()->getExchange().empty())
- msg->getProperties<DeliveryProperties>()->setExchange(exchangeName);
- msg->setTimestamp(getSession().getBroker().getExpiryPolicy());
- }
- if (!cacheExchange || cacheExchange->getName() != exchangeName){
+ if (!cacheExchange || cacheExchange->getName() != exchangeName)
cacheExchange = session.getBroker().getExchanges().get(exchangeName);
- }
+ cacheExchange->setProperties(msg);
/* verify the userid if specified: */
std::string id =
@@ -516,14 +508,16 @@ void SemanticState::ConsumerImpl::setCreditMode()
void SemanticState::ConsumerImpl::addByteCredit(uint32_t value)
{
if (byteCredit != 0xFFFFFFFF) {
- byteCredit += value;
+ if (value == 0xFFFFFFFF) byteCredit = value;
+ else byteCredit += value;
}
}
void SemanticState::ConsumerImpl::addMessageCredit(uint32_t value)
{
if (msgCredit != 0xFFFFFFFF) {
- msgCredit += value;
+ if (value == 0xFFFFFFFF) msgCredit = value;
+ else msgCredit += value;
}
}
diff --git a/qpid/cpp/src/qpid/broker/SessionAdapter.cpp b/qpid/cpp/src/qpid/broker/SessionAdapter.cpp
index ae160fabc7..96c47085f0 100644
--- a/qpid/cpp/src/qpid/broker/SessionAdapter.cpp
+++ b/qpid/cpp/src/qpid/broker/SessionAdapter.cpp
@@ -362,10 +362,6 @@ void SessionAdapter::QueueHandlerImpl::declare(const string& name, const string&
getBroker().getExchanges().getDefault()->bind(queue, name, 0);
queue->bound(getBroker().getExchanges().getDefault()->getName(), name, arguments);
- //if event generation is turned on, pass in a pointer to
- //the QueueEvents instance to use
- if (queue->getEventMode()) queue->setQueueEventManager(getBroker().getQueueEvents());
-
//handle automatic cleanup:
if (exclusive) {
exclusiveQueues.push_back(queue);
diff --git a/qpid/cpp/src/qpid/broker/SessionHandler.cpp b/qpid/cpp/src/qpid/broker/SessionHandler.cpp
index 2c4de478f6..442c3eb34b 100644
--- a/qpid/cpp/src/qpid/broker/SessionHandler.cpp
+++ b/qpid/cpp/src/qpid/broker/SessionHandler.cpp
@@ -34,7 +34,8 @@ using namespace qpid::sys;
SessionHandler::SessionHandler(Connection& c, ChannelId ch)
: amqp_0_10::SessionHandler(&c.getOutput(), ch),
connection(c),
- proxy(out)
+ proxy(out),
+ clusterOrderProxy(c.getClusterOrderOutput() ? new SetChannelProxy(ch, c.getClusterOrderOutput()) : 0)
{}
SessionHandler::~SessionHandler() {}
@@ -84,11 +85,23 @@ void SessionHandler::readyToSend() {
if (session.get()) session->readyToSend();
}
-// TODO aconway 2008-05-12: hacky - handle attached for bridge clients.
-// We need to integrate the client code so we can run a real client
-// in the bridge.
-//
-void SessionHandler::attached(const std::string& name) {
+/**
+ * Used by inter-broker bridges to set up session id and attach
+ */
+void SessionHandler::attachAs(const std::string& name)
+{
+ SessionId id(connection.getUserId(), name);
+ SessionState::Configuration config = connection.broker.getSessionManager().getSessionConfig();
+ session.reset(new SessionState(connection.getBroker(), *this, id, config));
+ sendAttach(false);
+}
+
+/**
+ * TODO: this is a little ugly, fix it; its currently still relied on
+ * for 'push' bridges
+ */
+void SessionHandler::attached(const std::string& name)
+{
if (session.get()) {
amqp_0_10::SessionHandler::attached(name);
} else {
diff --git a/qpid/cpp/src/qpid/broker/SessionHandler.h b/qpid/cpp/src/qpid/broker/SessionHandler.h
index 7449db1560..ffc032f64c 100644
--- a/qpid/cpp/src/qpid/broker/SessionHandler.h
+++ b/qpid/cpp/src/qpid/broker/SessionHandler.h
@@ -54,10 +54,20 @@ class SessionHandler : public amqp_0_10::SessionHandler {
framing::AMQP_ClientProxy& getProxy() { return proxy; }
const framing::AMQP_ClientProxy& getProxy() const { return proxy; }
+ /**
+ * If commands are sent based on the local time (e.g. in timers), they don't have
+ * a well-defined ordering across cluster nodes.
+ * This proxy is for sending such commands. In a clustered broker it will take steps
+ * to synchronize command order across the cluster. In a stand-alone broker
+ * it is just a synonym for getProxy()
+ */
+ framing::AMQP_ClientProxy& getClusterOrderProxy() {
+ return clusterOrderProxy.get() ? *clusterOrderProxy : proxy;
+ }
+
virtual void handleDetach();
-
- // Overrides
- void attached(const std::string& name);
+ void attached(const std::string& name);//used by 'pushing' inter-broker bridges
+ void attachAs(const std::string& name);//used by 'pulling' inter-broker bridges
protected:
virtual void setState(const std::string& sessionName, bool force);
@@ -69,9 +79,16 @@ class SessionHandler : public amqp_0_10::SessionHandler {
virtual void readyToSend();
private:
+ struct SetChannelProxy : public framing::AMQP_ClientProxy { // Proxy that sets the channel.
+ framing::ChannelHandler setChannel;
+ SetChannelProxy(uint16_t ch, framing::FrameHandler* out)
+ : framing::AMQP_ClientProxy(setChannel), setChannel(ch, out) {}
+ };
+
Connection& connection;
framing::AMQP_ClientProxy proxy;
std::auto_ptr<SessionState> session;
+ std::auto_ptr<SetChannelProxy> clusterOrderProxy;
};
}} // namespace qpid::broker
diff --git a/qpid/cpp/src/qpid/broker/SessionState.cpp b/qpid/cpp/src/qpid/broker/SessionState.cpp
index 82ffede3f9..7e5f605753 100644
--- a/qpid/cpp/src/qpid/broker/SessionState.cpp
+++ b/qpid/cpp/src/qpid/broker/SessionState.cpp
@@ -66,7 +66,7 @@ SessionState::SessionState(
uint32_t maxRate = broker.getOptions().maxSessionRate;
if (maxRate) {
if (handler->getConnection().getClientThrottling()) {
- rateFlowcontrol = new RateFlowcontrol(maxRate);
+ rateFlowcontrol.reset(new RateFlowcontrol(maxRate));
} else {
QPID_LOG(warning, getId() << ": Unable to flow control client - client doesn't support");
}
@@ -212,11 +212,15 @@ struct ScheduledCreditTask : public TimerTask {
void fire() {
// This is the best we can currently do to avoid a destruction/fire race
if (!isCancelled()) {
- if ( !sessionState.processSendCredit(0) ) {
- QPID_LOG(warning, sessionState.getId() << ": Reschedule sending credit");
- reset();
- timer.add(this);
- }
+ sessionState.getConnection().requestIOProcessing(boost::bind(&ScheduledCreditTask::sendCredit, this));
+ }
+ }
+
+ void sendCredit() {
+ if ( !sessionState.processSendCredit(0) ) {
+ QPID_LOG(warning, sessionState.getId() << ": Reschedule sending credit");
+ reset();
+ timer.add(this);
}
}
};
@@ -274,7 +278,8 @@ bool SessionState::processSendCredit(uint32_t msgs)
if ( msgs > 0 && rateFlowcontrol->flowStopped() ) {
QPID_LOG(warning, getId() << ": producer throttling violation");
// TODO: Probably do message.stop("") first time then disconnect
- getProxy().getMessage().stop("");
+ // See comment on getClusterOrderProxy() in .h file
+ getClusterOrderProxy().getMessage().stop("");
return true;
}
AbsTime now = AbsTime::now();
@@ -282,7 +287,7 @@ bool SessionState::processSendCredit(uint32_t msgs)
if (mgmtObject) mgmtObject->dec_clientCredit(msgs);
if ( sendCredit>0 ) {
QPID_LOG(debug, getId() << ": send producer credit " << sendCredit);
- getProxy().getMessage().flow("", 0, sendCredit);
+ getClusterOrderProxy().getMessage().flow("", 0, sendCredit);
rateFlowcontrol->sentCredit(now, sendCredit);
if (mgmtObject) mgmtObject->inc_clientCredit(sendCredit);
return true;
@@ -363,8 +368,9 @@ void SessionState::readyToSend() {
// Issue initial credit - use a heuristic here issue min of 300 messages or 1 secs worth
uint32_t credit = std::min(rateFlowcontrol->getRate(), 300U);
QPID_LOG(debug, getId() << ": Issuing producer message credit " << credit);
- getProxy().getMessage().setFlowMode("", 0);
- getProxy().getMessage().flow("", 0, credit);
+ // See comment on getClusterOrderProxy() in .h file
+ getClusterOrderProxy().getMessage().setFlowMode("", 0);
+ getClusterOrderProxy().getMessage().flow("", 0, credit);
rateFlowcontrol->sentCredit(AbsTime::now(), credit);
if (mgmtObject) mgmtObject->inc_clientCredit(credit);
}
@@ -372,4 +378,8 @@ void SessionState::readyToSend() {
Broker& SessionState::getBroker() { return broker; }
+framing::AMQP_ClientProxy& SessionState::getClusterOrderProxy() {
+ return handler->getClusterOrderProxy();
+}
+
}} // namespace qpid::broker
diff --git a/qpid/cpp/src/qpid/broker/SessionState.h b/qpid/cpp/src/qpid/broker/SessionState.h
index c435a741f8..bdfed87905 100644
--- a/qpid/cpp/src/qpid/broker/SessionState.h
+++ b/qpid/cpp/src/qpid/broker/SessionState.h
@@ -56,7 +56,7 @@ class Message;
class SessionHandler;
class SessionManager;
class RateFlowcontrol;
-class TimerTask;
+struct TimerTask;
/**
* Broker-side session state includes session's handler chains, which
@@ -125,6 +125,15 @@ class SessionState : public qpid::SessionState,
void sendAcceptAndCompletion();
+ /**
+ * If commands are sent based on the local time (e.g. in timers), they don't have
+ * a well-defined ordering across cluster nodes.
+ * This proxy is for sending such commands. In a clustered broker it will take steps
+ * to synchronize command order across the cluster. In a stand-alone broker
+ * it is just a synonym for getProxy()
+ */
+ framing::AMQP_ClientProxy& getClusterOrderProxy();
+
Broker& broker;
SessionHandler* handler;
sys::AbsTime expiry; // Used by SessionManager.
@@ -138,7 +147,7 @@ class SessionState : public qpid::SessionState,
// State used for producer flow control (rate limited)
qpid::sys::Mutex rateLock;
- RateFlowcontrol* rateFlowcontrol;
+ boost::scoped_ptr<RateFlowcontrol> rateFlowcontrol;
boost::intrusive_ptr<TimerTask> flowControlTimer;
friend class SessionManager;
diff --git a/qpid/cpp/src/qpid/broker/Timer.h b/qpid/cpp/src/qpid/broker/Timer.h
index be4ac9d056..564fec5804 100644
--- a/qpid/cpp/src/qpid/broker/Timer.h
+++ b/qpid/cpp/src/qpid/broker/Timer.h
@@ -21,6 +21,7 @@
#ifndef _Timer_
#define _Timer_
+#include "BrokerImportExport.h"
#include "qpid/sys/Monitor.h"
#include "qpid/sys/Thread.h"
#include "qpid/sys/Runnable.h"
@@ -43,9 +44,9 @@ struct TimerTask : public RefCounted {
qpid::sys::AbsTime time;
volatile bool cancelled;
- TimerTask(qpid::sys::Duration timeout);
+ QPID_BROKER_EXTERN TimerTask(qpid::sys::Duration timeout);
TimerTask(qpid::sys::AbsTime time);
- virtual ~TimerTask();
+ QPID_BROKER_EXTERN virtual ~TimerTask();
void reset();
void cancel();
bool isCancelled() const;
@@ -69,10 +70,10 @@ class Timer : private qpid::sys::Runnable {
virtual void run();
public:
- Timer();
- virtual ~Timer();
+ QPID_BROKER_EXTERN Timer();
+ QPID_BROKER_EXTERN virtual ~Timer();
- void add(boost::intrusive_ptr<TimerTask> task);
+ QPID_BROKER_EXTERN void add(boost::intrusive_ptr<TimerTask> task);
void start();
void stop();
diff --git a/qpid/cpp/src/qpid/broker/TopicExchange.h b/qpid/cpp/src/qpid/broker/TopicExchange.h
index f3a2e221f7..24bf5f7bca 100644
--- a/qpid/cpp/src/qpid/broker/TopicExchange.h
+++ b/qpid/cpp/src/qpid/broker/TopicExchange.h
@@ -23,6 +23,7 @@
#include <map>
#include <vector>
+#include "BrokerImportExport.h"
#include "Exchange.h"
#include "qpid/framing/FieldTable.h"
#include "qpid/sys/Monitor.h"
@@ -40,7 +41,7 @@ class Tokens : public std::vector<std::string> {
/** Tokenize s, provides automatic conversion of string to Tokens */
Tokens(const std::string& s) { operator=(s); }
/** Tokenizing assignment operator s */
- Tokens & operator=(const std::string& s);
+ QPID_BROKER_EXTERN Tokens & operator=(const std::string& s);
void key(std::string& key) const;
private:
@@ -60,12 +61,12 @@ class TopicPattern : public Tokens
// Default copy, assign, dtor are sufficient.
TopicPattern(const Tokens& tokens) { operator=(tokens); }
TopicPattern(const std::string& str) { operator=(str); }
- TopicPattern& operator=(const Tokens&);
+ QPID_BROKER_EXTERN TopicPattern& operator=(const Tokens&);
TopicPattern& operator=(const std::string& str) { return operator=(Tokens(str)); }
/** Match a topic */
bool match(const std::string& topic) { return match(Tokens(topic)); }
- bool match(const Tokens& topic) const;
+ QPID_BROKER_EXTERN bool match(const Tokens& topic) const;
private:
void normalize();
@@ -84,21 +85,30 @@ class TopicExchange : public virtual Exchange {
public:
static const std::string typeName;
- TopicExchange(const string& name, management::Manageable* parent = 0);
- TopicExchange(const string& _name, bool _durable,
- const qpid::framing::FieldTable& _args, management::Manageable* parent = 0);
+ QPID_BROKER_EXTERN TopicExchange(const string& name,
+ management::Manageable* parent = 0);
+ QPID_BROKER_EXTERN TopicExchange(const string& _name,
+ bool _durable,
+ const qpid::framing::FieldTable& _args,
+ management::Manageable* parent = 0);
virtual std::string getType() const { return typeName; }
- virtual bool bind(Queue::shared_ptr queue, const string& routingKey, const qpid::framing::FieldTable* args);
+ QPID_BROKER_EXTERN virtual bool bind(Queue::shared_ptr queue,
+ const string& routingKey,
+ const qpid::framing::FieldTable* args);
virtual bool unbind(Queue::shared_ptr queue, const string& routingKey, const qpid::framing::FieldTable* args);
- virtual void route(Deliverable& msg, const string& routingKey, const qpid::framing::FieldTable* args);
+ QPID_BROKER_EXTERN virtual void route(Deliverable& msg,
+ const string& routingKey,
+ const qpid::framing::FieldTable* args);
- virtual bool isBound(Queue::shared_ptr queue, const string* const routingKey, const qpid::framing::FieldTable* const args);
+ QPID_BROKER_EXTERN virtual bool isBound(Queue::shared_ptr queue,
+ const string* const routingKey,
+ const qpid::framing::FieldTable* const args);
- virtual ~TopicExchange();
+ QPID_BROKER_EXTERN virtual ~TopicExchange();
virtual bool supportsDynamicBinding() { return true; }
};
diff --git a/qpid/cpp/src/qpid/broker/TxAccept.cpp b/qpid/cpp/src/qpid/broker/TxAccept.cpp
index c7001e5526..73f365d509 100644
--- a/qpid/cpp/src/qpid/broker/TxAccept.cpp
+++ b/qpid/cpp/src/qpid/broker/TxAccept.cpp
@@ -50,12 +50,12 @@ void TxAccept::RangeOps::operator()(SequenceNumber start, SequenceNumber end)
void TxAccept::RangeOps::prepare(TransactionContext* ctxt)
{
- for_each(ranges.begin(), ranges.end(), bind(&RangeOp::prepare, _1, ctxt));
+ std::for_each(ranges.begin(), ranges.end(), bind(&RangeOp::prepare, _1, ctxt));
}
void TxAccept::RangeOps::commit()
{
- for_each(ranges.begin(), ranges.end(), bind(&RangeOp::commit, _1));
+ std::for_each(ranges.begin(), ranges.end(), bind(&RangeOp::commit, _1));
//now remove if isRedundant():
if (!ranges.empty()) {
ack_iterator i = ranges.front().range.start;
diff --git a/qpid/cpp/src/qpid/broker/TxBuffer.h b/qpid/cpp/src/qpid/broker/TxBuffer.h
index aabb5ea0b1..f63a65f115 100644
--- a/qpid/cpp/src/qpid/broker/TxBuffer.h
+++ b/qpid/cpp/src/qpid/broker/TxBuffer.h
@@ -24,6 +24,7 @@
#include <algorithm>
#include <functional>
#include <vector>
+#include "BrokerImportExport.h"
#include "TransactionalStore.h"
#include "TxOp.h"
@@ -68,7 +69,7 @@ namespace qpid {
/**
* Adds an operation to the transaction.
*/
- void enlist(TxOp::shared_ptr op);
+ QPID_BROKER_EXTERN void enlist(TxOp::shared_ptr op);
/**
* Requests that all ops are prepared. This should
@@ -81,7 +82,7 @@ namespace qpid {
* @returns true if all the operations prepared
* successfully, false if not.
*/
- bool prepare(TransactionContext* const ctxt);
+ QPID_BROKER_EXTERN bool prepare(TransactionContext* const ctxt);
/**
* Signals that the ops all prepared successfully and can
@@ -91,7 +92,7 @@ namespace qpid {
* Should only be called after a call to prepare() returns
* true.
*/
- void commit();
+ QPID_BROKER_EXTERN void commit();
/**
* Signals that all ops can be rolled back.
@@ -100,13 +101,13 @@ namespace qpid {
* returns true (2pc) or instead of a prepare call
* ('server-local')
*/
- void rollback();
+ QPID_BROKER_EXTERN void rollback();
/**
* Helper method for managing the process of server local
* commit
*/
- bool commitLocal(TransactionalStore* const store);
+ QPID_BROKER_EXTERN bool commitLocal(TransactionalStore* const store);
// Used by cluster to replicate transaction status.
void accept(TxOpConstVisitor& v) const;
diff --git a/qpid/cpp/src/qpid/broker/TxPublish.h b/qpid/cpp/src/qpid/broker/TxPublish.h
index 1f73cb8767..ebe3b51f3d 100644
--- a/qpid/cpp/src/qpid/broker/TxPublish.h
+++ b/qpid/cpp/src/qpid/broker/TxPublish.h
@@ -21,6 +21,7 @@
#ifndef _TxPublish_
#define _TxPublish_
+#include "BrokerImportExport.h"
#include "Queue.h"
#include "Deliverable.h"
#include "Message.h"
@@ -65,19 +66,19 @@ namespace qpid {
std::list<Queue::shared_ptr> queues;
public:
- TxPublish(boost::intrusive_ptr<Message> msg);
- virtual bool prepare(TransactionContext* ctxt) throw();
- virtual void commit() throw();
- virtual void rollback() throw();
+ QPID_BROKER_EXTERN TxPublish(boost::intrusive_ptr<Message> msg);
+ QPID_BROKER_EXTERN virtual bool prepare(TransactionContext* ctxt) throw();
+ QPID_BROKER_EXTERN virtual void commit() throw();
+ QPID_BROKER_EXTERN virtual void rollback() throw();
virtual Message& getMessage() { return *msg; };
- virtual void deliverTo(const boost::shared_ptr<Queue>& queue);
+ QPID_BROKER_EXTERN virtual void deliverTo(const boost::shared_ptr<Queue>& queue);
virtual ~TxPublish(){}
virtual void accept(TxOpConstVisitor& visitor) const { visitor(*this); }
- uint64_t contentSize();
+ QPID_BROKER_EXTERN uint64_t contentSize();
boost::intrusive_ptr<Message> getMessage() const { return msg; }
const std::list<Queue::shared_ptr> getQueues() const { return queues; }
diff --git a/qpid/cpp/src/qpid/client/ClientImportExport.h b/qpid/cpp/src/qpid/client/ClientImportExport.h
new file mode 100644
index 0000000000..0e6e5660d6
--- /dev/null
+++ b/qpid/cpp/src/qpid/client/ClientImportExport.h
@@ -0,0 +1,33 @@
+#ifndef QPID_CLIENT_IMPORT_EXPORT_H
+#define QPID_CLIENT_IMPORT_EXPORT_H
+
+/*
+ * 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.
+ */
+
+#if defined(WIN32) && !defined(QPID_DECLARE_STATIC)
+#if defined(CLIENT_EXPORT)
+#define QPID_CLIENT_EXTERN __declspec(dllexport)
+#else
+#define QPID_CLIENT_EXTERN __declspec(dllimport)
+#endif
+#else
+#define QPID_CLIENT_EXTERN
+#endif
+
+#endif
diff --git a/qpid/cpp/src/qpid/client/Connection.h b/qpid/cpp/src/qpid/client/Connection.h
index 03631ef56f..846ac33790 100644
--- a/qpid/cpp/src/qpid/client/Connection.h
+++ b/qpid/cpp/src/qpid/client/Connection.h
@@ -24,6 +24,7 @@
#include <map>
#include <string>
#include "qpid/client/Session.h"
+#include "qpid/client/ClientImportExport.h"
namespace qpid {
@@ -58,9 +59,9 @@ class Connection
* Creates a connection object, but does not open the connection.
* @see open()
*/
- Connection();
+ QPID_CLIENT_EXTERN Connection();
- ~Connection();
+ QPID_CLIENT_EXTERN ~Connection();
/**
* Opens a connection to a broker.
@@ -79,7 +80,7 @@ class Connection
* hosts, where implemented(!), provide namespace partitioning
* within a single broker).
*/
- void open(const std::string& host, int port = 5672,
+ QPID_CLIENT_EXTERN void open(const std::string& host, int port = 5672,
const std::string& uid = "guest",
const std::string& pwd = "guest",
const std::string& virtualhost = "/", uint16_t maxFrameSize=65535);
@@ -101,7 +102,7 @@ class Connection
* hosts, where implemented(!), provide namespace partitioning
* within a single broker).
*/
- void open(const Url& url,
+ QPID_CLIENT_EXTERN void open(const Url& url,
const std::string& uid = "guest",
const std::string& pwd = "guest",
const std::string& virtualhost = "/", uint16_t maxFrameSize=65535);
@@ -116,14 +117,14 @@ class Connection
* @param settings used for any settings not provided by the URL.
* Settings provided by the url (e.g. host, port) are ignored.
*/
- void open(const Url& url, const ConnectionSettings& settings);
+ QPID_CLIENT_EXTERN void open(const Url& url, const ConnectionSettings& settings);
/**
* Opens a connection to a broker.
*
* @param the settings to use (host, port etc). @see ConnectionSettings.
*/
- void open(const ConnectionSettings& settings);
+ QPID_CLIENT_EXTERN void open(const ConnectionSettings& settings);
/**
* Close the connection.
@@ -131,7 +132,7 @@ class Connection
* Any further use of this connection (without reopening it) will
* not succeed.
*/
- void close();
+ QPID_CLIENT_EXTERN void close();
/**
* Create a new session on this connection. Sessions allow
@@ -174,23 +175,23 @@ class Connection
* If the name is empty (the default) then a unique name will be
* chosen using a Universally-unique identifier (UUID) algorithm.
*/
- Session newSession(const std::string& name=std::string(), uint32_t timeoutSeconds = 0);
+ QPID_CLIENT_EXTERN Session newSession(const std::string& name=std::string(), uint32_t timeoutSeconds = 0);
/**
* Resume a suspended session. A session may be resumed
* on a different connection to the one that created it.
*/
- void resume(Session& session);
+ QPID_CLIENT_EXTERN void resume(Session& session);
- bool isOpen() const;
+ QPID_CLIENT_EXTERN bool isOpen() const;
- std::vector<Url> getKnownBrokers();
- void registerFailureCallback ( boost::function<void ()> fn );
+ QPID_CLIENT_EXTERN std::vector<Url> getKnownBrokers();
+ QPID_CLIENT_EXTERN void registerFailureCallback ( boost::function<void ()> fn );
/**
* Return the set of client negotiated settings
*/
- const ConnectionSettings& getNegotiatedSettings();
+ QPID_CLIENT_EXTERN const ConnectionSettings& getNegotiatedSettings();
friend class ConnectionAccess; ///<@internal
friend class SessionBase_0_10; ///<@internal
diff --git a/qpid/cpp/src/qpid/client/ConnectionHandler.cpp b/qpid/cpp/src/qpid/client/ConnectionHandler.cpp
index 377b84c019..6efdb91e96 100644
--- a/qpid/cpp/src/qpid/client/ConnectionHandler.cpp
+++ b/qpid/cpp/src/qpid/client/ConnectionHandler.cpp
@@ -28,6 +28,7 @@
#include "qpid/framing/reply_exceptions.h"
#include "qpid/log/Helpers.h"
#include "qpid/log/Statement.h"
+#include "qpid/sys/SystemInfo.h"
using namespace qpid::client;
using namespace qpid::framing;
@@ -52,6 +53,9 @@ const std::string INVALID_STATE_OPEN_OK("open-ok received in invalid state");
const std::string INVALID_STATE_CLOSE_OK("close-ok received in invalid state");
const std::string SESSION_FLOW_CONTROL("qpid.session_flow");
+const std::string CLIENT_PROCESS_NAME("qpid.client_process");
+const std::string CLIENT_PID("qpid.client_pid");
+const std::string CLIENT_PPID("qpid.client_ppid");
const int SESSION_FLOW_CONTROL_VER = 1;
}
@@ -80,6 +84,9 @@ ConnectionHandler::ConnectionHandler(const ConnectionSettings& s, ProtocolVersio
FINISHED.insert(CLOSED);
properties.setInt(SESSION_FLOW_CONTROL, SESSION_FLOW_CONTROL_VER);
+ properties.setString(CLIENT_PROCESS_NAME, sys::SystemInfo::getProcessName());
+ properties.setInt(CLIENT_PID, sys::SystemInfo::getProcessId());
+ properties.setInt(CLIENT_PPID, sys::SystemInfo::getParentProcessId());
}
void ConnectionHandler::incoming(AMQFrame& frame)
diff --git a/qpid/cpp/src/qpid/client/ConnectionImpl.cpp b/qpid/cpp/src/qpid/client/ConnectionImpl.cpp
index 8e27d78479..745bdb63b5 100644
--- a/qpid/cpp/src/qpid/client/ConnectionImpl.cpp
+++ b/qpid/cpp/src/qpid/client/ConnectionImpl.cpp
@@ -180,6 +180,9 @@ void ConnectionImpl::close()
template <class F> void ConnectionImpl::closeInternal(const F& f) {
+ if (heartbeatTask) {
+ heartbeatTask->cancel();
+ }
{
Mutex::ScopedUnlock u(lock);
connector->close();
diff --git a/qpid/cpp/src/qpid/client/ConnectionSettings.h b/qpid/cpp/src/qpid/client/ConnectionSettings.h
index f60b11a4ab..71fef219b4 100644
--- a/qpid/cpp/src/qpid/client/ConnectionSettings.h
+++ b/qpid/cpp/src/qpid/client/ConnectionSettings.h
@@ -25,6 +25,7 @@
#include "qpid/Options.h"
#include "qpid/log/Options.h"
#include "qpid/Url.h"
+#include "qpid/client/ClientImportExport.h"
#include <iostream>
#include <exception>
@@ -42,14 +43,14 @@ namespace client {
*/
struct ConnectionSettings {
- ConnectionSettings();
- virtual ~ConnectionSettings();
+ QPID_CLIENT_EXTERN ConnectionSettings();
+ QPID_CLIENT_EXTERN virtual ~ConnectionSettings();
/**
* Allows socket to be configured; default only sets tcp-nodelay
* based on the flag set. Can be overridden.
*/
- virtual void configureSocket(qpid::sys::Socket&) const;
+ QPID_CLIENT_EXTERN virtual void configureSocket(qpid::sys::Socket&) const;
/**
* The protocol used for the connection (defaults to 'tcp')
diff --git a/qpid/cpp/src/qpid/client/Connector.cpp b/qpid/cpp/src/qpid/client/Connector.cpp
index e6355601df..c251233082 100644
--- a/qpid/cpp/src/qpid/client/Connector.cpp
+++ b/qpid/cpp/src/qpid/client/Connector.cpp
@@ -92,8 +92,6 @@ class TCPConnector : public Connector, public sys::Codec, private sys::Runnable
framing::ProtocolVersion version;
bool initiated;
-
- sys::Mutex closedLock;
bool closed;
bool joined;
@@ -185,7 +183,7 @@ TCPConnector::~TCPConnector() {
}
void TCPConnector::connect(const std::string& host, int port){
- Mutex::ScopedLock l(closedLock);
+ Mutex::ScopedLock l(lock);
assert(closed);
try {
socket.connect(host, port);
@@ -207,7 +205,7 @@ void TCPConnector::connect(const std::string& host, int port){
}
void TCPConnector::init(){
- Mutex::ScopedLock l(closedLock);
+ Mutex::ScopedLock l(lock);
assert(joined);
ProtocolInitiation init(version);
writeDataBlock(init);
@@ -216,17 +214,21 @@ void TCPConnector::init(){
}
bool TCPConnector::closeInternal() {
- Mutex::ScopedLock l(closedLock);
- bool ret = !closed;
+ bool ret;
+ {
+ Mutex::ScopedLock l(lock);
+ ret = !closed;
if (!closed) {
closed = true;
+ aio->queueForDeletion();
poller->shutdown();
}
- if (!joined && receiver.id() != Thread::current().id()) {
- joined = true;
- Mutex::ScopedUnlock u(closedLock);
- receiver.join();
+ if (joined || receiver.id() == Thread::current().id()) {
+ return ret;
}
+ joined = true;
+ }
+ receiver.join();
return ret;
}
@@ -259,21 +261,19 @@ const std::string& TCPConnector::getIdentifier() const {
}
void TCPConnector::send(AMQFrame& frame) {
+ Mutex::ScopedLock l(lock);
+ frames.push_back(frame);
+ //only ask to write if this is the end of a frameset or if we
+ //already have a buffers worth of data
+ currentSize += frame.encodedSize();
bool notifyWrite = false;
- {
- Mutex::ScopedLock l(lock);
- frames.push_back(frame);
- //only ask to write if this is the end of a frameset or if we
- //already have a buffers worth of data
- currentSize += frame.encodedSize();
- if (frame.getEof()) {
- lastEof = frames.size();
- notifyWrite = true;
- } else {
- notifyWrite = (currentSize >= maxFrameSize);
- }
+ if (frame.getEof()) {
+ lastEof = frames.size();
+ notifyWrite = true;
+ } else {
+ notifyWrite = (currentSize >= maxFrameSize);
}
- if (notifyWrite) aio->notifyPendingWrite();
+ if (notifyWrite && !closed) aio->notifyPendingWrite();
}
void TCPConnector::handleClosed() {
@@ -384,14 +384,13 @@ void TCPConnector::run() {
assert(protect);
try {
Dispatcher d(poller);
-
+
for (int i = 0; i < 32; i++) {
aio->queueReadBuffer(new Buff(maxFrameSize));
}
-
+
aio->start(poller);
d.run();
- aio->queueForDeletion();
socket.close();
} catch (const std::exception& e) {
QPID_LOG(error, QPID_MSG("FAIL " << identifier << ": " << e.what()));
diff --git a/qpid/cpp/src/qpid/client/Dispatcher.cpp b/qpid/cpp/src/qpid/client/Dispatcher.cpp
index 27cc4184f9..8d8574520a 100644
--- a/qpid/cpp/src/qpid/client/Dispatcher.cpp
+++ b/qpid/cpp/src/qpid/client/Dispatcher.cpp
@@ -136,8 +136,7 @@ void Dispatcher::listen(const boost::intrusive_ptr<SubscriptionImpl>& subscripti
void Dispatcher::cancel(const std::string& destination) {
ScopedLock<Mutex> l(lock);
- listeners.erase(destination);
- if (autoStop && listeners.empty())
+ if (listeners.erase(destination) && running && autoStop && listeners.empty())
queue->close();
}
diff --git a/qpid/cpp/src/qpid/client/FailoverManager.cpp b/qpid/cpp/src/qpid/client/FailoverManager.cpp
index ab9dbca70f..86b50a0a61 100644
--- a/qpid/cpp/src/qpid/client/FailoverManager.cpp
+++ b/qpid/cpp/src/qpid/client/FailoverManager.cpp
@@ -21,12 +21,15 @@
#include "FailoverManager.h"
#include "qpid/Exception.h"
#include "qpid/log/Statement.h"
+#include "qpid/sys/Time.h"
namespace qpid {
namespace client {
using qpid::sys::Monitor;
+using qpid::sys::AbsTime;
+using qpid::sys::Duration;
FailoverManager::FailoverManager(const ConnectionSettings& s,
ReconnectionStrategy* rs) : settings(s), strategy(rs), state(IDLE) {}
@@ -35,15 +38,21 @@ void FailoverManager::execute(Command& c)
{
bool retry = false;
bool completed = false;
+ AbsTime failed;
while (!completed) {
try {
AsyncSession session = connect().newSession();
+ if (retry) {
+ Duration failoverTime(failed, AbsTime::now());
+ QPID_LOG(info, "Failed over for " << &c << " in " << (failoverTime/qpid::sys::TIME_MSEC) << " milliseconds");
+ }
c.execute(session, retry);
session.sync();//TODO: shouldn't be required
session.close();
completed = true;
} catch(const TransportFailure&) {
- retry = true;
+ retry = true;
+ failed = AbsTime::now();
}
}
}
diff --git a/qpid/cpp/src/qpid/client/FailoverManager.h b/qpid/cpp/src/qpid/client/FailoverManager.h
index 8b6eeda8a1..bef5e18840 100644
--- a/qpid/cpp/src/qpid/client/FailoverManager.h
+++ b/qpid/cpp/src/qpid/client/FailoverManager.h
@@ -27,6 +27,7 @@
#include "qpid/Exception.h"
#include "qpid/client/AsyncSession.h"
#include "qpid/sys/Monitor.h"
+#include "qpid/client/ClientImportExport.h"
#include <vector>
namespace qpid {
@@ -84,7 +85,7 @@ class FailoverManager
* to edit or reorder the list of urls to which reconnection is
* attempted
*/
- FailoverManager(const ConnectionSettings& settings, ReconnectionStrategy* strategy = 0);
+ QPID_CLIENT_EXTERN FailoverManager(const ConnectionSettings& settings, ReconnectionStrategy* strategy = 0);
/**
* Return the current connection if open or attept to reconnect to
* the specified list of urls. If no list is specified the list of
@@ -95,15 +96,15 @@ class FailoverManager
* If the full list is tried and all attempts fail,
* CannotConnectException is thrown.
*/
- Connection& connect(std::vector<Url> brokers = std::vector<Url>());
+ QPID_CLIENT_EXTERN Connection& connect(std::vector<Url> brokers = std::vector<Url>());
/**
* Return the current connection whether open or not
*/
- Connection& getConnection();
+ QPID_CLIENT_EXTERN Connection& getConnection();
/**
* Close the current connection
*/
- void close();
+ QPID_CLIENT_EXTERN void close();
/**
* Reliably execute the specified command. This involves creating
* a session on which to carry out the work of the command,
@@ -116,7 +117,7 @@ class FailoverManager
* on failover to ensure they continue to use the same logical
* connection.
*/
- void execute(Command&);
+ QPID_CLIENT_EXTERN void execute(Command&);
private:
enum State {IDLE, CONNECTING, CANT_CONNECT};
diff --git a/qpid/cpp/src/qpid/client/Future.h b/qpid/cpp/src/qpid/client/Future.h
index 67f39cdf3f..ea01522fe8 100644
--- a/qpid/cpp/src/qpid/client/Future.h
+++ b/qpid/cpp/src/qpid/client/Future.h
@@ -30,6 +30,7 @@
#include "FutureCompletion.h"
#include "FutureResult.h"
#include "SessionImpl.h"
+#include "ClientImportExport.h"
namespace qpid {
namespace client {
@@ -54,9 +55,9 @@ public:
}
}
- void wait(SessionImpl& session);
- bool isComplete(SessionImpl& session);
- void setFutureResult(boost::shared_ptr<FutureResult> r);
+ QPID_CLIENT_EXTERN void wait(SessionImpl& session);
+ QPID_CLIENT_EXTERN bool isComplete(SessionImpl& session);
+ QPID_CLIENT_EXTERN void setFutureResult(boost::shared_ptr<FutureResult> r);
};
}}
diff --git a/qpid/cpp/src/qpid/client/FutureResult.h b/qpid/cpp/src/qpid/client/FutureResult.h
index e97d80476d..64428c0341 100644
--- a/qpid/cpp/src/qpid/client/FutureResult.h
+++ b/qpid/cpp/src/qpid/client/FutureResult.h
@@ -23,6 +23,8 @@
#define _FutureResult_
#include <string>
+
+#include "ClientImportExport.h"
#include "qpid/framing/amqp_framing.h"
#include "FutureCompletion.h"
@@ -36,7 +38,7 @@ class FutureResult : public FutureCompletion
{
std::string result;
public:
- const std::string& getResult(SessionImpl& session) const;
+ QPID_CLIENT_EXTERN const std::string& getResult(SessionImpl& session) const;
void received(const std::string& result);
};
diff --git a/qpid/cpp/src/qpid/client/Handle.h b/qpid/cpp/src/qpid/client/Handle.h
index 4fd82b7646..d8b822d0f9 100644
--- a/qpid/cpp/src/qpid/client/Handle.h
+++ b/qpid/cpp/src/qpid/client/Handle.h
@@ -22,6 +22,8 @@
*
*/
+#include "qpid/client/ClientImportExport.h"
+
namespace qpid {
namespace client {
@@ -34,23 +36,23 @@ template <class T> class HandlePrivate;
*/
template <class T> class Handle {
public:
- ~Handle();
- Handle(const Handle&);
- Handle& operator=(const Handle&);
+ QPID_CLIENT_EXTERN ~Handle();
+ QPID_CLIENT_EXTERN Handle(const Handle&);
+ QPID_CLIENT_EXTERN Handle& operator=(const Handle&);
/**@return true if handle is valid, i.e. not null. */
- bool isValid() const { return impl; }
+ QPID_CLIENT_EXTERN bool isValid() const { return impl; }
/**@return true if handle is null. It is an error to call any function on a null handle. */
- bool isNull() const { return !impl; }
+ QPID_CLIENT_EXTERN bool isNull() const { return !impl; }
- operator bool() const { return impl; }
- bool operator !() const { return impl; }
+ QPID_CLIENT_EXTERN operator bool() const { return impl; }
+ QPID_CLIENT_EXTERN bool operator !() const { return impl; }
- void swap(Handle<T>&);
+ QPID_CLIENT_EXTERN void swap(Handle<T>&);
protected:
- Handle(T* =0);
+ QPID_CLIENT_EXTERN Handle(T* =0);
T* impl;
friend class HandlePrivate<T>;
diff --git a/qpid/cpp/src/qpid/client/LocalQueue.h b/qpid/cpp/src/qpid/client/LocalQueue.h
index 30ea00612d..5b739d4303 100644
--- a/qpid/cpp/src/qpid/client/LocalQueue.h
+++ b/qpid/cpp/src/qpid/client/LocalQueue.h
@@ -22,6 +22,7 @@
*
*/
+#include "ClientImportExport.h"
#include "qpid/client/Message.h"
#include "qpid/client/Subscription.h"
#include "qpid/client/Demux.h"
@@ -75,16 +76,16 @@ class LocalQueue {
*
* LocalQueue is an alternative to implementing a MessageListener.
*/
- LocalQueue();
+ QPID_CLIENT_EXTERN LocalQueue();
- ~LocalQueue();
+ QPID_CLIENT_EXTERN ~LocalQueue();
/** Wait up to timeout for the next message from the local queue.
*@param result Set to the message from the queue.
*@param timeout wait up this timeout for a message to appear.
*@return true if result was set, false if queue was empty after timeout.
*/
- bool get(Message& result, sys::Duration timeout=0);
+ QPID_CLIENT_EXTERN bool get(Message& result, sys::Duration timeout=0);
/** Get the next message off the local queue, or wait up to the timeout
* for message from the broker queue.
@@ -92,16 +93,16 @@ class LocalQueue {
*@return message from the queue.
*@throw ClosedException if subscription is closed or timeout exceeded.
*/
- Message get(sys::Duration timeout=sys::TIME_INFINITE);
+ QPID_CLIENT_EXTERN Message get(sys::Duration timeout=sys::TIME_INFINITE);
/** Synonym for get() */
- Message pop(sys::Duration timeout=sys::TIME_INFINITE);
+ QPID_CLIENT_EXTERN Message pop(sys::Duration timeout=sys::TIME_INFINITE);
/** Return true if local queue is empty. */
- bool empty() const;
+ QPID_CLIENT_EXTERN bool empty() const;
/** Number of messages on the local queue */
- size_t size() const;
+ QPID_CLIENT_EXTERN size_t size() const;
private:
Demux::QueuePtr queue;
diff --git a/qpid/cpp/src/qpid/client/Message.h b/qpid/cpp/src/qpid/client/Message.h
index 3f932efd8b..235e20f97d 100644
--- a/qpid/cpp/src/qpid/client/Message.h
+++ b/qpid/cpp/src/qpid/client/Message.h
@@ -25,6 +25,7 @@
#include "qpid/client/Session.h"
#include "qpid/framing/MessageTransferBody.h"
#include "qpid/framing/TransferContent.h"
+#include "qpid/client/ClientImportExport.h"
namespace qpid {
namespace client {
@@ -111,7 +112,7 @@ public:
*@param data Data for the message body.
*@param routingKey Passed to the exchange that routes the message.
*/
- Message(const std::string& data=std::string(),
+ QPID_CLIENT_EXTERN Message(const std::string& data=std::string(),
const std::string& routingKey=std::string());
/** The destination of messages sent to the broker is the exchange
@@ -119,26 +120,26 @@ public:
* the delivery tag identifyig the local subscription (often this
* is the name of the subscribed queue.)
*/
- std::string getDestination() const;
+ QPID_CLIENT_EXTERN std::string getDestination() const;
/** Check the redelivered flag. */
- bool isRedelivered() const;
+ QPID_CLIENT_EXTERN bool isRedelivered() const;
/** Set the redelivered flag. */
- void setRedelivered(bool redelivered);
+ QPID_CLIENT_EXTERN void setRedelivered(bool redelivered);
/** Get a modifyable reference to the message headers. */
- framing::FieldTable& getHeaders();
+ QPID_CLIENT_EXTERN framing::FieldTable& getHeaders();
/** Get a non-modifyable reference to the message headers. */
- const framing::FieldTable& getHeaders() const;
+ QPID_CLIENT_EXTERN const framing::FieldTable& getHeaders() const;
///@internal
- const framing::MessageTransferBody& getMethod() const;
+ QPID_CLIENT_EXTERN const framing::MessageTransferBody& getMethod() const;
///@internal
- const framing::SequenceNumber& getId() const;
+ QPID_CLIENT_EXTERN const framing::SequenceNumber& getId() const;
/**@internal for incoming messages */
- Message(const framing::FrameSet& frameset);
+ QPID_CLIENT_EXTERN Message(const framing::FrameSet& frameset);
private:
//method and id are only set for received messages:
diff --git a/qpid/cpp/src/qpid/client/MessageListener.h b/qpid/cpp/src/qpid/client/MessageListener.h
index 75aad6521b..b86aa10c54 100644
--- a/qpid/cpp/src/qpid/client/MessageListener.h
+++ b/qpid/cpp/src/qpid/client/MessageListener.h
@@ -19,6 +19,7 @@
*
*/
#include <string>
+#include "qpid/client/ClientImportExport.h"
#ifndef _MessageListener_
#define _MessageListener_
@@ -85,7 +86,7 @@ namespace client {
class MessageListener{
public:
- virtual ~MessageListener();
+ QPID_CLIENT_EXTERN virtual ~MessageListener();
/** Called for each message arriving from the broker. Override
* in your own subclass to process messages.
diff --git a/qpid/cpp/src/qpid/client/MessageReplayTracker.h b/qpid/cpp/src/qpid/client/MessageReplayTracker.h
index 45b16fb704..280cbae4a5 100644
--- a/qpid/cpp/src/qpid/client/MessageReplayTracker.h
+++ b/qpid/cpp/src/qpid/client/MessageReplayTracker.h
@@ -23,7 +23,7 @@
*/
#include "AsyncSession.h"
#include "Message.h"
-
+#include "qpid/client/ClientImportExport.h"
#include <list>
#include <string>
@@ -37,13 +37,13 @@ namespace client {
class MessageReplayTracker
{
public:
- MessageReplayTracker(uint flushInterval);
- void send(const Message& message, const std::string& destination = "");
- void init(AsyncSession session);
- void replay(AsyncSession session);
- void setFlushInterval(uint interval);
- uint getFlushInterval();
- void checkCompletion();
+ QPID_CLIENT_EXTERN MessageReplayTracker(uint flushInterval);
+ QPID_CLIENT_EXTERN void send(const Message& message, const std::string& destination = "");
+ QPID_CLIENT_EXTERN void init(AsyncSession session);
+ QPID_CLIENT_EXTERN void replay(AsyncSession session);
+ QPID_CLIENT_EXTERN void setFlushInterval(uint interval);
+ QPID_CLIENT_EXTERN uint getFlushInterval();
+ QPID_CLIENT_EXTERN void checkCompletion();
template <class F> void foreach(F& f) {
for (std::list<ReplayRecord>::const_iterator i = buffer.begin(); i != buffer.end(); i++) {
diff --git a/qpid/cpp/src/qpid/client/QueueOptions.h b/qpid/cpp/src/qpid/client/QueueOptions.h
index d159378198..57d9487217 100644
--- a/qpid/cpp/src/qpid/client/QueueOptions.h
+++ b/qpid/cpp/src/qpid/client/QueueOptions.h
@@ -18,6 +18,8 @@
* under the License.
*
*/
+
+#include "ClientImportExport.h"
#include "qpid/framing/FieldTable.h"
#ifndef _QueueOptions_
@@ -36,8 +38,8 @@ enum QueueOrderingPolicy {FIFO, LVQ, LVQ_NO_BROWSE};
class QueueOptions: public framing::FieldTable
{
public:
- QueueOptions();
- virtual ~QueueOptions();
+ QPID_CLIENT_EXTERN QueueOptions();
+ QPID_CLIENT_EXTERN virtual ~QueueOptions();
/**
* Sets the queue sizing policy
@@ -51,58 +53,58 @@ class QueueOptions: public framing::FieldTable
* @param maxSize Set the max number of bytes for the sizing policies
* @param setMaxCount Set the max number of messages for the sizing policies
*/
- void setSizePolicy(QueueSizePolicy sp, uint64_t maxSize, uint32_t maxCount );
+ QPID_CLIENT_EXTERN void setSizePolicy(QueueSizePolicy sp, uint64_t maxSize, uint32_t maxCount );
/**
* Enables the persisting of a queue to the store module when a cluster fails down to it's last
* node. Does so optimistically. Will start persisting when cluster count >1 again.
*/
- void setPersistLastNode();
+ QPID_CLIENT_EXTERN void setPersistLastNode();
/**
* Sets the odering policy on the Queue, default ordering is FIFO.
*/
- void setOrdering(QueueOrderingPolicy op);
+ QPID_CLIENT_EXTERN void setOrdering(QueueOrderingPolicy op);
/**
* Use broker defualt sizing ploicy
*/
- void clearSizePolicy();
+ QPID_CLIENT_EXTERN void clearSizePolicy();
/**
* Clear Persist Last Node Policy
*/
- void clearPersistLastNode();
+ QPID_CLIENT_EXTERN void clearPersistLastNode();
/**
* get the key used match LVQ in args for message transfer
*/
- void getLVQKey(std::string& key);
+ QPID_CLIENT_EXTERN void getLVQKey(std::string& key);
/**
* Use default odering policy
*/
- void clearOrdering();
+ QPID_CLIENT_EXTERN void clearOrdering();
/**
* Turns on event generation for this queue (either enqueue only
* or for enqueue and dequeue events); the events can then be
* processed by a regsitered broker plugin.
*/
- void enableQueueEvents(bool enqueueOnly);
+ QPID_CLIENT_EXTERN void enableQueueEvents(bool enqueueOnly);
- static const std::string strMaxCountKey;
- static const std::string strMaxSizeKey;
- static const std::string strTypeKey;
- static const std::string strREJECT;
- static const std::string strFLOW_TO_DISK;
- static const std::string strRING;
- static const std::string strRING_STRICT;
- static const std::string strLastValueQueue;
- static const std::string strPersistLastNode;
- static const std::string strLVQMatchProperty;
- static const std::string strLastValueQueueNoBrowse;
- static const std::string strQueueEventMode;
+ static QPID_CLIENT_EXTERN const std::string strMaxCountKey;
+ static QPID_CLIENT_EXTERN const std::string strMaxSizeKey;
+ static QPID_CLIENT_EXTERN const std::string strTypeKey;
+ static QPID_CLIENT_EXTERN const std::string strREJECT;
+ static QPID_CLIENT_EXTERN const std::string strFLOW_TO_DISK;
+ static QPID_CLIENT_EXTERN const std::string strRING;
+ static QPID_CLIENT_EXTERN const std::string strRING_STRICT;
+ static QPID_CLIENT_EXTERN const std::string strLastValueQueue;
+ static QPID_CLIENT_EXTERN const std::string strPersistLastNode;
+ static QPID_CLIENT_EXTERN const std::string strLVQMatchProperty;
+ static QPID_CLIENT_EXTERN const std::string strLastValueQueueNoBrowse;
+ static QPID_CLIENT_EXTERN const std::string strQueueEventMode;
};
}
diff --git a/qpid/cpp/src/qpid/client/SessionBase_0_10.h b/qpid/cpp/src/qpid/client/SessionBase_0_10.h
index 091c977053..3ae21936f6 100644
--- a/qpid/cpp/src/qpid/client/SessionBase_0_10.h
+++ b/qpid/cpp/src/qpid/client/SessionBase_0_10.h
@@ -33,6 +33,7 @@
#include "qpid/client/SessionImpl.h"
#include "qpid/client/TypedResult.h"
#include "qpid/shared_ptr.h"
+#include "qpid/client/ClientImportExport.h"
#include <string>
namespace qpid {
@@ -65,19 +66,19 @@ class SessionBase_0_10 {
typedef framing::TransferContent DefaultContent;
///@internal
- SessionBase_0_10();
- ~SessionBase_0_10();
+ QPID_CLIENT_EXTERN SessionBase_0_10();
+ QPID_CLIENT_EXTERN ~SessionBase_0_10();
/** Get the next message frame-set from the session. */
- framing::FrameSet::shared_ptr get();
+ QPID_CLIENT_EXTERN framing::FrameSet::shared_ptr get();
/** Get the session ID */
- SessionId getId() const;
+ QPID_CLIENT_EXTERN SessionId getId() const;
/** Close the session.
* A session is automatically closed when all handles to it are destroyed.
*/
- void close();
+ QPID_CLIENT_EXTERN void close();
/**
* Synchronize the session: sync() waits until all commands issued
@@ -88,25 +89,25 @@ class SessionBase_0_10 {
* AsyncSession::executionSync() directly in the unusual event
* that you want to do an asynchronous sync.
*/
- void sync();
+ QPID_CLIENT_EXTERN void sync();
/** Set the timeout for this session. */
- uint32_t timeout(uint32_t seconds);
+ QPID_CLIENT_EXTERN uint32_t timeout(uint32_t seconds);
/** Suspend the session - detach it from its connection */
- void suspend();
+ QPID_CLIENT_EXTERN void suspend();
/** Resume a suspended session with a new connection */
- void resume(Connection);
+ QPID_CLIENT_EXTERN void resume(Connection);
/** Get the channel associated with this session */
- uint16_t getChannel() const;
+ QPID_CLIENT_EXTERN uint16_t getChannel() const;
- Execution& getExecution();
- void flush();
- void markCompleted(const framing::SequenceSet& ids, bool notifyPeer);
- void markCompleted(const framing::SequenceNumber& id, bool cumulative, bool notifyPeer);
- void sendCompletion();
+ QPID_CLIENT_EXTERN Execution& getExecution();
+ QPID_CLIENT_EXTERN void flush();
+ QPID_CLIENT_EXTERN void markCompleted(const framing::SequenceSet& ids, bool notifyPeer);
+ QPID_CLIENT_EXTERN void markCompleted(const framing::SequenceNumber& id, bool cumulative, bool notifyPeer);
+ QPID_CLIENT_EXTERN void sendCompletion();
protected:
boost::shared_ptr<SessionImpl> impl;
diff --git a/qpid/cpp/src/qpid/client/SessionImpl.cpp b/qpid/cpp/src/qpid/client/SessionImpl.cpp
index ee542a9cf8..5df376efa0 100644
--- a/qpid/cpp/src/qpid/client/SessionImpl.cpp
+++ b/qpid/cpp/src/qpid/client/SessionImpl.cpp
@@ -512,6 +512,7 @@ void SessionImpl::detach(const std::string& _name)
if (id.getName() != _name) throw InternalErrorException("Incorrect session name");
setState(DETACHED);
QPID_LOG(info, "Session detached by peer: " << id);
+ proxy.detached(_name, DETACH_CODE_NORMAL);
}
void SessionImpl::detached(const std::string& _name, uint8_t _code) {
@@ -744,7 +745,8 @@ void SessionImpl::assertOpen() const
void SessionImpl::handleClosed()
{
- demux.close(exceptionHolder.empty() ? new ClosedException() : exceptionHolder);
+ demux.close(exceptionHolder.empty() ?
+ sys::ExceptionHolder(new ClosedException()) : exceptionHolder);
results.close();
}
diff --git a/qpid/cpp/src/qpid/client/SslConnector.cpp b/qpid/cpp/src/qpid/client/SslConnector.cpp
index 75c3f5677e..a4298dd4ca 100644
--- a/qpid/cpp/src/qpid/client/SslConnector.cpp
+++ b/qpid/cpp/src/qpid/client/SslConnector.cpp
@@ -221,6 +221,7 @@ bool SslConnector::closeInternal() {
bool ret = !closed;
if (!closed) {
closed = true;
+ aio->queueForDeletion();
poller->shutdown();
}
if (!joined && receiver.id() != Thread::current().id()) {
@@ -386,7 +387,6 @@ void SslConnector::run(){
aio->start(poller);
d.run();
- aio->queueForDeletion();
socket.close();
} catch (const std::exception& e) {
QPID_LOG(error, e.what());
diff --git a/qpid/cpp/src/qpid/client/Subscription.h b/qpid/cpp/src/qpid/client/Subscription.h
index 47bb5d42a5..43c6100254 100644
--- a/qpid/cpp/src/qpid/client/Subscription.h
+++ b/qpid/cpp/src/qpid/client/Subscription.h
@@ -26,6 +26,7 @@
#include "qpid/client/SubscriptionSettings.h"
#include "qpid/client/Handle.h"
#include "qpid/client/Message.h"
+#include "qpid/client/ClientImportExport.h"
namespace qpid {
namespace client {
@@ -39,74 +40,74 @@ class SubscriptionManager;
*/
class Subscription : public Handle<SubscriptionImpl> {
public:
- Subscription(SubscriptionImpl* si=0) : Handle<SubscriptionImpl>(si) {}
+ QPID_CLIENT_EXTERN Subscription(SubscriptionImpl* si=0) : Handle<SubscriptionImpl>(si) {}
- /** The name of the subsctription, used as the "destination" for messages from the broker.
+ /** The name of the subscription, used as the "destination" for messages from the broker.
* Usually the same as the queue name but can be set differently.
*/
- std::string getName() const;
+ QPID_CLIENT_EXTERN std::string getName() const;
/** Name of the queue this subscription subscribes to */
- std::string getQueue() const;
+ QPID_CLIENT_EXTERN std::string getQueue() const;
/** Get the flow control and acknowledgement settings for this subscription */
- const SubscriptionSettings& getSettings() const;
+ QPID_CLIENT_EXTERN const SubscriptionSettings& getSettings() const;
/** Set the flow control parameters */
- void setFlowControl(const FlowControl&);
+ QPID_CLIENT_EXTERN void setFlowControl(const FlowControl&);
/** Automatically acknowledge (acquire and accept) batches of n messages.
* You can disable auto-acknowledgement by setting n=0, and use acquire() and accept()
* to manually acquire and accept messages.
*/
- void setAutoAck(unsigned int n);
+ QPID_CLIENT_EXTERN void setAutoAck(unsigned int n);
/** Get the set of ID's for messages received by this subscription but not yet acquired.
* This will always be empty if getSettings().acquireMode=ACQUIRE_MODE_PRE_ACQUIRED
*/
- SequenceSet getUnacquired() const;
+ QPID_CLIENT_EXTERN SequenceSet getUnacquired() const;
/** Get the set of ID's for messages received by this subscription but not yet accepted. */
- SequenceSet getUnaccepted() const;
+ QPID_CLIENT_EXTERN SequenceSet getUnaccepted() const;
/** Acquire messageIds and remove them from the unacquired set.
* oAdd them to the unaccepted set if getSettings().acceptMode == ACCEPT_MODE_EXPLICIT.
*/
- void acquire(const SequenceSet& messageIds);
+ QPID_CLIENT_EXTERN void acquire(const SequenceSet& messageIds);
/** Accept messageIds and remove them from the unaccepted set.
*@pre messageIds is a subset of getUnaccepted()
*/
- void accept(const SequenceSet& messageIds);
+ QPID_CLIENT_EXTERN void accept(const SequenceSet& messageIds);
/** Release messageIds and remove them from the unaccepted set.
*@pre messageIds is a subset of getUnaccepted()
*/
- void release(const SequenceSet& messageIds);
+ QPID_CLIENT_EXTERN void release(const SequenceSet& messageIds);
/* Acquire a single message */
- void acquire(const Message& m) { acquire(SequenceSet(m.getId())); }
+ QPID_CLIENT_EXTERN void acquire(const Message& m) { acquire(SequenceSet(m.getId())); }
/* Accept a single message */
- void accept(const Message& m) { accept(SequenceSet(m.getId())); }
+ QPID_CLIENT_EXTERN void accept(const Message& m) { accept(SequenceSet(m.getId())); }
/* Release a single message */
- void release(const Message& m) { release(SequenceSet(m.getId())); }
+ QPID_CLIENT_EXTERN void release(const Message& m) { release(SequenceSet(m.getId())); }
/** Get the session associated with this subscription */
- Session getSession() const;
+ QPID_CLIENT_EXTERN Session getSession() const;
/** Get the subscription manager associated with this subscription */
- SubscriptionManager& getSubscriptionManager() const;
+ QPID_CLIENT_EXTERN SubscriptionManager& getSubscriptionManager() const;
/** Cancel the subscription. */
- void cancel();
+ QPID_CLIENT_EXTERN void cancel();
/** Grant the specified amount of message credit */
- void grantMessageCredit(uint32_t);
+ QPID_CLIENT_EXTERN void grantMessageCredit(uint32_t);
/** Grant the specified amount of byte credit */
- void grantByteCredit(uint32_t);
+ QPID_CLIENT_EXTERN void grantByteCredit(uint32_t);
friend class SubscriptionManager;
};
diff --git a/qpid/cpp/src/qpid/client/SubscriptionImpl.h b/qpid/cpp/src/qpid/client/SubscriptionImpl.h
index 74fbacb951..e2b970ce05 100644
--- a/qpid/cpp/src/qpid/client/SubscriptionImpl.h
+++ b/qpid/cpp/src/qpid/client/SubscriptionImpl.h
@@ -30,6 +30,7 @@
#include "qpid/framing/SequenceSet.h"
#include "qpid/sys/Mutex.h"
#include "qpid/RefCounted.h"
+#include "qpid/client/ClientImportExport.h"
#include <memory>
namespace qpid {
@@ -39,62 +40,62 @@ class SubscriptionManager;
class SubscriptionImpl : public RefCounted, public MessageListener {
public:
- SubscriptionImpl(SubscriptionManager&, const std::string& queue,
+ QPID_CLIENT_EXTERN SubscriptionImpl(SubscriptionManager&, const std::string& queue,
const SubscriptionSettings&, const std::string& name, MessageListener* =0);
/** The name of the subsctription, used as the "destination" for messages from the broker.
* Usually the same as the queue name but can be set differently.
*/
- std::string getName() const;
+ QPID_CLIENT_EXTERN std::string getName() const;
/** Name of the queue this subscription subscribes to */
- std::string getQueue() const;
+ QPID_CLIENT_EXTERN std::string getQueue() const;
/** Get the flow control and acknowledgement settings for this subscription */
- const SubscriptionSettings& getSettings() const;
+ QPID_CLIENT_EXTERN const SubscriptionSettings& getSettings() const;
/** Set the flow control parameters */
- void setFlowControl(const FlowControl&);
+ QPID_CLIENT_EXTERN void setFlowControl(const FlowControl&);
/** Automatically acknowledge (acquire and accept) batches of n messages.
* You can disable auto-acknowledgement by setting n=0, and use acquire() and accept()
* to manually acquire and accept messages.
*/
- void setAutoAck(size_t n);
+ QPID_CLIENT_EXTERN void setAutoAck(size_t n);
/** Get the set of ID's for messages received by this subscription but not yet acquired.
* This will always be empty if acquireMode=ACQUIRE_MODE_PRE_ACQUIRED
*/
- SequenceSet getUnacquired() const;
+ QPID_CLIENT_EXTERN SequenceSet getUnacquired() const;
/** Get the set of ID's for messages acquired by this subscription but not yet accepted. */
- SequenceSet getUnaccepted() const;
+ QPID_CLIENT_EXTERN SequenceSet getUnaccepted() const;
/** Acquire messageIds and remove them from the un-acquired set for the session. */
- void acquire(const SequenceSet& messageIds);
+ QPID_CLIENT_EXTERN void acquire(const SequenceSet& messageIds);
/** Accept messageIds and remove them from the un-accepted set for the session. */
- void accept(const SequenceSet& messageIds);
+ QPID_CLIENT_EXTERN void accept(const SequenceSet& messageIds);
/** Release messageIds and remove them from the un-accepted set for the session. */
- void release(const SequenceSet& messageIds);
+ QPID_CLIENT_EXTERN void release(const SequenceSet& messageIds);
/** Get the session associated with this subscription */
- Session getSession() const;
+ QPID_CLIENT_EXTERN Session getSession() const;
/** Get the subscription manager associated with this subscription */
- SubscriptionManager& getSubscriptionManager() const;
+ QPID_CLIENT_EXTERN SubscriptionManager& getSubscriptionManager() const;
/** Send subscription request and issue appropriate flow control commands. */
- void subscribe();
+ QPID_CLIENT_EXTERN void subscribe();
/** Cancel the subscription. */
- void cancel();
+ QPID_CLIENT_EXTERN void cancel();
/** Grant specified credit for this subscription **/
- void grantCredit(framing::message::CreditUnit unit, uint32_t value);
+ QPID_CLIENT_EXTERN void grantCredit(framing::message::CreditUnit unit, uint32_t value);
- void received(Message&);
+ QPID_CLIENT_EXTERN void received(Message&);
/**
* Set up demux diversion for messages sent to this subscription
@@ -104,7 +105,7 @@ class SubscriptionImpl : public RefCounted, public MessageListener {
* Cancel any demux diversion that may have been setup for this
* subscription
*/
- void cancelDiversion();
+ QPID_CLIENT_EXTERN void cancelDiversion();
private:
diff --git a/qpid/cpp/src/qpid/client/SubscriptionManager.h b/qpid/cpp/src/qpid/client/SubscriptionManager.h
index 6b45092931..91ad2b6d56 100644
--- a/qpid/cpp/src/qpid/client/SubscriptionManager.h
+++ b/qpid/cpp/src/qpid/client/SubscriptionManager.h
@@ -30,6 +30,7 @@
#include <qpid/client/LocalQueue.h>
#include <qpid/client/Subscription.h>
#include <qpid/sys/Runnable.h>
+#include <qpid/client/ClientImportExport.h>
#include <set>
#include <sstream>
@@ -97,7 +98,7 @@ class SubscriptionManager : public sys::Runnable
{
public:
/** Create a new SubscriptionManager associated with a session */
- SubscriptionManager(const Session& session);
+ QPID_CLIENT_EXTERN SubscriptionManager(const Session& session);
/**
* Subscribe a MessagesListener to receive messages from queue.
@@ -110,7 +111,7 @@ class SubscriptionManager : public sys::Runnable
*@param settings settings for the subscription.
*@param name unique destination name for the subscription, defaults to queue name.
*/
- Subscription subscribe(MessageListener& listener,
+ QPID_CLIENT_EXTERN Subscription subscribe(MessageListener& listener,
const std::string& queue,
const SubscriptionSettings& settings,
const std::string& name=std::string());
@@ -125,7 +126,7 @@ class SubscriptionManager : public sys::Runnable
*@param name unique destination name for the subscription, defaults to queue name.
* If not specified, the queue name is used.
*/
- Subscription subscribe(LocalQueue& localQueue,
+ QPID_CLIENT_EXTERN Subscription subscribe(LocalQueue& localQueue,
const std::string& queue,
const SubscriptionSettings& settings,
const std::string& name=std::string());
@@ -141,7 +142,7 @@ class SubscriptionManager : public sys::Runnable
*@param name unique destination name for the subscription, defaults to queue name.
* If not specified, the queue name is used.
*/
- Subscription subscribe(MessageListener& listener,
+ QPID_CLIENT_EXTERN Subscription subscribe(MessageListener& listener,
const std::string& queue,
const std::string& name=std::string());
@@ -154,7 +155,7 @@ class SubscriptionManager : public sys::Runnable
*@param name unique destination name for the subscription, defaults to queue name.
* If not specified, the queue name is used.
*/
- Subscription subscribe(LocalQueue& localQueue,
+ QPID_CLIENT_EXTERN Subscription subscribe(LocalQueue& localQueue,
const std::string& queue,
const std::string& name=std::string());
@@ -164,53 +165,53 @@ class SubscriptionManager : public sys::Runnable
*@param timeout wait up this timeout for a message to appear.
*@return true if result was set, false if no message available after timeout.
*/
- bool get(Message& result, const std::string& queue, sys::Duration timeout=0);
+ QPID_CLIENT_EXTERN bool get(Message& result, const std::string& queue, sys::Duration timeout=0);
/** Get a single message from a queue.
*@param timeout wait up this timeout for a message to appear.
*@return message from the queue.
*@throw Exception if the timeout is exceeded.
*/
- Message get(const std::string& queue, sys::Duration timeout=sys::TIME_INFINITE);
+ QPID_CLIENT_EXTERN Message get(const std::string& queue, sys::Duration timeout=sys::TIME_INFINITE);
/** Get a subscription by name.
*@throw Exception if not found.
*/
- Subscription getSubscription(const std::string& name) const;
+ QPID_CLIENT_EXTERN Subscription getSubscription(const std::string& name) const;
/** Cancel a subscription. See also: Subscription.cancel() */
- void cancel(const std::string& name);
+ QPID_CLIENT_EXTERN void cancel(const std::string& name);
/** Deliver messages in the current thread until stop() is called.
* Only one thread may be running in a SubscriptionManager at a time.
* @see run
*/
- void run();
+ QPID_CLIENT_EXTERN void run();
/** Start a new thread to deliver messages.
* Only one thread may be running in a SubscriptionManager at a time.
* @see start
*/
- void start();
+ QPID_CLIENT_EXTERN void start();
/**
* Wait for the thread started by a call to start() to complete.
*/
- void wait();
+ QPID_CLIENT_EXTERN void wait();
/** If set true, run() will stop when all subscriptions
* are cancelled. If false, run will only stop when stop()
* is called. True by default.
*/
- void setAutoStop(bool set=true);
+ QPID_CLIENT_EXTERN void setAutoStop(bool set=true);
/** Stop delivery. Causes run() to return, or the thread started with start() to exit. */
- void stop();
+ QPID_CLIENT_EXTERN void stop();
static const uint32_t UNLIMITED=0xFFFFFFFF;
/** Set the flow control for a subscription. */
- void setFlowControl(const std::string& name, const FlowControl& flow);
+ QPID_CLIENT_EXTERN void setFlowControl(const std::string& name, const FlowControl& flow);
/** Set the flow control for a subscription.
*@param name: name of the subscription.
@@ -218,22 +219,22 @@ class SubscriptionManager : public sys::Runnable
*@param bytes: byte credit.
*@param window: if true use window-based flow control.
*/
- void setFlowControl(const std::string& name, uint32_t messages, uint32_t bytes, bool window=true);
+ QPID_CLIENT_EXTERN void setFlowControl(const std::string& name, uint32_t messages, uint32_t bytes, bool window=true);
/** Set the default settings for subscribe() calls that don't
* include a SubscriptionSettings parameter.
*/
- void setDefaultSettings(const SubscriptionSettings& s) { defaultSettings = s; }
+ QPID_CLIENT_EXTERN void setDefaultSettings(const SubscriptionSettings& s) { defaultSettings = s; }
/** Get the default settings for subscribe() calls that don't
* include a SubscriptionSettings parameter.
*/
- const SubscriptionSettings& getDefaultSettings() const { return defaultSettings; }
+ QPID_CLIENT_EXTERN const SubscriptionSettings& getDefaultSettings() const { return defaultSettings; }
/** Get the default settings for subscribe() calls that don't
* include a SubscriptionSettings parameter.
*/
- SubscriptionSettings& getDefaultSettings() { return defaultSettings; }
+ QPID_CLIENT_EXTERN SubscriptionSettings& getDefaultSettings() { return defaultSettings; }
/**
* Set the default flow control settings for subscribe() calls
@@ -243,7 +244,7 @@ class SubscriptionManager : public sys::Runnable
*@param bytes: byte credit.
*@param window: if true use window-based flow control.
*/
- void setFlowControl(uint32_t messages, uint32_t bytes, bool window=true) {
+ QPID_CLIENT_EXTERN void setFlowControl(uint32_t messages, uint32_t bytes, bool window=true) {
defaultSettings.flowControl = FlowControl(messages, bytes, window);
}
@@ -251,16 +252,16 @@ class SubscriptionManager : public sys::Runnable
*Set the default accept-mode for subscribe() calls that don't
*include a SubscriptionSettings parameter.
*/
- void setAcceptMode(AcceptMode mode) { defaultSettings.acceptMode = mode; }
+ QPID_CLIENT_EXTERN void setAcceptMode(AcceptMode mode) { defaultSettings.acceptMode = mode; }
/**
* Set the default acquire-mode subscribe()s that don't specify SubscriptionSettings.
*/
- void setAcquireMode(AcquireMode mode) { defaultSettings.acquireMode = mode; }
+ QPID_CLIENT_EXTERN void setAcquireMode(AcquireMode mode) { defaultSettings.acquireMode = mode; }
- void registerFailoverHandler ( boost::function<void ()> fh );
+ QPID_CLIENT_EXTERN void registerFailoverHandler ( boost::function<void ()> fh );
- Session getSession() const;
+ QPID_CLIENT_EXTERN Session getSession() const;
private:
mutable sys::Mutex lock;
diff --git a/qpid/cpp/src/qpid/client/windows/SaslFactory.cpp b/qpid/cpp/src/qpid/client/windows/SaslFactory.cpp
new file mode 100644
index 0000000000..58956609a4
--- /dev/null
+++ b/qpid/cpp/src/qpid/client/windows/SaslFactory.cpp
@@ -0,0 +1,139 @@
+/*
+ *
+ * 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.
+ *
+ */
+
+#include "qpid/client/SaslFactory.h"
+#include "qpid/client/ConnectionSettings.h"
+
+#include "qpid/Exception.h"
+#include "qpid/framing/reply_exceptions.h"
+#include "qpid/sys/SecurityLayer.h"
+#include "qpid/log/Statement.h"
+
+#include "boost/tokenizer.hpp"
+
+namespace qpid {
+namespace client {
+
+using qpid::sys::SecurityLayer;
+using qpid::framing::InternalErrorException;
+
+class WindowsSasl : public Sasl
+{
+ public:
+ WindowsSasl(const ConnectionSettings&);
+ ~WindowsSasl();
+ std::string start(const std::string& mechanisms);
+ std::string step(const std::string& challenge);
+ std::string getMechanism();
+ std::auto_ptr<SecurityLayer> getSecurityLayer(uint16_t maxFrameSize);
+ private:
+ ConnectionSettings settings;
+ std::string mechanism;
+};
+
+qpid::sys::Mutex SaslFactory::lock;
+std::auto_ptr<SaslFactory> SaslFactory::instance;
+
+SaslFactory::SaslFactory()
+{
+}
+
+SaslFactory::~SaslFactory()
+{
+}
+
+SaslFactory& SaslFactory::getInstance()
+{
+ qpid::sys::Mutex::ScopedLock l(lock);
+ if (!instance.get()) {
+ instance = std::auto_ptr<SaslFactory>(new SaslFactory());
+ }
+ return *instance;
+}
+
+std::auto_ptr<Sasl> SaslFactory::create(const ConnectionSettings& settings)
+{
+ std::auto_ptr<Sasl> sasl(new WindowsSasl(settings));
+ return sasl;
+}
+
+namespace {
+ const std::string ANONYMOUS = "ANONYMOUS";
+ const std::string PLAIN = "PLAIN";
+}
+
+WindowsSasl::WindowsSasl(const ConnectionSettings& s)
+ : settings(s)
+{
+}
+
+WindowsSasl::~WindowsSasl()
+{
+}
+
+std::string WindowsSasl::start(const std::string& mechanisms)
+{
+ QPID_LOG(debug, "WindowsSasl::start(" << mechanisms << ")");
+
+ typedef boost::tokenizer<boost::char_separator<char> > tokenizer;
+ boost::char_separator<char> sep(" ");
+ bool havePlain = false;
+ bool haveAnon = false;
+ tokenizer mechs(mechanisms, sep);
+ for (tokenizer::iterator mech = mechs.begin();
+ mech != mechs.end();
+ ++mech) {
+ if (*mech == ANONYMOUS)
+ haveAnon = true;
+ else if (*mech == PLAIN)
+ havePlain = true;
+ }
+ if (!haveAnon && !havePlain)
+ throw InternalErrorException(QPID_MSG("Sasl error: no common mechanism"));
+
+ std::string resp = "";
+ if (havePlain) {
+ mechanism = PLAIN;
+ resp = ((char)0) + settings.username + ((char)0) + settings.password;
+ }
+ else {
+ mechanism = ANONYMOUS;
+ }
+ return resp;
+}
+
+std::string WindowsSasl::step(const std::string& challenge)
+{
+ // Shouldn't get this for PLAIN...
+ throw InternalErrorException(QPID_MSG("Sasl step error"));
+}
+
+std::string WindowsSasl::getMechanism()
+{
+ return mechanism;
+}
+
+std::auto_ptr<SecurityLayer> WindowsSasl::getSecurityLayer(uint16_t maxFrameSize)
+{
+ return std::auto_ptr<SecurityLayer>(0);
+}
+
+}} // namespace qpid::client
diff --git a/qpid/cpp/src/qpid/cluster/Cluster.cpp b/qpid/cpp/src/qpid/cluster/Cluster.cpp
index 6221b0054c..f8e412f1e6 100644
--- a/qpid/cpp/src/qpid/cluster/Cluster.cpp
+++ b/qpid/cpp/src/qpid/cluster/Cluster.cpp
@@ -21,7 +21,9 @@
#include "Connection.h"
#include "UpdateClient.h"
#include "FailoverExchange.h"
+#include "UpdateExchange.h"
+#include "qpid/assert.h"
#include "qmf/org/apache/qpid/cluster/ArgsClusterStopClusterNode.h"
#include "qmf/org/apache/qpid/cluster/Package.h"
#include "qpid/broker/Broker.h"
@@ -91,9 +93,10 @@ Cluster::Cluster(const ClusterSettings& set, broker::Broker& b) :
cpg(*this),
name(settings.name),
myUrl(settings.url.empty() ? Url() : Url(settings.url)),
- myId(cpg.self()),
+ self(cpg.self()),
readMax(settings.readMax),
writeEstimate(settings.writeEstimate),
+ expiryPolicy(new ExpiryPolicy(mcast, self, broker.getTimer())),
mcast(cpg, poller, boost::bind(&Cluster::leave, this)),
dispatcher(cpg, poller, boost::bind(&Cluster::leave, this)),
deliverEventQueue(boost::bind(&Cluster::deliveredEvent, this, _1),
@@ -104,15 +107,12 @@ Cluster::Cluster(const ClusterSettings& set, broker::Broker& b) :
boost::bind(&Cluster::leave, this),
"Error delivering frames",
poller),
- connections(*this),
- decoder(boost::bind(&PollableFrameQueue::push, &deliverFrameQueue, _1), connections),
- expiryPolicy(new ExpiryPolicy(boost::bind(&Cluster::isLeader, this), mcast, myId, broker.getTimer())),
- frameId(0),
initialized(false),
+ decoder(boost::bind(&Cluster::deliverFrame, this, _1)),
+ discarding(true),
state(INIT),
lastSize(0),
- lastBroker(false),
- sequence(0)
+ lastBroker(false)
{
mAgent = ManagementAgent::Singleton::getInstance();
if (mAgent != 0){
@@ -122,7 +122,13 @@ Cluster::Cluster(const ClusterSettings& set, broker::Broker& b) :
mgmtObject->set_status("JOINING");
}
+ // Failover exchange provides membership updates to clients.
failoverExchange.reset(new FailoverExchange(this));
+ broker.getExchanges().registerExchange(failoverExchange);
+
+ // Update exchange is used during updates to replicate messages without modifying delivery-properties.exchange.
+ broker.getExchanges().registerExchange(boost::shared_ptr<broker::Exchange>(new UpdateExchange(this)));
+
if (settings.quorum) quorum.init();
cpg.join(name);
// pump the CPG dispatch manually till we get initialized.
@@ -149,21 +155,21 @@ void Cluster::initialize() {
// Called in connection thread to insert a client connection.
void Cluster::addLocalConnection(const boost::intrusive_ptr<Connection>& c) {
- Lock l(lock);
- connections.insert(c);
+ localConnections.insert(c);
}
// Called in connection thread to insert an updated shadow connection.
void Cluster::addShadowConnection(const boost::intrusive_ptr<Connection>& c) {
- Lock l(lock);
- assert(state <= UPDATEE); // Only during update.
- connections.insert(c);
+ // Safe to use connections here because we're pre-catchup, either
+ // discarding or stalled, so deliveredFrame is not processing any
+ // connection events.
+ assert(discarding);
+ connections.insert(ConnectionMap::value_type(c->getId(), c));
}
+// Called by Connection::deliverClose() in deliverFrameQueue thread.
void Cluster::erase(const ConnectionId& id) {
- // Called only by Connection::deliverClose in deliver thread, no need to lock.
connections.erase(id);
- decoder.erase(id);
}
std::vector<string> Cluster::getIds() const {
@@ -193,7 +199,6 @@ void Cluster::leave(Lock&) {
if (state != LEFT) {
state = LEFT;
QPID_LOG(notice, *this << " leaving cluster " << name);
- connections.clear();
try { broker.shutdown(); }
catch (const std::exception& e) {
QPID_LOG(critical, *this << " error during broker shutdown: " << e.what());
@@ -213,52 +218,88 @@ void Cluster::deliver(
MemberId from(nodeid, pid);
framing::Buffer buf(static_cast<char*>(msg), msg_len);
Event e(Event::decodeCopy(from, buf));
- e.setSequence(sequence++);
- if (from == myId) // Record self-deliveries for flow control.
+ if (from == self) // Record self-deliveries for flow control.
mcast.selfDeliver(e);
- deliver(e);
+ deliverEvent(e);
}
-void Cluster::deliver(const Event& e) {
- if (state == LEFT) return;
- QPID_LATENCY_INIT(e);
+void Cluster::deliverEvent(const Event& e) {
deliverEventQueue.push(e);
}
-// Handler for deliverEventQueue
+void Cluster::deliverFrame(const EventFrame& e) {
+ deliverFrameQueue.push(e);
+}
+
+// Handler for deliverEventQueue.
+// This thread decodes frames from events.
void Cluster::deliveredEvent(const Event& e) {
- QPID_LATENCY_RECORD("delivered event queue", e);
- Buffer buf(const_cast<char*>(e.getData()), e.getSize());
- if (e.getType() == CONTROL) {
- AMQFrame frame;
- while (frame.decode(buf))
- deliverFrameQueue.push(EventFrame(e, frame));
+ QPID_LOG(trace, *this << " DLVR: " << e);
+ if (e.isCluster()) {
+ EventFrame ef(e, e.getFrame());
+ // Stop the deliverEventQueue on update offers.
+ // This preserves the connection decoder fragments for an update.
+ ClusterUpdateOfferBody* offer = dynamic_cast<ClusterUpdateOfferBody*>(ef.frame.getBody());
+ if (offer)
+ deliverEventQueue.stop();
+ deliverFrame(ef);
}
- else if (e.getType() == DATA)
- decoder.decode(e, e.getData());
+ else if(!discarding) {
+ if (e.isControl())
+ deliverFrame(EventFrame(e, e.getFrame()));
+ else
+ decoder.decode(e, e.getData());
+}
+ else // Discard connection events if discarding is set.
+ QPID_LOG(trace, *this << " DROP: " << e);
}
-// Handler for deliverFrameQueue
+// Handler for deliverFrameQueue.
+// This thread executes the main logic.
void Cluster::deliveredFrame(const EventFrame& e) {
Mutex::ScopedLock l(lock);
- const_cast<AMQFrame&>(e.frame).setClusterId(frameId++);
- QPID_LOG(trace, *this << " DLVR: " << e);
- QPID_LATENCY_RECORD("delivered frame queue", e.frame);
- if (e.isCluster()) { // Cluster control frame
+ if (e.isCluster()) {
+ QPID_LOG(trace, *this << " DLVR: " << e);
ClusterDispatcher dispatch(*this, e.connectionId.getMember(), l);
if (!framing::invoke(dispatch, *e.frame.getBody()).wasHandled())
throw Exception(QPID_MSG("Invalid cluster control"));
}
- else { // Connection frame.
- if (state <= UPDATEE) {
- QPID_LOG(trace, *this << " DROP: " << e);
- return;
- }
- boost::intrusive_ptr<Connection> connection = connections.get(e.connectionId);
- if (connection) // Ignore frames to closed local connections.
+ else if (state >= CATCHUP) {
+ QPID_LOG(trace, *this << " DLVR: " << e);
+ ConnectionPtr connection = getConnection(e.connectionId, l);
+ if (connection)
connection->deliveredFrame(e);
}
- QPID_LATENCY_RECORD("processed", e.frame);
+ else // Drop connection frames while state < CATCHUP
+ QPID_LOG(trace, *this << " DROP: " << e);
+}
+
+// Called in deliverFrameQueue thread
+ConnectionPtr Cluster::getConnection(const ConnectionId& id, Lock&) {
+ ConnectionPtr cp;
+ ConnectionMap::iterator i = connections.find(id);
+ if (i != connections.end())
+ cp = i->second;
+ else {
+ if(id.getMember() == self)
+ cp = localConnections.getErase(id);
+ else {
+ // New remote connection, create a shadow.
+ std::ostringstream mgmtId;
+ mgmtId << id;
+ cp = new Connection(*this, shadowOut, mgmtId.str(), id);
+ }
+ if (cp)
+ connections.insert(ConnectionMap::value_type(id, cp));
+ }
+ return cp;
+}
+
+Cluster::ConnectionVector Cluster::getConnections(Lock&) {
+ ConnectionVector result(connections.size());
+ std::transform(connections.begin(), connections.end(), result.begin(),
+ boost::bind(&ConnectionMap::value_type::second, _1));
+ return result;
}
struct AddrList {
@@ -306,42 +347,45 @@ void Cluster::configChange (
std::string addresses;
for (cpg_address* p = current; p < current+nCurrent; ++p)
addresses.append(MemberId(*p).str());
- deliver(Event::control(ClusterConfigChangeBody(ProtocolVersion(), addresses), myId));
+ deliverEvent(Event::control(ClusterConfigChangeBody(ProtocolVersion(), addresses), self));
}
void Cluster::setReady(Lock&) {
state = READY;
if (mgmtObject!=0) mgmtObject->set_status("ACTIVE");
mcast.release();
+ broker.getQueueEvents().enable();
}
void Cluster::configChange(const MemberId&, const std::string& addresses, Lock& l) {
bool memberChange = map.configChange(addresses);
if (state == LEFT) return;
- if (!map.isAlive(myId)) { // Final config change.
+ if (!map.isAlive(self)) { // Final config change.
leave(l);
return;
}
if (state == INIT) { // First configChange
if (map.aliveCount() == 1) {
- setClusterId(true);
+ setClusterId(true, l);
+ discarding = false;
setReady(l);
- map = ClusterMap(myId, myUrl, true);
+ map = ClusterMap(self, myUrl, true);
memberUpdate(l);
QPID_LOG(notice, *this << " first in cluster");
}
else { // Joining established group.
state = JOINER;
QPID_LOG(info, *this << " joining cluster: " << map);
- mcast.mcastControl(ClusterUpdateRequestBody(ProtocolVersion(), myUrl.str()), myId);
+ mcast.mcastControl(ClusterUpdateRequestBody(ProtocolVersion(), myUrl.str()), self);
elders = map.getAlive();
- elders.erase(myId);
+ elders.erase(self);
broker.getLinks().setPassive(true);
+ broker.getQueueEvents().disable();
}
- }
- else if (state >= READY && memberChange) {
+ }
+ else if (state >= CATCHUP && memberChange) {
memberUpdate(l);
elders = ClusterMap::intersection(elders, map.getAlive());
if (elders.empty()) {
@@ -351,13 +395,11 @@ void Cluster::configChange(const MemberId&, const std::string& addresses, Lock&
}
}
-bool Cluster::isLeader() const { return elders.empty(); }
-
-void Cluster::tryMakeOffer(const MemberId& id, Lock& ) {
+void Cluster::makeOffer(const MemberId& id, Lock& ) {
if (state == READY && map.isJoiner(id)) {
state = OFFER;
QPID_LOG(info, *this << " send update-offer to " << id);
- mcast.mcastControl(ClusterUpdateOfferBody(ProtocolVersion(), id, clusterId), myId);
+ mcast.mcastControl(ClusterUpdateOfferBody(ProtocolVersion(), id, clusterId), self);
}
}
@@ -367,88 +409,89 @@ void Cluster::tryMakeOffer(const MemberId& id, Lock& ) {
// callbacks will be invoked.
//
void Cluster::brokerShutdown() {
- if (state != LEFT) {
- try { cpg.shutdown(); }
- catch (const std::exception& e) {
- QPID_LOG(error, *this << " shutting down CPG: " << e.what());
- }
+ try { cpg.shutdown(); }
+ catch (const std::exception& e) {
+ QPID_LOG(error, *this << " shutting down CPG: " << e.what());
}
delete this;
}
void Cluster::updateRequest(const MemberId& id, const std::string& url, Lock& l) {
map.updateRequest(id, url);
- tryMakeOffer(id, l);
+ makeOffer(id, l);
}
void Cluster::ready(const MemberId& id, const std::string& url, Lock& l) {
if (map.ready(id, Url(url)))
memberUpdate(l);
- if (state == CATCHUP && id == myId) {
+ if (state == CATCHUP && id == self) {
setReady(l);
QPID_LOG(notice, *this << " caught up, active cluster member");
}
}
void Cluster::updateOffer(const MemberId& updater, uint64_t updateeInt, const Uuid& uuid, Lock& l) {
+ // NOTE: deliverEventQueue has been stopped at the update offer by
+ // deliveredEvent in case an update is required.
if (state == LEFT) return;
MemberId updatee(updateeInt);
boost::optional<Url> url = map.updateOffer(updater, updatee);
- if (updater == myId) {
+ if (updater == self) {
assert(state == OFFER);
- if (url) { // My offer was first.
+ if (url) // My offer was first.
updateStart(updatee, *url, l);
- }
else { // Another offer was first.
+ deliverEventQueue.start(); // Don't need to update
setReady(l);
QPID_LOG(info, *this << " cancelled update offer to " << updatee);
- tryMakeOffer(map.firstJoiner(), l); // Maybe make another offer.
+ makeOffer(map.firstJoiner(), l); // Maybe make another offer.
}
}
- else if (updatee == myId && url) {
+ else if (updatee == self && url) {
assert(state == JOINER);
- setClusterId(uuid);
+ setClusterId(uuid, l);
state = UPDATEE;
QPID_LOG(info, *this << " receiving update from " << updater);
- deliverFrameQueue.stop();
checkUpdateIn(l);
}
+ else
+ deliverEventQueue.start(); // Don't need to update
}
-void Cluster::updateStart(const MemberId& updatee, const Url& url, Lock&) {
+void Cluster::updateStart(const MemberId& updatee, const Url& url, Lock& l) {
+ // NOTE: deliverEventQueue is already stopped at the stall point by deliveredEvent.
if (state == LEFT) return;
assert(state == OFFER);
state = UPDATER;
- QPID_LOG(info, *this << " stall for update to " << updatee << " at " << url);
- deliverFrameQueue.stop();
- if (updateThread.id()) updateThread.join(); // Join the previous updatethread.
+ QPID_LOG(info, *this << " sending update to " << updatee << " at " << url);
+ if (updateThread.id())
+ updateThread.join(); // Join the previous updateThread to avoid leaks.
client::ConnectionSettings cs;
cs.username = settings.username;
cs.password = settings.password;
cs.mechanism = settings.mechanism;
updateThread = Thread(
- new UpdateClient(myId, updatee, url, broker, map, frameId, connections.values(),
+ new UpdateClient(self, updatee, url, broker, map, *expiryPolicy, getConnections(l), decoder,
boost::bind(&Cluster::updateOutDone, this),
boost::bind(&Cluster::updateOutError, this, _1),
cs));
}
// Called in update thread.
-void Cluster::updateInDone(const ClusterMap& m, uint64_t fid) {
+void Cluster::updateInDone(const ClusterMap& m) {
Lock l(lock);
updatedMap = m;
- frameId = fid;
checkUpdateIn(l);
}
-void Cluster::checkUpdateIn(Lock& ) {
- if (state == LEFT) return;
+void Cluster::checkUpdateIn(Lock&) {
if (state == UPDATEE && updatedMap) {
map = *updatedMap;
- mcast.mcastControl(ClusterReadyBody(ProtocolVersion(), myUrl.str()), myId);
+ mcast.mcastControl(ClusterReadyBody(ProtocolVersion(), myUrl.str()), self);
state = CATCHUP;
+ discarding = false; // ok to set, we're stalled for update.
QPID_LOG(info, *this << " received update, starting catch-up");
- deliverFrameQueue.start();
+ deliverEventQueue.start();
}
}
@@ -462,8 +505,8 @@ void Cluster::updateOutDone(Lock& l) {
assert(state == UPDATER);
state = READY;
mcast.release();
- deliverFrameQueue.start();
- tryMakeOffer(map.firstJoiner(), l); // Try another offer
+ deliverEventQueue.start(); // Start processing events again.
+ makeOffer(map.firstJoiner(), l); // Try another offer
}
void Cluster::updateOutError(const std::exception& e) {
@@ -487,7 +530,7 @@ Manageable::status_t Cluster::ManagementMethod (uint32_t methodId, Args& args, s
{
_qmf::ArgsClusterStopClusterNode& iargs = (_qmf::ArgsClusterStopClusterNode&) args;
stringstream stream;
- stream << myId;
+ stream << self;
if (iargs.i_brokerId == stream.str())
stopClusterNode(l);
}
@@ -508,7 +551,7 @@ void Cluster::stopClusterNode(Lock& l) {
void Cluster::stopFullCluster(Lock& ) {
QPID_LOG(notice, *this << " shutting down cluster " << name);
- mcast.mcastControl(ClusterShutdownBody(), myId);
+ mcast.mcastControl(ClusterShutdownBody(), self);
}
void Cluster::memberUpdate(Lock& l) {
@@ -518,13 +561,13 @@ void Cluster::memberUpdate(Lock& l) {
size_t size = urls.size();
failoverExchange->setUrls(urls);
- if (size == 1 && lastSize > 1 && state >= READY) {
- QPID_LOG(info, *this << " last broker standing, update queue policies");
+ if (size == 1 && lastSize > 1 && state >= CATCHUP) {
+ QPID_LOG(notice, *this << " last broker standing, update queue policies");
lastBroker = true;
broker.getQueues().updateQueueClusterState(true);
}
else if (size > 1 && lastBroker) {
- QPID_LOG(info, *this << " last broker standing joined by " << size-1 << " replicas, updating queue policies" << size);
+ QPID_LOG(notice, *this << " last broker standing joined by " << size-1 << " replicas, updating queue policies" << size);
lastBroker = false;
broker.getQueues().updateQueueClusterState(false);
}
@@ -546,17 +589,23 @@ void Cluster::memberUpdate(Lock& l) {
mgmtObject->set_memberIDs(idstr);
}
- // Close connections belonging to members that have now been excluded
- connections.update(myId, map);
+ // Erase connections belonging to members that have left the cluster.
+ ConnectionMap::iterator i = connections.begin();
+ while (i != connections.end()) {
+ ConnectionMap::iterator j = i++;
+ MemberId m = j->second->getId().getMember();
+ if (m != self && !map.isMember(m))
+ connections.erase(j);
+ }
}
std::ostream& operator<<(std::ostream& o, const Cluster& cluster) {
static const char* STATE[] = { "INIT", "JOINER", "UPDATEE", "CATCHUP", "READY", "OFFER", "UPDATER", "LEFT" };
- return o << cluster.myId << "(" << STATE[cluster.state] << ")";
+ return o << cluster.self << "(" << STATE[cluster.state] << ")";
}
MemberId Cluster::getId() const {
- return myId; // Immutable, no need to lock.
+ return self; // Immutable, no need to lock.
}
broker::Broker& Cluster::getBroker() const {
@@ -571,11 +620,11 @@ void Cluster::checkQuorum() {
}
}
-void Cluster::setClusterId(const Uuid& uuid) {
+void Cluster::setClusterId(const Uuid& uuid, Lock&) {
clusterId = uuid;
if (mgmtObject) {
stringstream stream;
- stream << myId;
+ stream << self;
mgmtObject->set_clusterID(clusterId.str());
mgmtObject->set_memberID(stream.str());
}
diff --git a/qpid/cpp/src/qpid/cluster/Cluster.h b/qpid/cpp/src/qpid/cluster/Cluster.h
index 8c5eb06ff7..b716e2d781 100644
--- a/qpid/cpp/src/qpid/cluster/Cluster.h
+++ b/qpid/cpp/src/qpid/cluster/Cluster.h
@@ -19,34 +19,34 @@
*
*/
-#include "ClusterSettings.h"
#include "ClusterMap.h"
-#include "ConnectionMap.h"
+#include "ClusterSettings.h"
#include "Cpg.h"
+#include "Decoder.h"
#include "Event.h"
+#include "EventFrame.h"
+#include "ExpiryPolicy.h"
#include "FailoverExchange.h"
+#include "LockedConnectionMap.h"
#include "Multicaster.h"
-#include "EventFrame.h"
#include "NoOpConnectionOutputHandler.h"
+#include "PollableQueue.h"
#include "PollerDispatch.h"
#include "Quorum.h"
-#include "Decoder.h"
-#include "PollableQueue.h"
-#include "ExpiryPolicy.h"
+#include "qmf/org/apache/qpid/cluster/Cluster.h"
+#include "qpid/Url.h"
#include "qpid/broker/Broker.h"
-#include "qpid/sys/Monitor.h"
#include "qpid/management/Manageable.h"
-#include "qpid/Url.h"
-#include "qmf/org/apache/qpid/cluster/Cluster.h"
+#include "qpid/sys/Monitor.h"
-#include <boost/intrusive_ptr.hpp>
#include <boost/bind.hpp>
+#include <boost/intrusive_ptr.hpp>
#include <boost/optional.hpp>
#include <algorithm>
-#include <vector>
#include <map>
+#include <vector>
namespace qpid {
@@ -58,6 +58,7 @@ class Uuid;
namespace cluster {
class Connection;
+class EventFrame;
/**
* Connection to the cluster
@@ -65,82 +66,91 @@ class Connection;
class Cluster : private Cpg::Handler, public management::Manageable {
public:
typedef boost::intrusive_ptr<Connection> ConnectionPtr;
- typedef std::vector<ConnectionPtr> Connections;
+ typedef std::vector<ConnectionPtr> ConnectionVector;
- /** Construct the cluster in plugin earlyInitialize */
+ // Public functions are thread safe unless otherwise mentioned in a comment.
+
+ // Construct the cluster in plugin earlyInitialize.
Cluster(const ClusterSettings&, broker::Broker&);
virtual ~Cluster();
- /** Join the cluster in plugin initialize. Requires transport
- * plugins to be available.. */
+ // Called by plugin initialize: cluster start-up requires transport plugins .
+ // Thread safety: only called by plugin initialize.
void initialize();
- // Connection map - called in connection threads.
+ // Connection map.
void addLocalConnection(const ConnectionPtr&);
void addShadowConnection(const ConnectionPtr&);
void erase(const ConnectionId&);
- // URLs of current cluster members - called in connection threads.
+ // URLs of current cluster members.
std::vector<std::string> getIds() const;
std::vector<Url> getUrls() const;
boost::shared_ptr<FailoverExchange> getFailoverExchange() const { return failoverExchange; }
- // Leave the cluster - called in any thread.
+ // Leave the cluster - called when fatal errors occur.
void leave();
// Update completed - called in update thread
- void updateInDone(const ClusterMap&, uint64_t frameId);
+ void updateInDone(const ClusterMap&);
MemberId getId() const;
broker::Broker& getBroker() const;
Multicaster& getMulticast() { return mcast; }
- boost::function<bool ()> isQuorate;
- void checkQuorum(); // called in connection threads.
+ void checkQuorum();
size_t getReadMax() { return readMax; }
size_t getWriteEstimate() { return writeEstimate; }
- bool isLeader() const; // Called in deliver thread.
+ void deliverFrame(const EventFrame&);
+
+ // Called only during update by Connection::shadowReady
+ Decoder& getDecoder() { return decoder; }
+
+ ExpiryPolicy& getExpiryPolicy() { return *expiryPolicy; }
private:
typedef sys::Monitor::ScopedLock Lock;
typedef PollableQueue<Event> PollableEventQueue;
typedef PollableQueue<EventFrame> PollableFrameQueue;
+ typedef std::map<ConnectionId, ConnectionPtr> ConnectionMap;
- // NB: The final Lock& parameter on functions below is used to mark functions
- // that should only be called by a function that already holds the lock.
- // The parameter makes it hard to forget since you have to have an instance of
- // a Lock to call the unlocked functions.
-
+ // NB: A dummy Lock& parameter marks functions that must only be
+ // called with Cluster::lock locked.
+
void leave(Lock&);
std::vector<std::string> getIds(Lock&) const;
std::vector<Url> getUrls(Lock&) const;
- // Make an offer if we can - called in deliver thread.
- void tryMakeOffer(const MemberId&, Lock&);
-
- // Called in main thread in ~Broker.
+ // == Called in main thread from Broker destructor.
void brokerShutdown();
+ // == Called in deliverEventQueue thread
+ void deliveredEvent(const Event&);
+
+ // == Called in deliverFrameQueue thread
+ void deliveredFrame(const EventFrame&);
+
// Cluster controls implement XML methods from cluster.xml.
- // Called in deliver thread.
- //
void updateRequest(const MemberId&, const std::string&, Lock&);
void updateOffer(const MemberId& updater, uint64_t updatee, const framing::Uuid&, Lock&);
void ready(const MemberId&, const std::string&, Lock&);
void configChange(const MemberId&, const std::string& addresses, Lock& l);
void messageExpired(const MemberId&, uint64_t, Lock& l);
void shutdown(const MemberId&, Lock&);
- void deliveredEvent(const Event&);
- void deliveredFrame(const EventFrame&);
- // Helper, called in deliver thread.
+ // Helper functions
+ ConnectionPtr getConnection(const ConnectionId&, Lock&);
+ ConnectionVector getConnections(Lock&);
void updateStart(const MemberId& updatee, const Url& url, Lock&);
-
+ void makeOffer(const MemberId&, Lock&);
void setReady(Lock&);
+ void memberUpdate(Lock&);
+ void setClusterId(const framing::Uuid&, Lock&);
+ // == Called in CPG dispatch thread
void deliver( // CPG deliver callback.
cpg_handle_t /*handle*/,
struct cpg_name *group,
@@ -149,7 +159,7 @@ class Cluster : private Cpg::Handler, public management::Manageable {
void* /*msg*/,
int /*msg_len*/);
- void deliver(const Event&);
+ void deliverEvent(const Event&);
void configChange( // CPG config change callback.
cpg_handle_t /*handle*/,
@@ -159,23 +169,21 @@ class Cluster : private Cpg::Handler, public management::Manageable {
struct cpg_address */*joined*/, int /*nJoined*/
);
+ // == Called in management threads.
virtual qpid::management::ManagementObject* GetManagementObject() const;
virtual management::Manageable::status_t ManagementMethod (uint32_t methodId, management::Args& args, std::string& text);
void stopClusterNode(Lock&);
void stopFullCluster(Lock&);
- void memberUpdate(Lock&);
- // Called in connection IO threads .
+ // == Called in connection IO threads .
void checkUpdateIn(Lock&);
- // Called in UpdateClient thread.
+ // == Called in UpdateClient thread.
void updateOutDone();
void updateOutError(const std::exception&);
void updateOutDone(Lock&);
- void setClusterId(const framing::Uuid&);
-
// Immutable members set on construction, never changed.
ClusterSettings settings;
broker::Broker& broker;
@@ -184,34 +192,38 @@ class Cluster : private Cpg::Handler, public management::Manageable {
Cpg cpg;
const std::string name;
Url myUrl;
- const MemberId myId;
+ const MemberId self;
const size_t readMax;
const size_t writeEstimate;
framing::Uuid clusterId;
NoOpConnectionOutputHandler shadowOut;
qpid::management::ManagementAgent* mAgent;
+ boost::intrusive_ptr<ExpiryPolicy> expiryPolicy;
// Thread safe members
Multicaster mcast;
PollerDispatch dispatcher;
PollableEventQueue deliverEventQueue;
PollableFrameQueue deliverFrameQueue;
- ConnectionMap connections;
boost::shared_ptr<FailoverExchange> failoverExchange;
Quorum quorum;
-
- // Used only in delivery thread
- Decoder decoder;
- ClusterMap::Set elders;
- boost::intrusive_ptr<ExpiryPolicy> expiryPolicy;
- uint64_t frameId;
+ LockedConnectionMap localConnections;
// Used only during initialization
bool initialized;
- // Remaining members are protected by lock
+ // Used only in deliverEventQueue thread or when stalled for update.
+ Decoder decoder;
+ bool discarding;
+
+ // Remaining members are protected by lock.
+ // FIXME aconway 2009-03-06: Most of these members are also only used in
+ // deliverFrameQueue thread or during stall. Review and separate members
+ // that require a lock, drop lock when not needed.
+ //
mutable sys::Monitor lock;
+
// Local cluster state, cluster map
enum {
INIT, ///< Initial state, no CPG messages received.
@@ -223,15 +235,16 @@ class Cluster : private Cpg::Handler, public management::Manageable {
UPDATER, ///< Offer accepted, sending a state update.
LEFT ///< Final state, left the cluster.
} state;
+
+ ConnectionMap connections;
ClusterMap map;
+ ClusterMap::Set elders;
size_t lastSize;
bool lastBroker;
- uint64_t sequence;
-
- // Update related
sys::Thread updateThread;
boost::optional<ClusterMap> updatedMap;
+
friend std::ostream& operator<<(std::ostream&, const Cluster&);
friend class ClusterDispatcher;
};
diff --git a/qpid/cpp/src/qpid/cluster/ClusterPlugin.cpp b/qpid/cpp/src/qpid/cluster/ClusterPlugin.cpp
index 132043f91a..adb6621caf 100644
--- a/qpid/cpp/src/qpid/cluster/ClusterPlugin.cpp
+++ b/qpid/cpp/src/qpid/cluster/ClusterPlugin.cpp
@@ -138,7 +138,6 @@ struct ClusterPlugin : public Plugin {
broker->setConnectionFactory(
boost::shared_ptr<sys::ConnectionCodec::Factory>(
new ConnectionCodec::Factory(broker->getConnectionFactory(), *cluster)));
- broker->getExchanges().registerExchange(cluster->getFailoverExchange());
ManagementBroker* mgmt = dynamic_cast<ManagementBroker*>(ManagementAgent::Singleton::getInstance());
if (mgmt) {
std::auto_ptr<IdAllocator> allocator(new UpdateClientIdAllocator());
diff --git a/qpid/cpp/src/qpid/cluster/ClusterSettings.h b/qpid/cpp/src/qpid/cluster/ClusterSettings.h
index a8f33be75e..88e8829dfe 100644
--- a/qpid/cpp/src/qpid/cluster/ClusterSettings.h
+++ b/qpid/cpp/src/qpid/cluster/ClusterSettings.h
@@ -35,7 +35,7 @@ struct ClusterSettings {
size_t readMax, writeEstimate;
std::string username, password, mechanism;
- ClusterSettings() : quorum(false), readMax(10), writeEstimate(64), username("guest"), password("guest") {}
+ ClusterSettings() : quorum(false), readMax(10), writeEstimate(64) {}
Url getUrl(uint16_t port) const {
if (url.empty()) return Url::getIpAddressesUrl(port);
diff --git a/qpid/cpp/src/qpid/cluster/Connection.cpp b/qpid/cpp/src/qpid/cluster/Connection.cpp
index 1a3f7c4ef7..aa7d082720 100644
--- a/qpid/cpp/src/qpid/cluster/Connection.cpp
+++ b/qpid/cpp/src/qpid/cluster/Connection.cpp
@@ -40,6 +40,7 @@
#include "qpid/framing/ConnectionCloseOkBody.h"
#include "qpid/log/Statement.h"
#include "qpid/sys/LatencyMetric.h"
+#include "qpid/sys/AtomicValue.h"
#include <boost/current_function.hpp>
@@ -58,27 +59,36 @@ using namespace framing;
NoOpConnectionOutputHandler Connection::discardHandler;
-// Shadow connections
-Connection::Connection(Cluster& c, sys::ConnectionOutputHandler& out,
- const std::string& wrappedId, ConnectionId myId)
- : cluster(c), self(myId), catchUp(false), output(*this, out),
- connection(&output, cluster.getBroker(), wrappedId), expectProtocolHeader(false)
+namespace {
+sys::AtomicValue<uint64_t> idCounter;
+}
+
+// Shadow connection
+Connection::Connection(Cluster& c, sys::ConnectionOutputHandler& out, const std::string& logId, const ConnectionId& id)
+ : cluster(c), self(id), catchUp(false), output(*this, out),
+ connection(&output, cluster.getBroker(), logId), expectProtocolHeader(false),
+ mcastFrameHandler(cluster.getMulticast(), self)
{ init(); }
-// Local connections
+// Local connection
Connection::Connection(Cluster& c, sys::ConnectionOutputHandler& out,
- const std::string& wrappedId, MemberId myId, bool isCatchUp, bool isLink)
- : cluster(c), self(myId, this), catchUp(isCatchUp), output(*this, out),
- connection(&output, cluster.getBroker(), wrappedId, isLink, catchUp ? ++catchUpId : 0),
- expectProtocolHeader(isLink)
+ const std::string& logId, MemberId member, bool isCatchUp, bool isLink)
+ : cluster(c), self(member, ++idCounter), catchUp(isCatchUp), output(*this, out),
+ connection(&output, cluster.getBroker(), logId, isLink, catchUp ? ++catchUpId : 0),
+ expectProtocolHeader(isLink), mcastFrameHandler(cluster.getMulticast(), self)
{ init(); }
void Connection::init() {
QPID_LOG(debug, cluster << " new connection: " << *this);
- if (isLocalClient()) {
+ if (isLocalClient()) {
+ connection.setClusterOrderOutput(mcastFrameHandler); // Actively send cluster-order frames from local node
cluster.addLocalConnection(this);
giveReadCredit(cluster.getReadMax());
}
+ else { // Shadow or catch-up connection
+ connection.setClusterOrderOutput(nullFrameHandler); // Passive, discard cluster-order frames
+ connection.setClientThrottling(false); // Disable client throttling, done by active node.
+ }
}
void Connection::giveReadCredit(int credit) {
@@ -140,10 +150,16 @@ bool Connection::checkUnsupported(const AMQBody& body) {
void Connection::deliveredFrame(const EventFrame& f) {
assert(!catchUp);
currentChannel = f.frame.getChannel();
- if (!framing::invoke(*this, *f.frame.getBody()).wasHandled() // Connection contol.
+ if (f.frame.getBody() // frame can be emtpy with just readCredit
+ && !framing::invoke(*this, *f.frame.getBody()).wasHandled() // Connection contol.
&& !checkUnsupported(*f.frame.getBody())) // Unsupported operation.
{
- connection.received(const_cast<AMQFrame&>(f.frame)); // Pass to broker connection.
+ if (f.type == DATA) // incoming data frames to broker::Connection
+ connection.received(const_cast<AMQFrame&>(f.frame));
+ else { // frame control, send frame via SessionState
+ broker::SessionState* ss = connection.getChannel(f.frame.getChannel()).getSession();
+ if (ss) ss->out(const_cast<AMQFrame&>(f.frame));
+ }
}
giveReadCredit(f.readCredit);
}
@@ -186,12 +202,12 @@ void Connection::left() {
connection.closed();
}
-// Decode data from local clients.
+// ConnectoinCodec::decode receives read buffers from directly-connected clients.
size_t Connection::decode(const char* buffer, size_t size) {
if (catchUp) { // Handle catch-up locally.
Buffer buf(const_cast<char*>(buffer), size);
while (localDecoder.decode(buf))
- received(localDecoder.frame);
+ received(localDecoder.getFrame());
}
else { // Multicast local connections.
assert(isLocal());
@@ -242,6 +258,7 @@ void Connection::sessionState(
const SequenceSet& unknownCompleted,
const SequenceSet& receivedIncomplete)
{
+
sessionState().setState(
replayStart,
sendCommandPoint,
@@ -253,21 +270,23 @@ void Connection::sessionState(
QPID_LOG(debug, cluster << " received session state update for " << sessionState().getId());
}
-void Connection::shadowReady(uint64_t memberId, uint64_t connectionId, const string& username) {
- ConnectionId shadow = ConnectionId(memberId, connectionId);
- QPID_LOG(debug, cluster << " catch-up connection " << *this << " becomes shadow " << shadow);
- self = shadow;
+void Connection::shadowReady(uint64_t memberId, uint64_t connectionId, const string& username, const string& fragment) {
+ ConnectionId shadowId = ConnectionId(memberId, connectionId);
+ QPID_LOG(debug, cluster << " catch-up connection " << *this << " becomes shadow " << shadowId);
+ self = shadowId;
connection.setUserId(username);
+ // OK to use decoder here because we are stalled for update.
+ cluster.getDecoder().get(self).setFragment(fragment.data(), fragment.size());
}
-void Connection::membership(const FieldTable& joiners, const FieldTable& members, uint64_t frameId) {
+void Connection::membership(const FieldTable& joiners, const FieldTable& members) {
QPID_LOG(debug, cluster << " incoming update complete on connection " << *this);
- cluster.updateInDone(ClusterMap(joiners, members), frameId);
+ cluster.updateInDone(ClusterMap(joiners, members));
self.second = 0; // Mark this as completed update connection.
}
bool Connection::isLocal() const {
- return self.first == cluster.getId() && self.second == this;
+ return self.first == cluster.getId() && self.second;
}
bool Connection::isShadow() const {
@@ -333,6 +352,10 @@ void Connection::queuePosition(const string& qname, const SequenceNumber& positi
q->setPosition(position);
}
+void Connection::expiryId(uint64_t id) {
+ cluster.getExpiryPolicy().setId(id);
+}
+
std::ostream& operator<<(std::ostream& o, const Connection& c) {
const char* type="unknown";
if (c.isLocal()) type = "local";
diff --git a/qpid/cpp/src/qpid/cluster/Connection.h b/qpid/cpp/src/qpid/cluster/Connection.h
index 98b47e1bc0..6434f763a8 100644
--- a/qpid/cpp/src/qpid/cluster/Connection.h
+++ b/qpid/cpp/src/qpid/cluster/Connection.h
@@ -27,14 +27,15 @@
#include "OutputInterceptor.h"
#include "NoOpConnectionOutputHandler.h"
#include "EventFrame.h"
+#include "McastFrameHandler.h"
#include "qpid/broker/Connection.h"
#include "qpid/amqp_0_10/Connection.h"
#include "qpid/sys/AtomicValue.h"
#include "qpid/sys/ConnectionInputHandler.h"
#include "qpid/sys/ConnectionOutputHandler.h"
-#include "qpid/framing/FrameDecoder.h"
#include "qpid/framing/SequenceNumber.h"
+#include "qpid/framing/FrameDecoder.h"
#include <iosfwd>
@@ -63,10 +64,10 @@ class Connection :
public:
typedef sys::PollableQueue<EventFrame> PollableFrameQueue;
- /** Local connection, use this in ConnectionId */
- Connection(Cluster&, sys::ConnectionOutputHandler& out, const std::string& id, MemberId, bool catchUp, bool isLink);
- /** Shadow connection */
- Connection(Cluster&, sys::ConnectionOutputHandler& out, const std::string& id, ConnectionId);
+ /** Local connection. */
+ Connection(Cluster&, sys::ConnectionOutputHandler& out, const std::string& logId, MemberId, bool catchUp, bool isLink);
+ /** Shadow connection. */
+ Connection(Cluster&, sys::ConnectionOutputHandler& out, const std::string& logId, const ConnectionId& id);
~Connection();
ConnectionId getId() const { return self; }
@@ -99,7 +100,7 @@ class Connection :
/** Called if the connectors member has left the cluster */
void left();
- // ConnectionCodec methods
+ // ConnectionCodec methods - called by IO layer with a read buffer.
size_t decode(const char* buffer, size_t size);
// Called for data delivered from the cluster.
@@ -117,9 +118,9 @@ class Connection :
const framing::SequenceNumber& received,
const framing::SequenceSet& unknownCompleted, const SequenceSet& receivedIncomplete);
- void shadowReady(uint64_t memberId, uint64_t connectionId, const std::string& username);
+ void shadowReady(uint64_t memberId, uint64_t connectionId, const std::string& username, const std::string& fragment);
- void membership(const framing::FieldTable&, const framing::FieldTable&, uint64_t frameId);
+ void membership(const framing::FieldTable&, const framing::FieldTable&);
void deliveryRecord(const std::string& queue,
const framing::SequenceNumber& position,
@@ -134,6 +135,7 @@ class Connection :
uint32_t credit);
void queuePosition(const std::string&, const framing::SequenceNumber&);
+ void expiryId(uint64_t);
void txStart();
void txAccept(const framing::SequenceSet&);
@@ -148,8 +150,12 @@ class Connection :
void exchange(const std::string& encoded);
void giveReadCredit(int credit);
-
+
private:
+ struct NullFrameHandler : public framing::FrameHandler {
+ void handle(framing::AMQFrame&) {}
+ };
+
void init();
bool checkUnsupported(const framing::AMQBody& body);
void deliverClose();
@@ -174,6 +180,8 @@ class Connection :
framing::ChannelId currentChannel;
boost::shared_ptr<broker::TxBuffer> txBuffer;
bool expectProtocolHeader;
+ McastFrameHandler mcastFrameHandler;
+ NullFrameHandler nullFrameHandler;
static qpid::sys::AtomicValue<uint64_t> catchUpId;
diff --git a/qpid/cpp/src/qpid/cluster/ConnectionCodec.cpp b/qpid/cpp/src/qpid/cluster/ConnectionCodec.cpp
index 442ac1438f..007337792b 100644
--- a/qpid/cpp/src/qpid/cluster/ConnectionCodec.cpp
+++ b/qpid/cpp/src/qpid/cluster/ConnectionCodec.cpp
@@ -44,18 +44,15 @@ ConnectionCodec::Factory::create(ProtocolVersion v, sys::OutputControl& out, con
return 0;
}
-// Used for outgoing Link connections, we don't care.
+// Used for outgoing Link connections
sys::ConnectionCodec*
-ConnectionCodec::Factory::create(sys::OutputControl& out, const std::string& id) {
- return new ConnectionCodec(out, id, cluster, false, true);
- //return next->create(out, id);
+ConnectionCodec::Factory::create(sys::OutputControl& out, const std::string& logId) {
+ return new ConnectionCodec(out, logId, cluster, false, true);
}
-ConnectionCodec::ConnectionCodec(sys::OutputControl& out, const std::string& id, Cluster& cluster, bool catchUp, bool isLink)
- : codec(out, id, isLink),
- interceptor(new Connection(cluster, codec, id, cluster.getId(), catchUp, isLink)),
- id(interceptor->getId()),
- localId(id)
+ConnectionCodec::ConnectionCodec(sys::OutputControl& out, const std::string& logId, Cluster& cluster, bool catchUp, bool isLink)
+ : codec(out, logId, isLink),
+ interceptor(new Connection(cluster, codec, logId, cluster.getId(), catchUp, isLink))
{
std::auto_ptr<sys::ConnectionInputHandler> ih(new ProxyInputHandler(interceptor));
codec.setInputHandler(ih);
diff --git a/qpid/cpp/src/qpid/cluster/ConnectionCodec.h b/qpid/cpp/src/qpid/cluster/ConnectionCodec.h
index 69c2b0c3c8..ea01b7abb9 100644
--- a/qpid/cpp/src/qpid/cluster/ConnectionCodec.h
+++ b/qpid/cpp/src/qpid/cluster/ConnectionCodec.h
@@ -56,7 +56,7 @@ class ConnectionCodec : public sys::ConnectionCodec {
sys::ConnectionCodec* create(sys::OutputControl&, const std::string& id);
};
- ConnectionCodec(sys::OutputControl& out, const std::string& id, Cluster& c, bool catchUp, bool isLink);
+ ConnectionCodec(sys::OutputControl& out, const std::string& logId, Cluster& c, bool catchUp, bool isLink);
~ConnectionCodec();
// ConnectionCodec functions.
@@ -71,8 +71,6 @@ class ConnectionCodec : public sys::ConnectionCodec {
private:
amqp_0_10::Connection codec;
boost::intrusive_ptr<cluster::Connection> interceptor;
- cluster::ConnectionId id;
- std::string localId;
};
}} // namespace qpid::cluster
diff --git a/qpid/cpp/src/qpid/cluster/ConnectionDecoder.cpp b/qpid/cpp/src/qpid/cluster/ConnectionDecoder.cpp
deleted file mode 100644
index 3c18cf751e..0000000000
--- a/qpid/cpp/src/qpid/cluster/ConnectionDecoder.cpp
+++ /dev/null
@@ -1,57 +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.
- *
- */
-
-#include "ConnectionDecoder.h"
-#include "EventFrame.h"
-#include "ConnectionMap.h"
-
-namespace qpid {
-namespace cluster {
-
-using namespace framing;
-
-ConnectionDecoder::ConnectionDecoder(const Handler& h) : handler(h) {}
-
-void ConnectionDecoder::decode(const EventHeader& eh, const void* data, ConnectionMap& map) {
- assert(eh.getType() == DATA); // Only handle connection data events.
- const char* cp = static_cast<const char*>(data);
- Buffer buf(const_cast<char*>(cp), eh.getSize());
- if (decoder.decode(buf)) { // Decoded a frame
- AMQFrame frame(decoder.frame);
- while (decoder.decode(buf)) {
- handler(EventFrame(eh, frame));
- frame = decoder.frame;
- }
- // Set read-credit on the last frame ending in this event.
- // Credit will be given when this frame is processed.
- handler(EventFrame(eh, frame, 1));
- }
- else {
- // We must give 1 unit read credit per event.
- // This event does not complete any frames so
- // we give read credit directly.
- ConnectionPtr connection = map.getLocal(eh.getConnectionId());
- if (connection)
- connection->giveReadCredit(1);
- }
-}
-
-}} // namespace qpid::cluster
diff --git a/qpid/cpp/src/qpid/cluster/ConnectionMap.cpp b/qpid/cpp/src/qpid/cluster/ConnectionMap.cpp
deleted file mode 100644
index b412bb13cc..0000000000
--- a/qpid/cpp/src/qpid/cluster/ConnectionMap.cpp
+++ /dev/null
@@ -1,96 +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.
- *
- */
-#include "ConnectionMap.h"
-#include "Cluster.h"
-#include "qpid/framing/reply_exceptions.h"
-#include "qpid/log/Statement.h"
-
-namespace qpid {
-namespace cluster {
-
-using framing::InternalErrorException;
-
-void ConnectionMap::insert(ConnectionPtr p) {
- std::pair<Map::iterator, bool> ib = map.insert(Map::value_type(p->getId(), p));
- if (!ib.second) {
- assert(0);
- throw InternalErrorException(QPID_MSG("Duplicate connection replica: " << p->getId()));
- }
-}
-
-void ConnectionMap::erase(const ConnectionId& id) {
- Map::iterator i = map.find(id);
- if (i == map.end()) {
- assert(0);
- QPID_LOG(warning, "Erase non-existent connection replica: " << id);
- }
- map.erase(i);
-}
-
-ConnectionMap::ConnectionPtr ConnectionMap::get(const ConnectionId& id) {
- Map::const_iterator i = map.find(id);
- if (i == map.end()) {
- // Deleted local connection.
- if(id.getMember() == cluster.getId())
- return 0;
- // New remote connection, create a shadow.
- std::ostringstream mgmtId;
- mgmtId << id;
- ConnectionPtr cp = new Connection(cluster, shadowOut, mgmtId.str(), id);
- std::pair<Map::iterator, bool> ib = map.insert(Map::value_type(id, cp));
- if (!ib.second)
- throw InternalErrorException(QPID_MSG("Duplicate entry in cluster connection map: " << id));
- i = ib.first;
- }
- return i->second;
-}
-
-ConnectionMap::ConnectionPtr ConnectionMap::getLocal(const ConnectionId& id) {
- if (id.getMember() != cluster.getId()) return 0;
- Map::const_iterator i = map.find(id);
- assert(i != map.end()); // FIXME aconway 2009-02-11: remove or exception.
- return i == map.end() ? 0 : i->second;
-}
-
-ConnectionMap::Vector ConnectionMap::values() const {
- Vector result(map.size());
- std::transform(map.begin(), map.end(), result.begin(),
- boost::bind(&Map::value_type::second, _1));
- return result;
-}
-
-void ConnectionMap::update(MemberId myId, const ClusterMap& cluster) {
- for (Map::iterator i = map.begin(); i != map.end(); ) {
- MemberId member = i->first.getMember();
- if (member != myId && !cluster.isMember(member)) {
- i->second->left();
- map.erase(i++);
- } else {
- i++;
- }
- }
-}
-
-void ConnectionMap::clear() {
- map.clear();
-}
-
-}} // namespace qpid::cluster
diff --git a/qpid/cpp/src/qpid/cluster/ConnectionMap.h b/qpid/cpp/src/qpid/cluster/ConnectionMap.h
deleted file mode 100644
index f8aa663339..0000000000
--- a/qpid/cpp/src/qpid/cluster/ConnectionMap.h
+++ /dev/null
@@ -1,88 +0,0 @@
-#ifndef QPID_CLUSTER_CONNECTIONMAP_H
-#define QPID_CLUSTER_CONNECTIONMAP_H
-
-/*
- *
- * 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.
- *
- */
-#include "types.h"
-#include "Connection.h"
-#include "ClusterMap.h"
-#include "NoOpConnectionOutputHandler.h"
-#include "qpid/sys/Mutex.h"
-#include <boost/intrusive_ptr.hpp>
-#include <map>
-
-namespace qpid {
-namespace cluster {
-
-class Cluster;
-
-/**
- * Thread safe map of connections. The map is used in:
- * - deliver thread to look connections and create new shadow connections.
- * - local catch-up connection threads to add a caught-up shadow connections.
- * - local client connection threads when local connections are created.
- */
-class ConnectionMap {
- public:
- typedef boost::intrusive_ptr<cluster::Connection> ConnectionPtr;
- typedef std::vector<ConnectionPtr> Vector;
-
- ConnectionMap(Cluster& c) : cluster(c) {}
-
- /** Insert a local connection or a caught up shadow connection.
- * Called in local connection thread.
- */
- void insert(ConnectionPtr p);
-
- /** Erase a closed connection. Called in deliver thread. */
- void erase(const ConnectionId& id);
-
- /** Get an existing connection. Returns 0 if id is a closed local
- * connections, frames for closed connections should be ignored.
- */
- ConnectionPtr get(const ConnectionId& id);
-
- /** If ID is a local connection and in the map return it, else return 0 */
- ConnectionPtr getLocal(const ConnectionId& id);
-
- /** Get connections for sending an update. */
- Vector values() const;
-
- /** Remove connections who's members are no longer in the cluster. Deliver thread. */
- void update(MemberId myId, const ClusterMap& cluster);
-
-
- void clear();
-
- size_t size() const;
-
- private:
- typedef std::map<ConnectionId, ConnectionPtr> Map;
-
- Cluster& cluster;
- NoOpConnectionOutputHandler shadowOut;
- Map map;
-};
-
-
-}} // namespace qpid::cluster
-
-#endif /*!QPID_CLUSTER_CONNECTIONMAP_H*/
diff --git a/qpid/cpp/src/qpid/cluster/Cpg.cpp b/qpid/cpp/src/qpid/cluster/Cpg.cpp
index c5a1b72003..915a578989 100644
--- a/qpid/cpp/src/qpid/cluster/Cpg.cpp
+++ b/qpid/cpp/src/qpid/cluster/Cpg.cpp
@@ -107,17 +107,16 @@ void Cpg::leave() {
check(cpg_leave(handle, &group), cantLeaveMsg(group));
}
-bool Cpg::isFlowControlEnabled() {
- cpg_flow_control_state_t flowState;
- check(cpg_flow_control_state_get(handle, &flowState), "Cannot get CPG flow control status.");
- return flowState == CPG_FLOW_CONTROL_ENABLED;
-}
+
+
bool Cpg::mcast(const iovec* iov, int iovLen) {
- if (isFlowControlEnabled()) {
- QPID_LOG(debug, "CPG flow control enabled")
+ // Check for flow control
+ cpg_flow_control_state_t flowState;
+ check(cpg_flow_control_state_get(handle, &flowState), "Cannot get CPG flow control status.");
+ if (flowState == CPG_FLOW_CONTROL_ENABLED)
return false;
- }
+
cpg_error_t result;
do {
result = cpg_mcast_joined(handle, CPG_TYPE_AGREED, const_cast<iovec*>(iov), iovLen);
@@ -149,9 +148,13 @@ void Cpg::dispatchBlocking() {
string Cpg::errorStr(cpg_error_t err, const std::string& msg) {
std::ostringstream os;
os << msg << ": ";
+ // FIXME aconway 2009-03-11: The commented out cases below are
+ // because of mistakes in the latest corosync header files.
+ // The code should be re-instated when that is sorted out.
+ //
switch (err) {
case CPG_OK: os << "ok"; break;
- case CPG_ERR_LIBRARY: os << "library"; break;
+ // case CPG_ERR_LIBRARY: os << "library"; break;
case CPG_ERR_TIMEOUT: os << "timeout"; break;
case CPG_ERR_TRY_AGAIN: os << "try again"; break;
case CPG_ERR_INVALID_PARAM: os << "invalid param"; break;
@@ -161,8 +164,8 @@ string Cpg::errorStr(cpg_error_t err, const std::string& msg) {
case CPG_ERR_NOT_EXIST: os << "not exist"; break;
case CPG_ERR_EXIST: os << "exist"; break;
case CPG_ERR_NOT_SUPPORTED: os << "not supported"; break;
- case CPG_ERR_SECURITY: os << "security"; break;
- case CPG_ERR_TOO_MANY_GROUPS: os << "too many groups"; break;
+ // case CPG_ERR_SECURITY: os << "security"; break;
+ // case CPG_ERR_TOO_MANY_GROUPS: os << "too many groups"; break;
default: os << ": unknown cpg error " << err;
};
os << " (" << err << ")";
@@ -203,13 +206,19 @@ ostream& operator<<(ostream& o, const ConnectionId& c) {
std::string MemberId::str() const {
char s[8];
- reinterpret_cast<uint32_t&>(s[0]) = htonl(first);
- reinterpret_cast<uint32_t&>(s[4]) = htonl(second);
+ uint32_t x;
+ x = htonl(first);
+ ::memcpy(s, &x, 4);
+ x = htonl(second);
+ ::memcpy(s+4, &x, 4);
return std::string(s,8);
}
MemberId::MemberId(const std::string& s) {
- first = ntohl(reinterpret_cast<const uint32_t&>(s[0]));
- second = ntohl(reinterpret_cast<const uint32_t&>(s[4]));
+ uint32_t x;
+ memcpy(&x, &s[0], 4);
+ first = ntohl(x);
+ memcpy(&x, &s[4], 4);
+ second = ntohl(x);
}
}} // namespace qpid::cluster
diff --git a/qpid/cpp/src/qpid/cluster/Cpg.h b/qpid/cpp/src/qpid/cluster/Cpg.h
index 5ac5a5bdbc..ac27a09ae6 100644
--- a/qpid/cpp/src/qpid/cluster/Cpg.h
+++ b/qpid/cpp/src/qpid/cluster/Cpg.h
@@ -114,8 +114,6 @@ class Cpg : public sys::IOHandle {
int getFd();
- bool isFlowControlEnabled();
-
private:
static std::string errorStr(cpg_error_t err, const std::string& msg);
static std::string cantJoinMsg(const Name&);
diff --git a/qpid/cpp/src/qpid/cluster/Decoder.cpp b/qpid/cpp/src/qpid/cluster/Decoder.cpp
index 1ba36bb521..b337ef43f4 100644
--- a/qpid/cpp/src/qpid/cluster/Decoder.cpp
+++ b/qpid/cpp/src/qpid/cluster/Decoder.cpp
@@ -18,33 +18,44 @@
* under the License.
*
*/
-
#include "Decoder.h"
-#include "Event.h"
+#include "EventFrame.h"
+#include "qpid/framing/ClusterConnectionDeliverCloseBody.h"
#include "qpid/framing/Buffer.h"
-#include "qpid/ptr_map.h"
+#include "qpid/framing/AMQFrame.h"
+
namespace qpid {
namespace cluster {
-using namespace framing;
-
-Decoder::Decoder(const Handler& h, ConnectionMap& cm) : handler(h), connections(cm) {}
-
-void Decoder::decode(const EventHeader& eh, const void* data) {
- ConnectionId id = eh.getConnectionId();
- Map::iterator i = map.find(id);
- if (i == map.end()) {
- std::pair<Map::iterator, bool> ib = map.insert(id, new ConnectionDecoder(handler));
- i = ib.first;
+void Decoder::decode(const EventHeader& eh, const char* data) {
+ assert(eh.getType() == DATA); // Only handle connection data events.
+ const char* cp = static_cast<const char*>(data);
+ framing::Buffer buf(const_cast<char*>(cp), eh.getSize());
+ framing::FrameDecoder& decoder = map[eh.getConnectionId()];
+ if (decoder.decode(buf)) { // Decoded a frame
+ framing::AMQFrame frame(decoder.getFrame());
+ while (decoder.decode(buf)) {
+ process(EventFrame(eh, frame));
+ frame = decoder.getFrame();
+ }
+ // Set read-credit on the last frame ending in this event.
+ // Credit will be given when this frame is processed.
+ process(EventFrame(eh, frame, 1));
}
- ptr_map_ptr(i)->decode(eh, data, connections);
+ else {
+ // We must give 1 unit read credit per event.
+ // This event does not complete any frames so
+ // send an empty frame with the read credit.
+ process(EventFrame(eh, framing::AMQFrame(), 1));
+ }
}
-void Decoder::erase(const ConnectionId& c) {
- Map::iterator i = map.find(c);
- if (i != map.end())
- map.erase(i);
+void Decoder::process(const EventFrame& ef) {
+ //need to check that this is not the empty frame mentioned above
+ if (ef.frame.getBody() && ef.frame.getMethod() && ef.frame.getMethod()->isA<framing::ClusterConnectionDeliverCloseBody>())
+ map.erase(ef.connectionId);
+ callback(ef);
}
}} // namespace qpid::cluster
diff --git a/qpid/cpp/src/qpid/cluster/Decoder.h b/qpid/cpp/src/qpid/cluster/Decoder.h
index 50f6afa491..acde4258a2 100644
--- a/qpid/cpp/src/qpid/cluster/Decoder.h
+++ b/qpid/cpp/src/qpid/cluster/Decoder.h
@@ -22,44 +22,36 @@
*
*/
-#include "ConnectionDecoder.h"
#include "types.h"
-#include <boost/ptr_container/ptr_map.hpp>
+#include "qpid/framing/FrameDecoder.h"
+#include <boost/function.hpp>
+#include <map>
namespace qpid {
namespace cluster {
+class EventFrame;
class EventHeader;
-class ConnectionMap;
/**
- * Holds a map of ConnectionDecoders. Decodes Events into EventFrames
- * and forwards EventFrames to a handler.
- *
- * THREAD UNSAFE: Called sequentially with un-decoded cluster events from CPG.
+ * A map of decoders for connections.
*/
class Decoder
{
public:
- typedef boost::function<void(const EventFrame&)> Handler;
-
- Decoder(const Handler& h, ConnectionMap&);
+ typedef boost::function<void(const EventFrame&)> FrameHandler;
- /** Takes EventHeader + data rather than Event so that the caller can
- * pass a pointer to connection data or a CPG buffer directly without copy.
- */
- void decode(const EventHeader& eh, const void* data);
-
- /** Erase the decoder for a connection. */
+ Decoder(FrameHandler fh) : callback(fh) {}
+ void decode(const EventHeader& eh, const char* data);
void erase(const ConnectionId&);
+ framing::FrameDecoder& get(const ConnectionId& c) { return map[c]; }
private:
- typedef boost::ptr_map<ConnectionId, ConnectionDecoder> Map;
- Handler handler;
+ typedef std::map<ConnectionId, framing::FrameDecoder> Map;
Map map;
- ConnectionMap& connections;
+ void process(const EventFrame&);
+ FrameHandler callback;
};
-
}} // namespace qpid::cluster
#endif /*!QPID_CLUSTER_DECODER_H*/
diff --git a/qpid/cpp/src/qpid/cluster/Event.cpp b/qpid/cpp/src/qpid/cluster/Event.cpp
index e30b961b3e..1cb010c266 100644
--- a/qpid/cpp/src/qpid/cluster/Event.cpp
+++ b/qpid/cpp/src/qpid/cluster/Event.cpp
@@ -23,6 +23,7 @@
#include "Cpg.h"
#include "qpid/framing/Buffer.h"
#include "qpid/framing/AMQFrame.h"
+#include "qpid/assert.h"
#include <ostream>
#include <iterator>
#include <algorithm>
@@ -31,6 +32,7 @@ namespace qpid {
namespace cluster {
using framing::Buffer;
+using framing::AMQFrame;
const size_t EventHeader::HEADER_SIZE =
sizeof(uint8_t) + // type
@@ -42,7 +44,7 @@ const size_t EventHeader::HEADER_SIZE =
;
EventHeader::EventHeader(EventType t, const ConnectionId& c, size_t s)
- : type(t), connectionId(c), size(s), sequence(0) {}
+ : type(t), connectionId(c), size(s) {}
Event::Event() {}
@@ -57,7 +59,7 @@ void EventHeader::decode(const MemberId& m, framing::Buffer& buf) {
type = (EventType)buf.getOctet();
if(type != DATA && type != CONTROL)
throw Exception("Invalid multicast event type");
- connectionId = ConnectionId(m, reinterpret_cast<Connection*>(buf.getLongLong()));
+ connectionId = ConnectionId(m, buf.getLongLong());
size = buf.getLong();
#ifdef QPID_LATENCY_METRIC
latency_metric_timestamp = buf.getLongLong();
@@ -74,14 +76,17 @@ Event Event::decodeCopy(const MemberId& m, framing::Buffer& buf) {
return e;
}
-Event Event::control(const framing::AMQBody& body, const ConnectionId& cid) {
- framing::AMQFrame f(body);
+Event Event::control(const framing::AMQFrame& f, const ConnectionId& cid) {
Event e(CONTROL, cid, f.encodedSize());
Buffer buf(e);
f.encode(buf);
return e;
}
+Event Event::control(const framing::AMQBody& body, const ConnectionId& cid) {
+ return control(framing::AMQFrame(body), cid);
+}
+
iovec Event::toIovec() {
encodeHeader();
iovec iov = { const_cast<char*>(getStore()), getStoreSize() };
@@ -90,7 +95,7 @@ iovec Event::toIovec() {
void EventHeader::encode(Buffer& b) const {
b.putOctet(type);
- b.putLongLong(reinterpret_cast<uint64_t>(connectionId.getPointer()));
+ b.putLongLong(connectionId.getNumber());
b.putLong(size);
#ifdef QPID_LATENCY_METRIC
b.putLongLong(latency_metric_timestamp);
@@ -108,12 +113,22 @@ Event::operator Buffer() const {
return Buffer(const_cast<char*>(getData()), getSize());
}
+AMQFrame Event::getFrame() const {
+ assert(type == CONTROL);
+ Buffer buf(*this);
+ AMQFrame frame;
+ QPID_ASSERT(frame.decode(buf));
+ return frame;
+}
+
static const char* EVENT_TYPE_NAMES[] = { "data", "control" };
+std::ostream& operator << (std::ostream& o, EventType t) {
+ return o << EVENT_TYPE_NAMES[t];
+}
+
std::ostream& operator << (std::ostream& o, const EventHeader& e) {
- o << "[event " << e.getConnectionId() << "/" << e.getSequence()
- << " " << EVENT_TYPE_NAMES[e.getType()]
- << " " << e.getSize() << " bytes]";
+ o << "Event[" << e.getConnectionId() << " " << e.getType() << " " << e.getSize() << " bytes]";
return o;
}
diff --git a/qpid/cpp/src/qpid/cluster/Event.h b/qpid/cpp/src/qpid/cluster/Event.h
index f1de248f89..e05ad60bcf 100644
--- a/qpid/cpp/src/qpid/cluster/Event.h
+++ b/qpid/cpp/src/qpid/cluster/Event.h
@@ -24,6 +24,7 @@
#include "types.h"
#include "qpid/RefCountedBuffer.h"
+#include "qpid/framing/AMQFrame.h"
#include "qpid/sys/LatencyMetric.h"
#include <sys/uio.h> // For iovec
#include <iosfwd>
@@ -34,6 +35,7 @@ namespace qpid {
namespace framing {
class AMQBody;
+class AMQFrame;
class Buffer;
}
@@ -55,11 +57,9 @@ class EventHeader : public ::qpid::sys::LatencyMetricTimestamp {
/** Size of header + payload. */
size_t getStoreSize() { return size + HEADER_SIZE; }
- uint64_t getSequence() const { return sequence; }
- void setSequence(uint64_t n) { sequence = n; }
-
- bool isCluster() const { return connectionId.getPointer() == 0; }
- bool isConnection() const { return connectionId.getPointer() != 0; }
+ bool isCluster() const { return connectionId.getNumber() == 0; }
+ bool isConnection() const { return connectionId.getNumber() != 0; }
+ bool isControl() const { return type == CONTROL; }
protected:
static const size_t HEADER_SIZE;
@@ -67,7 +67,6 @@ class EventHeader : public ::qpid::sys::LatencyMetricTimestamp {
EventType type;
ConnectionId connectionId;
size_t size;
- uint64_t sequence;
};
/**
@@ -83,8 +82,11 @@ class Event : public EventHeader {
/** Create an event copied from delivered data. */
static Event decodeCopy(const MemberId& m, framing::Buffer&);
- /** Create an event containing a control */
+ /** Create a control event. */
static Event control(const framing::AMQBody&, const ConnectionId&);
+
+ /** Create a control event. */
+ static Event control(const framing::AMQFrame&, const ConnectionId&);
// Data excluding header.
char* getData() { return store + HEADER_SIZE; }
@@ -93,6 +95,8 @@ class Event : public EventHeader {
// Store including header
char* getStore() { return store; }
const char* getStore() const { return store; }
+
+ framing::AMQFrame getFrame() const;
operator framing::Buffer() const;
@@ -105,6 +109,7 @@ class Event : public EventHeader {
};
std::ostream& operator << (std::ostream&, const EventHeader&);
+
}} // namespace qpid::cluster
#endif /*!QPID_CLUSTER_EVENT_H*/
diff --git a/qpid/cpp/src/qpid/cluster/EventFrame.cpp b/qpid/cpp/src/qpid/cluster/EventFrame.cpp
index ba01c170dd..9350c801f5 100644
--- a/qpid/cpp/src/qpid/cluster/EventFrame.cpp
+++ b/qpid/cpp/src/qpid/cluster/EventFrame.cpp
@@ -24,16 +24,20 @@
namespace qpid {
namespace cluster {
-EventFrame::EventFrame() : sequence(0) {}
+EventFrame::EventFrame() {}
EventFrame::EventFrame(const EventHeader& e, const framing::AMQFrame& f, int rc)
- : connectionId(e.getConnectionId()), frame(f), sequence(e.getSequence()), readCredit(rc)
+ : connectionId(e.getConnectionId()), frame(f), readCredit(rc), type(e.getType())
{
QPID_LATENCY_INIT(frame);
}
std::ostream& operator<<(std::ostream& o, const EventFrame& e) {
- return o << e.connectionId << "/" << e.sequence << " " << e.frame << " rc=" << e.readCredit;
+ if (e.frame.getBody()) o << e.frame;
+ else o << "null-frame";
+ o << " " << e.type << " " << e.connectionId;
+ if (e.readCredit) o << " read-credit=" << e.readCredit;
+ return o;
}
}} // namespace qpid::cluster
diff --git a/qpid/cpp/src/qpid/cluster/EventFrame.h b/qpid/cpp/src/qpid/cluster/EventFrame.h
index 7f33cedb5b..d6ff58dd38 100644
--- a/qpid/cpp/src/qpid/cluster/EventFrame.h
+++ b/qpid/cpp/src/qpid/cluster/EventFrame.h
@@ -42,22 +42,15 @@ struct EventFrame
EventFrame(const EventHeader& e, const framing::AMQFrame& f, int rc=0);
- bool isCluster() const { return !connectionId.getPointer(); }
- bool isConnection() const { return connectionId.getPointer(); }
+ bool isCluster() const { return connectionId.getNumber() == 0; }
+ bool isConnection() const { return connectionId.getNumber() != 0; }
bool isLastInEvent() const { return readCredit; }
- // True if this frame follows immediately after frame e.
- bool follows(const EventFrame& e) const {
- return sequence == e.sequence || (sequence == e.sequence+1 && e.readCredit);
- }
-
- bool operator<(const EventFrame& e) const { return sequence < e.sequence; }
-
ConnectionId connectionId;
framing::AMQFrame frame;
- uint64_t sequence;
- int readCredit; // last frame in an event, give credit when processed.
+ int readCredit; ///< last frame in an event, give credit when processed.
+ EventType type;
};
std::ostream& operator<<(std::ostream& o, const EventFrame& e);
diff --git a/qpid/cpp/src/qpid/cluster/ExpiryPolicy.cpp b/qpid/cpp/src/qpid/cluster/ExpiryPolicy.cpp
index 690acfc3ad..409180c499 100644
--- a/qpid/cpp/src/qpid/cluster/ExpiryPolicy.cpp
+++ b/qpid/cpp/src/qpid/cluster/ExpiryPolicy.cpp
@@ -30,48 +30,46 @@
namespace qpid {
namespace cluster {
-ExpiryPolicy::ExpiryPolicy(const boost::function<bool()> & f, Multicaster& m, const MemberId& id, broker::Timer& t)
- : expiredPolicy(new Expired), isLeader(f), mcast(m), memberId(id), timer(t) {}
-
-namespace {
-uint64_t clusterId(const broker::Message& m) {
- assert(m.getFrames().begin() != m.getFrames().end());
- return m.getFrames().begin()->getClusterId();
-}
+ExpiryPolicy::ExpiryPolicy(Multicaster& m, const MemberId& id, broker::Timer& t)
+ : expiryId(0), expiredPolicy(new Expired), mcast(m), memberId(id), timer(t) {}
struct ExpiryTask : public broker::TimerTask {
ExpiryTask(const boost::intrusive_ptr<ExpiryPolicy>& policy, uint64_t id, sys::AbsTime when)
- : TimerTask(when), expiryPolicy(policy), messageId(id) {}
- void fire() { expiryPolicy->sendExpire(messageId); }
+ : TimerTask(when), expiryPolicy(policy), expiryId(id) {}
+ void fire() { expiryPolicy->sendExpire(expiryId); }
boost::intrusive_ptr<ExpiryPolicy> expiryPolicy;
- const uint64_t messageId;
+ const uint64_t expiryId;
};
-}
void ExpiryPolicy::willExpire(broker::Message& m) {
- timer.add(new ExpiryTask(this, clusterId(m), m.getExpiration()));
+ uint64_t id = expiryId++;
+ assert(unexpiredById.find(id) == unexpiredById.end());
+ assert(unexpiredByMessage.find(&m) == unexpiredByMessage.end());
+ unexpiredById[id] = &m;
+ unexpiredByMessage[&m] = id;
+ timer.add(new ExpiryTask(this, id, m.getExpiration()));
}
bool ExpiryPolicy::hasExpired(broker::Message& m) {
- sys::Mutex::ScopedLock l(lock);
- IdSet::iterator i = expired.find(clusterId(m));
- if (i != expired.end()) {
- expired.erase(i);
- const_cast<broker::Message&>(m).setExpiryPolicy(expiredPolicy); // hasExpired() == true;
- return true;
- }
- return false;
+ return unexpiredByMessage.find(&m) == unexpiredByMessage.end();
}
void ExpiryPolicy::sendExpire(uint64_t id) {
- sys::Mutex::ScopedLock l(lock);
- if (isLeader())
- mcast.mcastControl(framing::ClusterMessageExpiredBody(framing::ProtocolVersion(), id), memberId);
+ mcast.mcastControl(framing::ClusterMessageExpiredBody(framing::ProtocolVersion(), id), memberId);
}
void ExpiryPolicy::deliverExpire(uint64_t id) {
- sys::Mutex::ScopedLock l(lock);
- expired.insert(id);
+ IdMessageMap::iterator i = unexpiredById.find(id);
+ if (i != unexpiredById.end()) {
+ i->second->setExpiryPolicy(expiredPolicy); // hasExpired() == true;
+ unexpiredByMessage.erase(i->second);
+ unexpiredById.erase(i);
+ }
+}
+
+boost::optional<uint64_t> ExpiryPolicy::getId(broker::Message& m) {
+ MessageIdMap::iterator i = unexpiredByMessage.find(&m);
+ return i == unexpiredByMessage.end() ? boost::optional<uint64_t>() : i->second;
}
bool ExpiryPolicy::Expired::hasExpired(broker::Message&) { return true; }
diff --git a/qpid/cpp/src/qpid/cluster/ExpiryPolicy.h b/qpid/cpp/src/qpid/cluster/ExpiryPolicy.h
index 7fb63c731e..9f8b1a9236 100644
--- a/qpid/cpp/src/qpid/cluster/ExpiryPolicy.h
+++ b/qpid/cpp/src/qpid/cluster/ExpiryPolicy.h
@@ -27,11 +27,15 @@
#include "qpid/sys/Mutex.h"
#include <boost/function.hpp>
#include <boost/intrusive_ptr.hpp>
-#include <set>
+#include <boost/optional.hpp>
+#include <map>
namespace qpid {
-namespace broker { class Timer; }
+namespace broker {
+class Timer;
+class Message;
+}
namespace cluster {
class Multicaster;
@@ -42,7 +46,7 @@ class Multicaster;
class ExpiryPolicy : public broker::ExpiryPolicy
{
public:
- ExpiryPolicy(const boost::function<bool()> & isLeader, Multicaster&, const MemberId&, broker::Timer&);
+ ExpiryPolicy(Multicaster&, const MemberId&, broker::Timer&);
void willExpire(broker::Message&);
@@ -54,18 +58,24 @@ class ExpiryPolicy : public broker::ExpiryPolicy
// Cluster delivers expiry notice.
void deliverExpire(uint64_t);
+ void setId(uint64_t id) { expiryId = id; }
+ uint64_t getId() const { return expiryId; }
+
+ boost::optional<uint64_t> getId(broker::Message&);
+
private:
- sys::Mutex lock;
- typedef std::set<uint64_t> IdSet;
+ typedef std::map<broker::Message*, uint64_t> MessageIdMap;
+ typedef std::map<uint64_t, broker::Message*> IdMessageMap;
struct Expired : public broker::ExpiryPolicy {
bool hasExpired(broker::Message&);
void willExpire(broker::Message&);
};
- IdSet expired;
+ MessageIdMap unexpiredByMessage;
+ IdMessageMap unexpiredById;
+ uint64_t expiryId;
boost::intrusive_ptr<Expired> expiredPolicy;
- boost::function<bool()> isLeader;
Multicaster& mcast;
MemberId memberId;
broker::Timer& timer;
diff --git a/qpid/cpp/src/qpid/cluster/ConnectionDecoder.h b/qpid/cpp/src/qpid/cluster/LockedConnectionMap.h
index 449387c1cc..8b2f6dae8e 100644
--- a/qpid/cpp/src/qpid/cluster/ConnectionDecoder.h
+++ b/qpid/cpp/src/qpid/cluster/LockedConnectionMap.h
@@ -1,5 +1,5 @@
-#ifndef QPID_CLUSTER_CONNECTIONDECODER_H
-#define QPID_CLUSTER_CONNECTIONDECODER_H
+#ifndef QPID_CLUSTER_LOCKEDCONNECTIONMAP_H
+#define QPID_CLUSTER_LOCKEDCONNECTIONMAP_H
/*
*
@@ -22,40 +22,41 @@
*
*/
-#include "qpid/framing/FrameDecoder.h"
-#include <boost/function.hpp>
+#include "types.h"
+#include "qpid/sys/Mutex.h"
+#include "Connection.h"
namespace qpid {
namespace cluster {
-class EventHeader;
-class EventFrame;
-class ConnectionMap;
-
/**
- * Decodes delivered connection data Event's as EventFrame's for a
- * connection replica, local or shadow. Manages state for frame
- * fragments and flow control.
- *
- * THREAD UNSAFE: connection events are decoded in sequence.
+ * Thread safe map of connections.
*/
-class ConnectionDecoder
+class LockedConnectionMap
{
public:
- typedef boost::function<void(const EventFrame&)> Handler;
-
- ConnectionDecoder(const Handler& h);
-
- /** Takes EventHeader + data rather than Event so that the caller can
- * pass a pointer to connection data or a CPG buffer directly without copy.
- */
- void decode(const EventHeader& eh, const void* data, ConnectionMap& connections);
+ void insert(const ConnectionPtr& c) {
+ sys::Mutex::ScopedLock l(lock);
+ map[c->getId()] = c;
+ }
+
+ ConnectionPtr getErase(const ConnectionId& c) {
+ sys::Mutex::ScopedLock l(lock);
+ Map::iterator i = map.find(c);
+ if (i != map.end()) {
+ ConnectionPtr cp = i->second;
+ map.erase(i);
+ return cp;
+ }
+ else
+ return 0;
+ }
private:
- Handler handler;
- framing::FrameDecoder decoder;
+ typedef std::map<ConnectionId, ConnectionPtr> Map;
+ mutable sys::Mutex lock;
+ Map map;
};
-
}} // namespace qpid::cluster
-#endif /*!QPID_CLUSTER_CONNECTIONDECODER_H*/
+#endif /*!QPID_CLUSTER_LOCKEDCONNECTIONMAP_H*/
diff --git a/qpid/cpp/src/qpid/sys/posix/PollableCondition.h b/qpid/cpp/src/qpid/cluster/McastFrameHandler.h
index 4ec277b0ec..5127c31c84 100644
--- a/qpid/cpp/src/qpid/sys/posix/PollableCondition.h
+++ b/qpid/cpp/src/qpid/cluster/McastFrameHandler.h
@@ -1,5 +1,5 @@
-#ifndef QPID_SYS_POSIX_POLLABLECONDITION_H
-#define QPID_SYS_POSIX_POLLABLECONDITION_H
+#ifndef QPID_CLUSTER_MCASTFRAMEHANDLER_H
+#define QPID_CLUSTER_MCASTFRAMEHANDLER_H
/*
*
@@ -22,35 +22,25 @@
*
*/
-#include "qpid/sys/IOHandle.h"
+#include "types.h"
+#include "Multicaster.h"
+#include "qpid/framing/FrameHandler.h"
namespace qpid {
-namespace sys {
+namespace cluster {
/**
- * A pollable condition to integrate in-process conditions with IO
- * conditions in a polling loop.
- *
- * Setting the condition makes it readable for a poller.
- *
- * Writable/disconnected conditions are undefined and should not be
- * polled for.
+ * A frame handler that multicasts frames as CONTROL events.
*/
-class PollableCondition : public sys::IOHandle {
+class McastFrameHandler : public framing::FrameHandler
+{
public:
- PollableCondition();
-
- /** Set the condition, triggers readable in a poller. */
- void set();
-
- /** Get the current state of the condition, then clear it.
- *@return The state of the condition before it was cleared.
- */
- bool clear();
-
+ McastFrameHandler(Multicaster& m, const ConnectionId& cid) : mcast(m), connection(cid) {}
+ void handle(framing::AMQFrame& frame) { mcast.mcastControl(frame, connection); }
private:
- int writeFd;
+ Multicaster& mcast;
+ ConnectionId connection;
};
-}} // namespace qpid::sys
+}} // namespace qpid::cluster
-#endif /*!QPID_SYS_POSIX_POLLABLECONDITION_H*/
+#endif /*!QPID_CLUSTER_MCASTFRAMEHANDLER_H*/
diff --git a/qpid/cpp/src/qpid/cluster/Multicaster.cpp b/qpid/cpp/src/qpid/cluster/Multicaster.cpp
index 239b3f5f35..f0738ab08f 100644
--- a/qpid/cpp/src/qpid/cluster/Multicaster.cpp
+++ b/qpid/cpp/src/qpid/cluster/Multicaster.cpp
@@ -24,6 +24,7 @@
#include "qpid/log/Statement.h"
#include "qpid/sys/LatencyMetric.h"
#include "qpid/framing/AMQBody.h"
+#include "qpid/framing/AMQFrame.h"
namespace qpid {
namespace cluster {
@@ -43,6 +44,11 @@ void Multicaster::mcastControl(const framing::AMQBody& body, const ConnectionId&
mcast(Event::control(body, id));
}
+void Multicaster::mcastControl(const framing::AMQFrame& frame, const ConnectionId& id) {
+ QPID_LOG(trace, "MCAST " << id << ": " << frame);
+ mcast(Event::control(frame, id));
+}
+
void Multicaster::mcastBuffer(const char* data, size_t size, const ConnectionId& id) {
Event e(DATA, id, size);
memcpy(e.getData(), data, size);
diff --git a/qpid/cpp/src/qpid/cluster/Multicaster.h b/qpid/cpp/src/qpid/cluster/Multicaster.h
index 1dfee47bd5..d1c3115977 100644
--- a/qpid/cpp/src/qpid/cluster/Multicaster.h
+++ b/qpid/cpp/src/qpid/cluster/Multicaster.h
@@ -50,6 +50,7 @@ class Multicaster
boost::function<void()> onError
);
void mcastControl(const framing::AMQBody& controlBody, const ConnectionId&);
+ void mcastControl(const framing::AMQFrame& controlFrame, const ConnectionId&);
void mcastBuffer(const char*, size_t, const ConnectionId&);
void mcast(const Event& e);
/** End holding mode, held events are mcast */
diff --git a/qpid/cpp/src/qpid/cluster/OutputInterceptor.cpp b/qpid/cpp/src/qpid/cluster/OutputInterceptor.cpp
index 45a369eea9..cd42446016 100644
--- a/qpid/cpp/src/qpid/cluster/OutputInterceptor.cpp
+++ b/qpid/cpp/src/qpid/cluster/OutputInterceptor.cpp
@@ -70,17 +70,12 @@ void OutputInterceptor::giveReadCredit(int32_t credit) {
// Called in write thread when the IO layer has no more data to write.
// We do nothing in the write thread, we run doOutput only on delivery
// of doOutput requests.
-bool OutputInterceptor::doOutput() {
- QPID_LOG(trace, parent << " write idle.");
- return false;
-}
+bool OutputInterceptor::doOutput() { return false; }
// Delivery of doOutput allows us to run the real connection doOutput()
// which tranfers frames to the codec for writing.
//
void OutputInterceptor::deliverDoOutput(size_t requested) {
- QPID_LATENCY_RECORD("deliver do-output", *this);
- QPID_LATENCY_CLEAR(*this);
size_t buf = getBuffered();
if (parent.isLocal())
writeEstimate.delivered(requested, sent, buf); // Update the estimate.
@@ -91,9 +86,7 @@ void OutputInterceptor::deliverDoOutput(size_t requested) {
moreOutput = parent.getBrokerConnection().doOutput();
} while (sent < requested && moreOutput);
sent += buf; // Include buffered data in the sent total.
-
- QPID_LOG(trace, "Delivered doOutput: requested=" << requested << " output=" << sent << " more=" << moreOutput);
-
+ QPID_LOG(trace, parent << " delivereDoOutput: requested=" << requested << " sent=" << sent << " more=" << moreOutput);
if (parent.isLocal() && moreOutput) {
QPID_LOG(trace, parent << " deliverDoOutput - sending doOutput, more output available.");
sendDoOutput();
diff --git a/qpid/cpp/src/qpid/cluster/PollableQueue.h b/qpid/cpp/src/qpid/cluster/PollableQueue.h
index e0422e2449..a44c39ad85 100644
--- a/qpid/cpp/src/qpid/cluster/PollableQueue.h
+++ b/qpid/cpp/src/qpid/cluster/PollableQueue.h
@@ -52,6 +52,8 @@ template <class T> class PollableQueue : public sys::PollableQueue<T> {
}
catch (const std::exception& e) {
QPID_LOG(error, message << ": " << e.what());
+ values.clear();
+ this->stop();
error();
}
}
diff --git a/qpid/cpp/src/qpid/cluster/UpdateClient.cpp b/qpid/cpp/src/qpid/cluster/UpdateClient.cpp
index 18746ccb7e..97eae7efa3 100644
--- a/qpid/cpp/src/qpid/cluster/UpdateClient.cpp
+++ b/qpid/cpp/src/qpid/cluster/UpdateClient.cpp
@@ -22,6 +22,8 @@
#include "Cluster.h"
#include "ClusterMap.h"
#include "Connection.h"
+#include "Decoder.h"
+#include "ExpiryPolicy.h"
#include "qpid/client/SessionBase_0_10Access.h"
#include "qpid/client/ConnectionAccess.h"
#include "qpid/broker/Broker.h"
@@ -86,33 +88,40 @@ void send(client::AsyncSession& s, const AMQBody& body) {
// TODO aconway 2008-09-24: optimization: update connections/sessions in parallel.
UpdateClient::UpdateClient(const MemberId& updater, const MemberId& updatee, const Url& url,
- broker::Broker& broker, const ClusterMap& m, uint64_t frameId_,
- const Cluster::Connections& cons,
+ broker::Broker& broker, const ClusterMap& m, ExpiryPolicy& expiry_,
+ const Cluster::ConnectionVector& cons, Decoder& decoder_,
const boost::function<void()>& ok,
const boost::function<void(const std::exception&)>& fail,
const client::ConnectionSettings& cs
)
: updaterId(updater), updateeId(updatee), updateeUrl(url), updaterBroker(broker), map(m),
- frameId(frameId_), connections(cons),
+ expiry(expiry_), connections(cons), decoder(decoder_),
connection(catchUpConnection()), shadowConnection(catchUpConnection()),
- done(ok), failed(fail)
+ done(ok), failed(fail), connectionSettings(cs)
{
connection.open(url, cs);
- session = connection.newSession("update_shared");
+ session = connection.newSession(UPDATE);
}
UpdateClient::~UpdateClient() {}
// Reserved exchange/queue name for catch-up, avoid clashes with user queues/exchanges.
-const std::string UpdateClient::UPDATE("qpid.qpid-update");
+const std::string UpdateClient::UPDATE("qpid.cluster-update");
+
+void UpdateClient::run() {
+ try {
+ update();
+ done();
+ } catch (const std::exception& e) {
+ failed(e);
+ }
+ delete this;
+}
void UpdateClient::update() {
QPID_LOG(debug, updaterId << " updating state to " << updateeId << " at " << updateeUrl);
Broker& b = updaterBroker;
b.getExchanges().eachExchange(boost::bind(&UpdateClient::updateExchange, this, _1));
-
- // Update exchange is used to route messages to the proper queue without modifying routing key.
- session.exchangeDeclare(arg::exchange=UPDATE, arg::type="fanout", arg::autoDelete=true);
b.getQueues().eachQueue(boost::bind(&UpdateClient::updateQueue, this, _1));
// Update queue is used to transfer acquired messages that are no longer on their original queue.
session.queueDeclare(arg::queue=UPDATE, arg::autoDelete=true);
@@ -121,25 +130,15 @@ void UpdateClient::update() {
std::for_each(connections.begin(), connections.end(), boost::bind(&UpdateClient::updateConnection, this, _1));
+ ClusterConnectionProxy(session).expiryId(expiry.getId());
ClusterConnectionMembershipBody membership;
map.toMethodBody(membership);
- membership.setFrameId(frameId);
AMQFrame frame(membership);
client::ConnectionAccess::getImpl(connection)->handle(frame);
connection.close();
QPID_LOG(debug, updaterId << " updated state to " << updateeId << " at " << updateeUrl);
}
-void UpdateClient::run() {
- try {
- update();
- done();
- } catch (const std::exception& e) {
- failed(e);
- }
- delete this;
-}
-
namespace {
template <class T> std::string encode(const T& t) {
std::string encoded;
@@ -152,8 +151,7 @@ template <class T> std::string encode(const T& t) {
void UpdateClient::updateExchange(const boost::shared_ptr<Exchange>& ex) {
QPID_LOG(debug, updaterId << " updating exchange " << ex->getName());
- ClusterConnectionProxy proxy(session);
- proxy.exchange(encode(*ex));
+ ClusterConnectionProxy(session).exchange(encode(*ex));
}
/** Bind a queue to the update exchange and update messges to it
@@ -164,24 +162,40 @@ class MessageUpdater {
bool haveLastPos;
framing::SequenceNumber lastPos;
client::AsyncSession session;
-
+ ExpiryPolicy& expiry;
+
public:
- MessageUpdater(const string& q, const client::AsyncSession s) : queue(q), haveLastPos(false), session(s) {
+ MessageUpdater(const string& q, const client::AsyncSession s, ExpiryPolicy& expiry_) : queue(q), haveLastPos(false), session(s), expiry(expiry_) {
session.exchangeBind(queue, UpdateClient::UPDATE);
}
~MessageUpdater() {
- session.exchangeUnbind(queue, UpdateClient::UPDATE);
+ try {
+ session.exchangeUnbind(queue, UpdateClient::UPDATE);
+ }
+ catch (const std::exception& e) {
+ // Don't throw in a destructor.
+ QPID_LOG(error, "Unbinding update queue " << queue << ": " << e.what());
+ }
}
void updateQueuedMessage(const broker::QueuedMessage& message) {
+ // Send the queue position if necessary.
if (!haveLastPos || message.position - lastPos != 1) {
ClusterConnectionProxy(session).queuePosition(queue, message.position.getValue()-1);
haveLastPos = true;
}
lastPos = message.position;
+
+ // Send the expiry ID if necessary.
+ if (message.payload->getProperties<DeliveryProperties>()->getTtl()) {
+ boost::optional<uint64_t> expiryId = expiry.getId(*message.payload);
+ if (!expiryId) return; // Message already expired, don't replicate.
+ ClusterConnectionProxy(session).expiryId(*expiryId);
+ }
+
SessionBase_0_10Access sb(session);
framing::MessageTransferBody transfer(
framing::ProtocolVersion(), UpdateClient::UPDATE, message::ACCEPT_MODE_NONE, message::ACQUIRE_MODE_PRE_ACQUIRED);
@@ -204,16 +218,13 @@ class MessageUpdater {
void updateMessage(const boost::intrusive_ptr<broker::Message>& message) {
updateQueuedMessage(broker::QueuedMessage(0, message, haveLastPos? lastPos.getValue()+1 : 1));
}
-
-
};
-
void UpdateClient::updateQueue(const boost::shared_ptr<Queue>& q) {
QPID_LOG(debug, updaterId << " updating queue " << q->getName());
ClusterConnectionProxy proxy(session);
proxy.queue(encode(*q));
- MessageUpdater updater(q->getName(), session);
+ MessageUpdater updater(q->getName(), session, expiry);
q->eachMessage(boost::bind(&MessageUpdater::updateQueuedMessage, &updater, _1));
q->eachBinding(boost::bind(&UpdateClient::updateBinding, this, q->getName(), _1));
}
@@ -228,13 +239,16 @@ void UpdateClient::updateConnection(const boost::intrusive_ptr<Connection>& upda
shadowConnection = catchUpConnection();
broker::Connection& bc = updateConnection->getBrokerConnection();
- // FIXME aconway 2008-10-20: What authentication info to use on reconnect?
- shadowConnection.open(updateeUrl, bc.getUserId(), ""/*password*/, "/"/*vhost*/, bc.getFrameMax());
+ connectionSettings.maxFrameSize = bc.getFrameMax();
+ shadowConnection.open(updateeUrl, connectionSettings);
bc.eachSessionHandler(boost::bind(&UpdateClient::updateSession, this, _1));
+ // Safe to use decoder here because we are stalled for update.
+ std::pair<const char*, size_t> fragment = decoder.get(updateConnection->getId()).getFragment();
ClusterConnectionProxy(shadowConnection).shadowReady(
updateConnection->getId().getMember(),
- reinterpret_cast<uint64_t>(updateConnection->getId().getPointer()),
- updateConnection->getBrokerConnection().getUserId()
+ updateConnection->getId().getNumber(),
+ bc.getUserId(),
+ string(fragment.first, fragment.second)
);
shadowConnection.close();
QPID_LOG(debug, updaterId << " updated connection " << *updateConnection);
@@ -269,7 +283,7 @@ void UpdateClient::updateSession(broker::SessionHandler& sh) {
SequenceNumber received = ss->receiverGetReceived().command;
if (inProgress)
--received;
-
+
// Reset command-sequence state.
proxy.sessionState(
ss->senderGetReplayPoint().command,
@@ -285,9 +299,6 @@ void UpdateClient::updateSession(broker::SessionHandler& sh) {
if (inProgress) {
inProgress->getFrames().map(simpl->out);
}
-
- // FIXME aconway 2008-09-23: update session replay list.
-
QPID_LOG(debug, updaterId << " updated session " << sh.getSession()->getId());
}
@@ -322,7 +333,7 @@ void UpdateClient::updateUnacked(const broker::DeliveryRecord& dr) {
// If the message is acquired then it is no longer on the
// updatees queue, put it on the update queue for updatee to pick up.
//
- MessageUpdater(UPDATE, shadowSession).updateQueuedMessage(dr.getMessage());
+ MessageUpdater(UPDATE, shadowSession, expiry).updateQueuedMessage(dr.getMessage());
}
ClusterConnectionProxy(shadowSession).deliveryRecord(
dr.getQueue()->getName(),
@@ -341,8 +352,8 @@ void UpdateClient::updateUnacked(const broker::DeliveryRecord& dr) {
class TxOpUpdater : public broker::TxOpConstVisitor, public MessageUpdater {
public:
- TxOpUpdater(UpdateClient& dc, client::AsyncSession s)
- : MessageUpdater(UpdateClient::UPDATE, s), parent(dc), session(s), proxy(s) {}
+ TxOpUpdater(UpdateClient& dc, client::AsyncSession s, ExpiryPolicy& expiry)
+ : MessageUpdater(UpdateClient::UPDATE, s, expiry), parent(dc), session(s), proxy(s) {}
void operator()(const broker::DtxAck& ) {
throw InternalErrorException("DTX transactions not currently supported by cluster.");
@@ -385,7 +396,7 @@ void UpdateClient::updateTxState(broker::SemanticState& s) {
broker::TxBuffer::shared_ptr txBuffer = s.getTxBuffer();
if (txBuffer) {
proxy.txStart();
- TxOpUpdater updater(*this, shadowSession);
+ TxOpUpdater updater(*this, shadowSession, expiry);
txBuffer->accept(updater);
proxy.txEnd();
}
diff --git a/qpid/cpp/src/qpid/cluster/UpdateClient.h b/qpid/cpp/src/qpid/cluster/UpdateClient.h
index 23f647c820..23d061b7e4 100644
--- a/qpid/cpp/src/qpid/cluster/UpdateClient.h
+++ b/qpid/cpp/src/qpid/cluster/UpdateClient.h
@@ -46,6 +46,7 @@ class SessionHandler;
class DeliveryRecord;
class SessionState;
class SemanticState;
+class Decoder;
} // namespace broker
@@ -54,6 +55,8 @@ namespace cluster {
class Cluster;
class Connection;
class ClusterMap;
+class Decoder;
+class ExpiryPolicy;
/**
* A client that updates the contents of a local broker to a remote one using AMQP.
@@ -63,8 +66,8 @@ class UpdateClient : public sys::Runnable {
static const std::string UPDATE; // Name for special update queue and exchange.
UpdateClient(const MemberId& updater, const MemberId& updatee, const Url&,
- broker::Broker& donor, const ClusterMap& map, uint64_t sequence,
- const std::vector<boost::intrusive_ptr<Connection> >& ,
+ broker::Broker& donor, const ClusterMap& map, ExpiryPolicy& expiry,
+ const std::vector<boost::intrusive_ptr<Connection> >&, Decoder&,
const boost::function<void()>& done,
const boost::function<void(const std::exception&)>& fail,
const client::ConnectionSettings&
@@ -92,12 +95,14 @@ class UpdateClient : public sys::Runnable {
Url updateeUrl;
broker::Broker& updaterBroker;
ClusterMap map;
- uint64_t frameId;
+ ExpiryPolicy& expiry;
std::vector<boost::intrusive_ptr<Connection> > connections;
+ Decoder& decoder;
client::Connection connection, shadowConnection;
client::AsyncSession session, shadowSession;
boost::function<void()> done;
boost::function<void(const std::exception& e)> failed;
+ client::ConnectionSettings connectionSettings;
};
}} // namespace qpid::cluster
diff --git a/qpid/cpp/src/qpid/cluster/UpdateExchange.h b/qpid/cpp/src/qpid/cluster/UpdateExchange.h
new file mode 100644
index 0000000000..7a4a484c8a
--- /dev/null
+++ b/qpid/cpp/src/qpid/cluster/UpdateExchange.h
@@ -0,0 +1,45 @@
+#ifndef QPID_CLUSTER_UPDATEEXCHANGE_H
+#define QPID_CLUSTER_UPDATEEXCHANGE_H
+
+/*
+ *
+ * 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.
+ *
+ */
+
+#include "UpdateClient.h"
+#include "qpid/broker/FanOutExchange.h"
+
+
+namespace qpid {
+namespace cluster {
+
+/**
+ * A keyless exchange (like fanout exchange) that does not modify deliver-properties.exchange
+ * on messages.
+ */
+class UpdateExchange : public broker::FanOutExchange
+{
+ public:
+ UpdateExchange(management::Manageable* parent) : broker::Exchange(UpdateClient::UPDATE, parent), broker::FanOutExchange(UpdateClient::UPDATE, parent) {}
+ void setProperties(const boost::intrusive_ptr<broker::Message>&) {}
+};
+
+}} // namespace qpid::cluster
+
+#endif /*!QPID_CLUSTER_UPDATEEXCHANGE_H*/
diff --git a/qpid/cpp/src/qpid/cluster/types.h b/qpid/cpp/src/qpid/cluster/types.h
index d1d6fdc427..c19152e4d8 100644
--- a/qpid/cpp/src/qpid/cluster/types.h
+++ b/qpid/cpp/src/qpid/cluster/types.h
@@ -68,16 +68,17 @@ inline bool operator==(const cpg_address& caddr, const MemberId& id) { return id
std::ostream& operator<<(std::ostream&, const MemberId&);
-struct ConnectionId : public std::pair<MemberId, Connection*> {
- ConnectionId(const MemberId& m=MemberId(), Connection* c=0) : std::pair<MemberId, Connection*> (m,c) {}
- ConnectionId(uint64_t m, uint64_t c)
- : std::pair<MemberId, Connection*>(MemberId(m), reinterpret_cast<Connection*>(c)) {}
+struct ConnectionId : public std::pair<MemberId, uint64_t> {
+ ConnectionId(const MemberId& m=MemberId(), uint64_t c=0) : std::pair<MemberId, uint64_t> (m,c) {}
+ ConnectionId(uint64_t m, uint64_t c) : std::pair<MemberId, uint64_t>(MemberId(m), c) {}
MemberId getMember() const { return first; }
- Connection* getPointer() const { return second; }
+ uint64_t getNumber() const { return second; }
};
std::ostream& operator<<(std::ostream&, const ConnectionId&);
+std::ostream& operator<<(std::ostream&, EventType);
+
}} // namespace qpid::cluster
#endif /*!QPID_CLUSTER_TYPES_H*/
diff --git a/qpid/cpp/src/qpid/console/Agent.h b/qpid/cpp/src/qpid/console/Agent.h
index 3307a1b44b..884d4c92bd 100644
--- a/qpid/cpp/src/qpid/console/Agent.h
+++ b/qpid/cpp/src/qpid/console/Agent.h
@@ -22,6 +22,7 @@
#define _QPID_CONSOLE_AGENT_H_
#include "Broker.h"
+#include "ConsoleImportExport.h"
namespace qpid {
namespace console {
@@ -30,7 +31,7 @@ namespace console {
*
* \ingroup qmfconsoleapi
*/
- class Agent {
+ class QPID_CONSOLE_EXTERN Agent {
public:
typedef std::vector<Agent*> Vector;
@@ -49,7 +50,7 @@ namespace console {
const std::string label;
};
- std::ostream& operator<<(std::ostream& o, const Agent& agent);
+ QPID_CONSOLE_EXTERN std::ostream& operator<<(std::ostream& o, const Agent& agent);
}
}
diff --git a/qpid/cpp/src/qpid/console/Broker.h b/qpid/cpp/src/qpid/console/Broker.h
index 9df2380dff..ddbd973dfe 100644
--- a/qpid/cpp/src/qpid/console/Broker.h
+++ b/qpid/cpp/src/qpid/console/Broker.h
@@ -21,6 +21,7 @@
#ifndef _QPID_CONSOLE_BROKER_H_
#define _QPID_CONSOLE_BROKER_H_
+#include "ConsoleImportExport.h"
#include "qpid/client/Connection.h"
#include "qpid/client/ConnectionSettings.h"
#include "qpid/client/SubscriptionManager.h"
@@ -50,8 +51,9 @@ namespace console {
*/
class Broker : public client::MessageListener {
public:
- Broker(SessionManager& sm, client::ConnectionSettings& settings);
- ~Broker();
+ QPID_CONSOLE_EXTERN Broker(SessionManager& sm,
+ client::ConnectionSettings& settings);
+ QPID_CONSOLE_EXTERN ~Broker();
bool isConnected() const { return connected; }
const std::string& getError() const { return error; }
@@ -61,7 +63,7 @@ namespace console {
void addBinding(const std::string& key) {
connThreadBody.bindExchange("qpid.management", key);
}
- std::string getUrl() const;
+ QPID_CONSOLE_EXTERN std::string getUrl() const;
private:
friend class SessionManager;
@@ -120,10 +122,10 @@ namespace console {
void setBrokerId(const framing::Uuid& id) { brokerId = id; }
void appendAgents(std::vector<Agent*>& agents) const;
- friend std::ostream& operator<<(std::ostream& o, const Broker& k);
+ friend QPID_CONSOLE_EXTERN std::ostream& operator<<(std::ostream& o, const Broker& k);
};
- std::ostream& operator<<(std::ostream& o, const Broker& k);
+ QPID_CONSOLE_EXTERN std::ostream& operator<<(std::ostream& o, const Broker& k);
}
}
diff --git a/qpid/cpp/src/qpid/console/ClassKey.cpp b/qpid/cpp/src/qpid/console/ClassKey.cpp
index 1780b03f94..b97eb3ca44 100644
--- a/qpid/cpp/src/qpid/console/ClassKey.cpp
+++ b/qpid/cpp/src/qpid/console/ClassKey.cpp
@@ -21,6 +21,7 @@
#include "ClassKey.h"
#include <string.h>
+#include <cstdio>
using namespace std;
using namespace qpid::console;
diff --git a/qpid/cpp/src/qpid/console/ClassKey.h b/qpid/cpp/src/qpid/console/ClassKey.h
index f6617e22d5..821b01c4ef 100644
--- a/qpid/cpp/src/qpid/console/ClassKey.h
+++ b/qpid/cpp/src/qpid/console/ClassKey.h
@@ -22,6 +22,7 @@
#define _QPID_CONSOLE_CLASSKEY_H_
#include <string>
+#include "ConsoleImportExport.h"
#include "Package.h"
#include "qpid/framing/Buffer.h"
@@ -32,7 +33,7 @@ namespace console {
*
* \ingroup qmfconsoleapi
*/
- class ClassKey {
+ class QPID_CONSOLE_EXTERN ClassKey {
public:
static const int HASH_SIZE = 16;
@@ -57,7 +58,7 @@ namespace console {
uint8_t hash[HASH_SIZE];
};
- std::ostream& operator<<(std::ostream& o, const ClassKey& k);
+ QPID_CONSOLE_EXTERN std::ostream& operator<<(std::ostream& o, const ClassKey& k);
}
}
diff --git a/qpid/cpp/src/qpid/console/ConsoleImportExport.h b/qpid/cpp/src/qpid/console/ConsoleImportExport.h
new file mode 100644
index 0000000000..e2d0af9db3
--- /dev/null
+++ b/qpid/cpp/src/qpid/console/ConsoleImportExport.h
@@ -0,0 +1,33 @@
+#ifndef QPID_CONSOLE_IMPORT_EXPORT_H
+#define QPID_CONSOLE_IMPORT_EXPORT_H
+
+/*
+ * 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.
+ */
+
+#if defined(WIN32) && !defined(QPID_DECLARE_STATIC)
+#if defined(CONSOLE_EXPORT)
+#define QPID_CONSOLE_EXTERN __declspec(dllexport)
+#else
+#define QPID_CONSOLE_EXTERN __declspec(dllimport)
+#endif
+#else
+#define QPID_CONSOLE_EXTERN
+#endif
+
+#endif
diff --git a/qpid/cpp/src/qpid/console/ConsoleListener.h b/qpid/cpp/src/qpid/console/ConsoleListener.h
index d0db6034f6..d661c63120 100644
--- a/qpid/cpp/src/qpid/console/ConsoleListener.h
+++ b/qpid/cpp/src/qpid/console/ConsoleListener.h
@@ -22,6 +22,7 @@
#define _QPID_CONSOLE_CONSOLE_LISTENER_H_
#include <string>
+#include "ConsoleImportExport.h"
#include "Broker.h"
#include "ClassKey.h"
#include "Object.h"
@@ -36,7 +37,7 @@ namespace console {
*
* \ingroup qmfconsoleapi
*/
- class ConsoleListener{
+ class QPID_CONSOLE_EXTERN ConsoleListener{
public:
virtual ~ConsoleListener() {};
diff --git a/qpid/cpp/src/qpid/console/Event.h b/qpid/cpp/src/qpid/console/Event.h
index 14f5a64716..4d51708965 100644
--- a/qpid/cpp/src/qpid/console/Event.h
+++ b/qpid/cpp/src/qpid/console/Event.h
@@ -21,6 +21,7 @@
#ifndef _QPID_CONSOLE_EVENT_H_
#define _QPID_CONSOLE_EVENT_H_
+#include "ConsoleImportExport.h"
#include "Object.h"
#include "qpid/framing/Uuid.h"
#include "qpid/framing/FieldTable.h"
@@ -46,26 +47,28 @@ namespace console {
SEV_WARNING = 4, SEV_NOTICE = 5, SEV_INFO = 6, SEV_DEBUG = 7
} Severity;
- Event(Broker* broker, SchemaClass* schemaClass, framing::Buffer& buffer);
+ QPID_CONSOLE_EXTERN Event(Broker* broker,
+ SchemaClass* schemaClass,
+ framing::Buffer& buffer);
Broker* getBroker() const { return broker; }
- const ClassKey& getClassKey() const;
+ QPID_CONSOLE_EXTERN const ClassKey& getClassKey() const;
SchemaClass* getSchema() const { return schema; }
const Object::AttributeMap& getAttributes() const { return attributes; }
uint64_t getTimestamp() const { return timestamp; }
uint8_t getSeverity() const { return severity; }
- std::string getSeverityString() const;
+ QPID_CONSOLE_EXTERN std::string getSeverityString() const;
- ObjectId attrRef(const std::string& key) const;
- uint32_t attrUint(const std::string& key) const;
- int32_t attrInt(const std::string& key) const;
- uint64_t attrUint64(const std::string& key) const;
- int64_t attrInt64(const std::string& key) const;
- std::string attrString(const std::string& key) const;
- bool attrBool(const std::string& key) const;
- float attrFloat(const std::string& key) const;
- double attrDouble(const std::string& key) const;
- framing::Uuid attrUuid(const std::string& key) const;
- framing::FieldTable attrMap(const std::string& key) const;
+ QPID_CONSOLE_EXTERN ObjectId attrRef(const std::string& key) const;
+ QPID_CONSOLE_EXTERN uint32_t attrUint(const std::string& key) const;
+ QPID_CONSOLE_EXTERN int32_t attrInt(const std::string& key) const;
+ QPID_CONSOLE_EXTERN uint64_t attrUint64(const std::string& key) const;
+ QPID_CONSOLE_EXTERN int64_t attrInt64(const std::string& key) const;
+ QPID_CONSOLE_EXTERN std::string attrString(const std::string& key) const;
+ QPID_CONSOLE_EXTERN bool attrBool(const std::string& key) const;
+ QPID_CONSOLE_EXTERN float attrFloat(const std::string& key) const;
+ QPID_CONSOLE_EXTERN double attrDouble(const std::string& key) const;
+ QPID_CONSOLE_EXTERN framing::Uuid attrUuid(const std::string& key) const;
+ QPID_CONSOLE_EXTERN framing::FieldTable attrMap(const std::string& key) const;
private:
Broker* broker;
@@ -75,7 +78,7 @@ namespace console {
Object::AttributeMap attributes;
};
- std::ostream& operator<<(std::ostream& o, const Event& event);
+ QPID_CONSOLE_EXTERN std::ostream& operator<<(std::ostream& o, const Event& event);
}
}
diff --git a/qpid/cpp/src/qpid/console/Object.h b/qpid/cpp/src/qpid/console/Object.h
index 2c6993fc8a..d2fb09ecca 100644
--- a/qpid/cpp/src/qpid/console/Object.h
+++ b/qpid/cpp/src/qpid/console/Object.h
@@ -21,6 +21,7 @@
#ifndef _QPID_CONSOLE_OBJECT_H_
#define _QPID_CONSOLE_OBJECT_H_
+#include "ConsoleImportExport.h"
#include "ObjectId.h"
#include "qpid/framing/Uuid.h"
#include "qpid/framing/FieldTable.h"
@@ -55,47 +56,50 @@ namespace console {
public:
typedef std::vector<Object> Vector;
struct AttributeMap : public std::map<std::string, boost::shared_ptr<Value> > {
- void addRef(const std::string& key, const ObjectId& val);
- void addUint(const std::string& key, uint32_t val);
- void addInt(const std::string& key, int32_t val);
- void addUint64(const std::string& key, uint64_t val);
- void addInt64(const std::string& key, int64_t val);
- void addString(const std::string& key, const std::string& val);
- void addBool(const std::string& key, bool val);
- void addFloat(const std::string& key, float val);
- void addDouble(const std::string& key, double val);
- void addUuid(const std::string& key, const framing::Uuid& val);
- void addMap(const std::string& key, const framing::FieldTable& val);
+ QPID_CONSOLE_EXTERN void addRef(const std::string& key, const ObjectId& val);
+ QPID_CONSOLE_EXTERN void addUint(const std::string& key, uint32_t val);
+ QPID_CONSOLE_EXTERN void addInt(const std::string& key, int32_t val);
+ QPID_CONSOLE_EXTERN void addUint64(const std::string& key, uint64_t val);
+ QPID_CONSOLE_EXTERN void addInt64(const std::string& key, int64_t val);
+ QPID_CONSOLE_EXTERN void addString(const std::string& key, const std::string& val);
+ QPID_CONSOLE_EXTERN void addBool(const std::string& key, bool val);
+ QPID_CONSOLE_EXTERN void addFloat(const std::string& key, float val);
+ QPID_CONSOLE_EXTERN void addDouble(const std::string& key, double val);
+ QPID_CONSOLE_EXTERN void addUuid(const std::string& key, const framing::Uuid& val);
+ QPID_CONSOLE_EXTERN void addMap(const std::string& key, const framing::FieldTable& val);
};
- Object(Broker* broker, SchemaClass* schemaClass, framing::Buffer& buffer, bool prop, bool stat);
- ~Object();
+ QPID_CONSOLE_EXTERN Object(Broker* broker, SchemaClass* schemaClass, framing::Buffer& buffer, bool prop, bool stat);
+ QPID_CONSOLE_EXTERN ~Object();
Broker* getBroker() const { return broker; }
const ObjectId& getObjectId() const { return objectId; }
- const ClassKey& getClassKey() const;
+ QPID_CONSOLE_EXTERN const ClassKey& getClassKey() const;
SchemaClass* getSchema() const { return schema; }
uint64_t getCurrentTime() const { return currentTime; }
uint64_t getCreateTime() const { return createTime; }
uint64_t getDeleteTime() const { return deleteTime; }
bool isDeleted() const { return deleteTime != 0; }
- std::string getIndex() const;
- void mergeUpdate(const Object& updated);
+ QPID_CONSOLE_EXTERN std::string getIndex() const;
+ QPID_CONSOLE_EXTERN void mergeUpdate(const Object& updated);
const AttributeMap& getAttributes() const { return attributes; }
- void invokeMethod(const std::string name, const AttributeMap& args, MethodResponse& result);
- void handleMethodResp(framing::Buffer& buffer, uint32_t sequence);
+ QPID_CONSOLE_EXTERN void invokeMethod(const std::string name,
+ const AttributeMap& args,
+ MethodResponse& result);
+ QPID_CONSOLE_EXTERN void handleMethodResp(framing::Buffer& buffer,
+ uint32_t sequence);
- ObjectId attrRef(const std::string& key) const;
- uint32_t attrUint(const std::string& key) const;
- int32_t attrInt(const std::string& key) const;
- uint64_t attrUint64(const std::string& key) const;
- int64_t attrInt64(const std::string& key) const;
- std::string attrString(const std::string& key) const;
- bool attrBool(const std::string& key) const;
- float attrFloat(const std::string& key) const;
- double attrDouble(const std::string& key) const;
- framing::Uuid attrUuid(const std::string& key) const;
- framing::FieldTable attrMap(const std::string& key) const;
+ QPID_CONSOLE_EXTERN ObjectId attrRef(const std::string& key) const;
+ QPID_CONSOLE_EXTERN uint32_t attrUint(const std::string& key) const;
+ QPID_CONSOLE_EXTERN int32_t attrInt(const std::string& key) const;
+ QPID_CONSOLE_EXTERN uint64_t attrUint64(const std::string& key) const;
+ QPID_CONSOLE_EXTERN int64_t attrInt64(const std::string& key) const;
+ QPID_CONSOLE_EXTERN std::string attrString(const std::string& key) const;
+ QPID_CONSOLE_EXTERN bool attrBool(const std::string& key) const;
+ QPID_CONSOLE_EXTERN float attrFloat(const std::string& key) const;
+ QPID_CONSOLE_EXTERN double attrDouble(const std::string& key) const;
+ QPID_CONSOLE_EXTERN framing::Uuid attrUuid(const std::string& key) const;
+ QPID_CONSOLE_EXTERN framing::FieldTable attrMap(const std::string& key) const;
private:
Broker* broker;
@@ -111,7 +115,7 @@ namespace console {
void parsePresenceMasks(framing::Buffer& buffer, std::set<std::string>& excludeList);
};
- std::ostream& operator<<(std::ostream& o, const Object& object);
+ QPID_CONSOLE_EXTERN std::ostream& operator<<(std::ostream& o, const Object& object);
}
}
diff --git a/qpid/cpp/src/qpid/console/ObjectId.h b/qpid/cpp/src/qpid/console/ObjectId.h
index 73304ca306..ac0e8d8b03 100644
--- a/qpid/cpp/src/qpid/console/ObjectId.h
+++ b/qpid/cpp/src/qpid/console/ObjectId.h
@@ -22,6 +22,7 @@
#define _QPID_CONSOLE_OBJECTID_H
#include <iostream>
+#include "ConsoleImportExport.h"
#include "qpid/sys/IntegerTypes.h"
namespace qpid {
@@ -34,7 +35,7 @@ namespace console {
*
* \ingroup qmfconsoleapi
*/
- class ObjectId {
+ class QPID_CONSOLE_EXTERN ObjectId {
public:
ObjectId() : first(0), second(0) {}
ObjectId(framing::Buffer& buffer);
@@ -61,7 +62,7 @@ namespace console {
uint64_t second;
};
- std::ostream& operator<<(std::ostream& o, const ObjectId& id);
+ QPID_CONSOLE_EXTERN std::ostream& operator<<(std::ostream& o, const ObjectId& id);
}
}
diff --git a/qpid/cpp/src/qpid/console/Package.h b/qpid/cpp/src/qpid/console/Package.h
index 18203cb807..3cc63c8b75 100644
--- a/qpid/cpp/src/qpid/console/Package.h
+++ b/qpid/cpp/src/qpid/console/Package.h
@@ -23,6 +23,7 @@
#include <string>
#include <map>
+#include "ConsoleImportExport.h"
#include "qpid/sys/IntegerTypes.h"
namespace qpid {
diff --git a/qpid/cpp/src/qpid/console/SequenceManager.h b/qpid/cpp/src/qpid/console/SequenceManager.h
index c7a8c20fe6..5a041f530b 100644
--- a/qpid/cpp/src/qpid/console/SequenceManager.h
+++ b/qpid/cpp/src/qpid/console/SequenceManager.h
@@ -21,6 +21,7 @@
#ifndef _QPID_CONSOLE_SEQUENCEMANAGER_H_
#define _QPID_CONSOLE_SEQUENCEMANAGER_H_
+#include "ConsoleImportExport.h"
#include "qpid/sys/Mutex.h"
#include <map>
#include <string>
@@ -38,8 +39,8 @@ namespace console {
typedef std::set<uint32_t> set;
SequenceManager() : sequence(0) {}
- uint32_t reserve(const std::string& context = "");
- std::string release(uint32_t seq);
+ QPID_CONSOLE_EXTERN uint32_t reserve(const std::string& context = "");
+ QPID_CONSOLE_EXTERN std::string release(uint32_t seq);
private:
sys::Mutex lock;
diff --git a/qpid/cpp/src/qpid/console/SessionManager.h b/qpid/cpp/src/qpid/console/SessionManager.h
index ab6e111caa..4341fe317c 100644
--- a/qpid/cpp/src/qpid/console/SessionManager.h
+++ b/qpid/cpp/src/qpid/console/SessionManager.h
@@ -22,6 +22,7 @@
*
*/
+#include "ConsoleImportExport.h"
#include "Broker.h"
#include "Package.h"
#include "SequenceManager.h"
@@ -80,8 +81,8 @@ class SessionManager
* and bindClass methods. If userBindings is false, the listener will receive
* updates for all object classes.
*/
- SessionManager(ConsoleListener* listener = 0,
- Settings settings = Settings());
+ QPID_CONSOLE_EXTERN SessionManager(ConsoleListener* listener = 0,
+ Settings settings = Settings());
/** Connect a broker to the console session
*
@@ -89,32 +90,33 @@ class SessionManager
*@return broker object if operation is successful
* an exception shall be thrown.
*/
- Broker* addBroker(client::ConnectionSettings& settings);
+ QPID_CONSOLE_EXTERN Broker* addBroker(client::ConnectionSettings& settings);
/** Disconnect a broker from the console session
*
*@param broker The broker object returned from an earlier call to addBroker.
*/
- void delBroker(Broker* broker);
+ QPID_CONSOLE_EXTERN void delBroker(Broker* broker);
/** Get a list of known management packages
*
*@param packages Vector of package names returned by the session manager.
*/
- void getPackages(NameVector& packages);
+ QPID_CONSOLE_EXTERN void getPackages(NameVector& packages);
/** Get a list of class keys associated with a package
*
*@param classKeys List of class keys returned by the session manager.
*@param packageName Name of package being queried.
*/
- void getClasses(KeyVector& classKeys, const std::string& packageName);
+ QPID_CONSOLE_EXTERN void getClasses(KeyVector& classKeys,
+ const std::string& packageName);
/** Get the schema of a class given its class key
*
*@param classKey Class key of the desired schema.
*/
- SchemaClass& getSchema(const ClassKey& classKey);
+ QPID_CONSOLE_EXTERN SchemaClass& getSchema(const ClassKey& classKey);
/** Request that updates be received for all classes within a package
*
@@ -123,7 +125,7 @@ class SessionManager
*
*@param packageName Name of the package to which to bind.
*/
- void bindPackage(const std::string& packageName);
+ QPID_CONSOLE_EXTERN void bindPackage(const std::string& packageName);
/** Request update to be received for a particular class
*
@@ -132,8 +134,9 @@ class SessionManager
*
*@param classKey Class key of class to which to bind.
*/
- void bindClass(const ClassKey& classKey);
- void bindClass(const std::string& packageName, const std::string& className);
+ QPID_CONSOLE_EXTERN void bindClass(const ClassKey& classKey);
+ QPID_CONSOLE_EXTERN void bindClass(const std::string& packageName,
+ const std::string& className);
/** Get a list of qmf agents known to the session manager.
*
@@ -141,7 +144,8 @@ class SessionManager
*@param broker Return agents registered with this broker only. If NULL, return agents
* from all connected brokers.
*/
- void getAgents(Agent::Vector& agents, Broker* broker = 0);
+ QPID_CONSOLE_EXTERN void getAgents(Agent::Vector& agents,
+ Broker* broker = 0);
/** Get objects from agents. There are four variants of this method with different ways of
* specifying from which class objects are being queried.
@@ -153,8 +157,10 @@ class SessionManager
*@param broker Restrict the query to this broker, or all brokers if NULL.
*@param agent Restrict the query to this agent, or all agents if NULL.
*/
- void getObjects(Object::Vector& objects, const std::string& className,
- Broker* broker = 0, Agent* agent = 0);
+ QPID_CONSOLE_EXTERN void getObjects(Object::Vector& objects,
+ const std::string& className,
+ Broker* broker = 0,
+ Agent* agent = 0);
//void getObjects(Object::Vector& objects, const ClassKey& classKey,
// Broker* broker = 0, Agent* agent = 0);
//void getObjects(Object::Vector& objects, const ObjectId& objectId,
diff --git a/qpid/cpp/src/qpid/framing/AMQBody.h b/qpid/cpp/src/qpid/framing/AMQBody.h
index 9e66b9738f..60ac2d3b7e 100644
--- a/qpid/cpp/src/qpid/framing/AMQBody.h
+++ b/qpid/cpp/src/qpid/framing/AMQBody.h
@@ -26,6 +26,7 @@
#include "qpid/framing/BodyFactory.h"
#include <boost/intrusive_ptr.hpp>
#include <ostream>
+#include "qpid/CommonImportExport.h"
namespace qpid {
namespace framing {
@@ -48,7 +49,7 @@ struct AMQBodyConstVisitor {
class AMQBody : public RefCounted {
public:
AMQBody() {}
- virtual ~AMQBody();
+ QPID_COMMON_EXTERN virtual ~AMQBody();
// Make AMQBody copyable even though RefCounted.
AMQBody(const AMQBody&) : RefCounted() {}
@@ -71,7 +72,7 @@ class AMQBody : public RefCounted {
virtual boost::intrusive_ptr<AMQBody> clone() const = 0;
};
-std::ostream& operator<<(std::ostream& out, const AMQBody& body) ;
+QPID_COMMON_EXTERN std::ostream& operator<<(std::ostream& out, const AMQBody& body) ;
enum BodyTypes {
METHOD_BODY = 1,
diff --git a/qpid/cpp/src/qpid/framing/AMQContentBody.h b/qpid/cpp/src/qpid/framing/AMQContentBody.h
index a81cf36168..9606ae5ec5 100644
--- a/qpid/cpp/src/qpid/framing/AMQContentBody.h
+++ b/qpid/cpp/src/qpid/framing/AMQContentBody.h
@@ -21,6 +21,7 @@
#include "amqp_types.h"
#include "AMQBody.h"
#include "Buffer.h"
+#include "qpid/CommonImportExport.h"
#ifndef _AMQContentBody_
#define _AMQContentBody_
@@ -33,18 +34,18 @@ class AMQContentBody : public AMQBody
string data;
public:
- AMQContentBody();
- AMQContentBody(const string& data);
+ QPID_COMMON_EXTERN AMQContentBody();
+ QPID_COMMON_EXTERN AMQContentBody(const string& data);
inline virtual ~AMQContentBody(){}
- inline uint8_t type() const { return CONTENT_BODY; };
- inline const string& getData() const { return data; }
- inline string& getData() { return data; }
- uint32_t encodedSize() const;
- void encode(Buffer& buffer) const;
- void decode(Buffer& buffer, uint32_t size);
- void print(std::ostream& out) const;
- void accept(AMQBodyConstVisitor& v) const { v.visit(*this); }
- boost::intrusive_ptr<AMQBody> clone() const { return BodyFactory::copy(*this); }
+ QPID_COMMON_EXTERN inline uint8_t type() const { return CONTENT_BODY; };
+ QPID_COMMON_EXTERN inline const string& getData() const { return data; }
+ QPID_COMMON_EXTERN inline string& getData() { return data; }
+ QPID_COMMON_EXTERN uint32_t encodedSize() const;
+ QPID_COMMON_EXTERN void encode(Buffer& buffer) const;
+ QPID_COMMON_EXTERN void decode(Buffer& buffer, uint32_t size);
+ QPID_COMMON_EXTERN void print(std::ostream& out) const;
+ QPID_COMMON_EXTERN void accept(AMQBodyConstVisitor& v) const { v.visit(*this); }
+ QPID_COMMON_EXTERN boost::intrusive_ptr<AMQBody> clone() const { return BodyFactory::copy(*this); }
};
}
diff --git a/qpid/cpp/src/qpid/framing/AMQFrame.cpp b/qpid/cpp/src/qpid/framing/AMQFrame.cpp
index 80c8e0b56d..9473b2a513 100644
--- a/qpid/cpp/src/qpid/framing/AMQFrame.cpp
+++ b/qpid/cpp/src/qpid/framing/AMQFrame.cpp
@@ -41,7 +41,7 @@ AMQFrame::AMQFrame(const boost::intrusive_ptr<AMQBody>& b) : body(b) { init(); }
AMQFrame::AMQFrame(const AMQBody& b) : body(b.clone()) { init(); }
-AMQFrame::~AMQFrame() {}
+AMQFrame::~AMQFrame() { init(); }
AMQBody* AMQFrame::getBody() {
// Non-const AMQBody* may be used to modify the body.
diff --git a/qpid/cpp/src/qpid/framing/AMQFrame.h b/qpid/cpp/src/qpid/framing/AMQFrame.h
index 028d0c1d8a..34319e7ed4 100644
--- a/qpid/cpp/src/qpid/framing/AMQFrame.h
+++ b/qpid/cpp/src/qpid/framing/AMQFrame.h
@@ -29,6 +29,7 @@
#include "qpid/sys/LatencyMetric.h"
#include <boost/intrusive_ptr.hpp>
#include <boost/cast.hpp>
+#include "qpid/CommonImportExport.h"
namespace qpid {
namespace framing {
@@ -36,15 +37,15 @@ namespace framing {
class AMQFrame : public AMQDataBlock, public sys::LatencyMetricTimestamp
{
public:
- AMQFrame(const boost::intrusive_ptr<AMQBody>& b=0);
- AMQFrame(const AMQBody& b);
- ~AMQFrame();
+ QPID_COMMON_EXTERN AMQFrame(const boost::intrusive_ptr<AMQBody>& b=0);
+ QPID_COMMON_EXTERN AMQFrame(const AMQBody& b);
+ QPID_COMMON_EXTERN ~AMQFrame();
ChannelId getChannel() const { return channel; }
void setChannel(ChannelId c) { channel = c; }
- AMQBody* getBody();
- const AMQBody* getBody() const;
+ QPID_COMMON_EXTERN AMQBody* getBody();
+ QPID_COMMON_EXTERN const AMQBody* getBody() const;
AMQMethodBody* getMethod() { return getBody()->getMethod(); }
const AMQMethodBody* getMethod() const { return getBody()->getMethod(); }
@@ -59,9 +60,9 @@ class AMQFrame : public AMQDataBlock, public sys::LatencyMetricTimestamp
return boost::polymorphic_downcast<const T*>(getBody());
}
- void encode(Buffer& buffer) const;
- bool decode(Buffer& buffer);
- uint32_t encodedSize() const;
+ QPID_COMMON_EXTERN void encode(Buffer& buffer) const;
+ QPID_COMMON_EXTERN bool decode(Buffer& buffer);
+ QPID_COMMON_EXTERN uint32_t encodedSize() const;
// 0-10 terminology: first/last frame (in segment) first/last segment (in assembly)
@@ -88,13 +89,10 @@ class AMQFrame : public AMQDataBlock, public sys::LatencyMetricTimestamp
void setEos(bool isEos) { eos = isEos; }
static uint16_t DECODE_SIZE_MIN;
- static uint32_t frameOverhead();
+ QPID_COMMON_EXTERN static uint32_t frameOverhead();
/** Must point to at least DECODE_SIZE_MIN bytes of data */
static uint16_t decodeSize(char* data);
- uint64_t getClusterId() const { return clusterId; }
- void setClusterId(uint64_t id) { clusterId = id; }
-
private:
void init();
@@ -106,10 +104,9 @@ class AMQFrame : public AMQDataBlock, public sys::LatencyMetricTimestamp
bool bos : 1;
bool eos : 1;
mutable uint32_t encodedSizeCache;
- uint64_t clusterId; // Used to identify frames in a clustered broekr.
};
-std::ostream& operator<<(std::ostream&, const AMQFrame&);
+QPID_COMMON_EXTERN std::ostream& operator<<(std::ostream&, const AMQFrame&);
}} // namespace qpid::framing
diff --git a/qpid/cpp/src/qpid/framing/AMQHeaderBody.h b/qpid/cpp/src/qpid/framing/AMQHeaderBody.h
index 9846544949..b8099f2e51 100644
--- a/qpid/cpp/src/qpid/framing/AMQHeaderBody.h
+++ b/qpid/cpp/src/qpid/framing/AMQHeaderBody.h
@@ -26,6 +26,7 @@
#include "Buffer.h"
#include "qpid/framing/DeliveryProperties.h"
#include "qpid/framing/MessageProperties.h"
+#include "qpid/CommonImportExport.h"
#include <iostream>
#include <boost/optional.hpp>
@@ -83,12 +84,12 @@ public:
inline uint8_t type() const { return HEADER_BODY; }
- uint32_t encodedSize() const;
- void encode(Buffer& buffer) const;
- void decode(Buffer& buffer, uint32_t size);
- uint64_t getContentLength() const;
- void print(std::ostream& out) const;
- void accept(AMQBodyConstVisitor&) const;
+ QPID_COMMON_EXTERN uint32_t encodedSize() const;
+ QPID_COMMON_EXTERN void encode(Buffer& buffer) const;
+ QPID_COMMON_EXTERN void decode(Buffer& buffer, uint32_t size);
+ QPID_COMMON_EXTERN uint64_t getContentLength() const;
+ QPID_COMMON_EXTERN void print(std::ostream& out) const;
+ QPID_COMMON_EXTERN void accept(AMQBodyConstVisitor&) const;
template <class T> T* get(bool create) {
boost::optional<T>& p=properties.OptProps<T>::props;
diff --git a/qpid/cpp/src/qpid/framing/AMQHeartbeatBody.h b/qpid/cpp/src/qpid/framing/AMQHeartbeatBody.h
index 3fb41c128e..5d3f633576 100644
--- a/qpid/cpp/src/qpid/framing/AMQHeartbeatBody.h
+++ b/qpid/cpp/src/qpid/framing/AMQHeartbeatBody.h
@@ -21,6 +21,7 @@
#include "amqp_types.h"
#include "AMQBody.h"
#include "Buffer.h"
+#include "qpid/CommonImportExport.h"
#ifndef _AMQHeartbeatBody_
#define _AMQHeartbeatBody_
@@ -31,12 +32,12 @@ namespace framing {
class AMQHeartbeatBody : public AMQBody
{
public:
- virtual ~AMQHeartbeatBody();
+ QPID_COMMON_EXTERN virtual ~AMQHeartbeatBody();
inline uint32_t encodedSize() const { return 0; }
inline uint8_t type() const { return HEARTBEAT_BODY; }
inline void encode(Buffer& ) const {}
inline void decode(Buffer& , uint32_t /*size*/) {}
- virtual void print(std::ostream& out) const;
+ QPID_COMMON_EXTERN virtual void print(std::ostream& out) const;
void accept(AMQBodyConstVisitor& v) const { v.visit(*this); }
boost::intrusive_ptr<AMQBody> clone() const { return BodyFactory::copy(*this); }
};
diff --git a/qpid/cpp/src/qpid/framing/AMQMethodBody.h b/qpid/cpp/src/qpid/framing/AMQMethodBody.h
index cc7489ddd9..a38726b0fc 100644
--- a/qpid/cpp/src/qpid/framing/AMQMethodBody.h
+++ b/qpid/cpp/src/qpid/framing/AMQMethodBody.h
@@ -25,7 +25,7 @@
#include "AMQBody.h"
#include "qpid/framing/ProtocolVersion.h"
#include "qpid/shared_ptr.h"
-
+#include "qpid/CommonImportExport.h"
#include <ostream>
#include <assert.h>
@@ -40,7 +40,7 @@ class MethodBodyConstVisitor;
class AMQMethodBody : public AMQBody {
public:
AMQMethodBody() {}
- virtual ~AMQMethodBody();
+ QPID_COMMON_EXTERN virtual ~AMQMethodBody();
virtual void accept(MethodBodyConstVisitor&) const = 0;
diff --git a/qpid/cpp/src/qpid/framing/AccumulatedAck.h b/qpid/cpp/src/qpid/framing/AccumulatedAck.h
index ea78b797e0..ede73897c7 100644
--- a/qpid/cpp/src/qpid/framing/AccumulatedAck.h
+++ b/qpid/cpp/src/qpid/framing/AccumulatedAck.h
@@ -27,6 +27,7 @@
#include <ostream>
#include "SequenceNumber.h"
#include "SequenceNumberSet.h"
+#include "qpid/CommonImportExport.h"
namespace qpid {
namespace framing {
@@ -58,17 +59,17 @@ namespace qpid {
*/
std::list<Range> ranges;
- explicit AccumulatedAck(SequenceNumber r = SequenceNumber());
- void update(SequenceNumber firstTag, SequenceNumber lastTag);
- void consolidate();
- void clear();
- bool covers(SequenceNumber tag) const;
+ QPID_COMMON_EXTERN explicit AccumulatedAck(SequenceNumber r = SequenceNumber());
+ QPID_COMMON_EXTERN void update(SequenceNumber firstTag, SequenceNumber lastTag);
+ QPID_COMMON_EXTERN void consolidate();
+ QPID_COMMON_EXTERN void clear();
+ QPID_COMMON_EXTERN bool covers(SequenceNumber tag) const;
void collectRanges(SequenceNumberSet& set) const;
- void update(const SequenceNumber cumulative, const SequenceNumberSet& range);
+ QPID_COMMON_EXTERN void update(const SequenceNumber cumulative, const SequenceNumberSet& range);
void operator()(SequenceNumber first, SequenceNumber last) { update(first, last); }
};
- std::ostream& operator<<(std::ostream&, const Range&);
- std::ostream& operator<<(std::ostream&, const AccumulatedAck&);
+ QPID_COMMON_EXTERN std::ostream& operator<<(std::ostream&, const Range&);
+ QPID_COMMON_EXTERN std::ostream& operator<<(std::ostream&, const AccumulatedAck&);
}
}
diff --git a/qpid/cpp/src/qpid/framing/Array.h b/qpid/cpp/src/qpid/framing/Array.h
index 183fcb6d5c..0b6b704ed2 100644
--- a/qpid/cpp/src/qpid/framing/Array.h
+++ b/qpid/cpp/src/qpid/framing/Array.h
@@ -24,6 +24,7 @@
#include <boost/shared_ptr.hpp>
#include <iostream>
#include <vector>
+#include "qpid/CommonImportExport.h"
#ifndef _Array_
#define _Array_
@@ -41,38 +42,38 @@ class Array
typedef ValueVector::const_iterator const_iterator;
typedef ValueVector::iterator iterator;
- uint32_t encodedSize() const;
- void encode(Buffer& buffer) const;
- void decode(Buffer& buffer);
+ QPID_COMMON_EXTERN uint32_t encodedSize() const;
+ QPID_COMMON_EXTERN void encode(Buffer& buffer) const;
+ QPID_COMMON_EXTERN void decode(Buffer& buffer);
- int count() const;
- bool operator==(const Array& other) const;
+ QPID_COMMON_EXTERN int count() const;
+ QPID_COMMON_EXTERN bool operator==(const Array& other) const;
- Array();
- Array(TypeCode type);
- Array(uint8_t type);
+ QPID_COMMON_EXTERN Array();
+ QPID_COMMON_EXTERN Array(TypeCode type);
+ QPID_COMMON_EXTERN Array(uint8_t type);
//creates a longstr array
- Array(const std::vector<std::string>& in);
+ QPID_COMMON_EXTERN Array(const std::vector<std::string>& in);
- TypeCode getType() const { return type; }
+ QPID_COMMON_EXTERN TypeCode getType() const { return type; }
// std collection interface.
- const_iterator begin() const { return values.begin(); }
- const_iterator end() const { return values.end(); }
- iterator begin() { return values.begin(); }
- iterator end(){ return values.end(); }
-
- ValuePtr front() const { return values.front(); }
- ValuePtr back() const { return values.back(); }
- size_t size() const { return values.size(); }
-
- void insert(iterator i, ValuePtr value);
- void erase(iterator i) { values.erase(i); }
- void push_back(ValuePtr value) { values.insert(end(), value); }
- void pop_back() { values.pop_back(); }
+ QPID_COMMON_EXTERN const_iterator begin() const { return values.begin(); }
+ QPID_COMMON_EXTERN const_iterator end() const { return values.end(); }
+ QPID_COMMON_EXTERN iterator begin() { return values.begin(); }
+ QPID_COMMON_EXTERN iterator end(){ return values.end(); }
+
+ QPID_COMMON_EXTERN ValuePtr front() const { return values.front(); }
+ QPID_COMMON_EXTERN ValuePtr back() const { return values.back(); }
+ QPID_COMMON_EXTERN size_t size() const { return values.size(); }
+
+ QPID_COMMON_EXTERN void insert(iterator i, ValuePtr value);
+ QPID_COMMON_EXTERN void erase(iterator i) { values.erase(i); }
+ QPID_COMMON_EXTERN void push_back(ValuePtr value) { values.insert(end(), value); }
+ QPID_COMMON_EXTERN void pop_back() { values.pop_back(); }
// Non-std interface
- void add(ValuePtr value) { push_back(value); }
+ QPID_COMMON_EXTERN void add(ValuePtr value) { push_back(value); }
template <class T>
void collect(std::vector<T>& out) const
@@ -86,7 +87,7 @@ class Array
TypeCode type;
ValueVector values;
- friend std::ostream& operator<<(std::ostream& out, const Array& body);
+ friend QPID_COMMON_EXTERN std::ostream& operator<<(std::ostream& out, const Array& body);
};
}
diff --git a/qpid/cpp/src/qpid/framing/Buffer.h b/qpid/cpp/src/qpid/framing/Buffer.h
index 828e6e963a..57fb1e32a0 100644
--- a/qpid/cpp/src/qpid/framing/Buffer.h
+++ b/qpid/cpp/src/qpid/framing/Buffer.h
@@ -20,6 +20,7 @@
*/
#include "amqp_types.h"
#include "qpid/Exception.h"
+#include "qpid/CommonImportExport.h"
#include <boost/iterator/iterator_facade.hpp>
#ifndef _Buffer_
@@ -66,65 +67,65 @@ class Buffer
friend class Iterator;
- Buffer(char* data=0, uint32_t size=0);
+ QPID_COMMON_EXTERN Buffer(char* data=0, uint32_t size=0);
- void record();
- void restore(bool reRecord = false);
- void reset();
+ QPID_COMMON_EXTERN void record();
+ QPID_COMMON_EXTERN void restore(bool reRecord = false);
+ QPID_COMMON_EXTERN void reset();
- uint32_t available() { return size - position; }
- uint32_t getSize() { return size; }
- uint32_t getPosition() { return position; }
- Iterator getIterator() { return Iterator(*this); }
- char* getPointer() { return data; }
+ QPID_COMMON_EXTERN uint32_t available() { return size - position; }
+ QPID_COMMON_EXTERN uint32_t getSize() { return size; }
+ QPID_COMMON_EXTERN uint32_t getPosition() { return position; }
+ QPID_COMMON_EXTERN Iterator getIterator() { return Iterator(*this); }
+ QPID_COMMON_EXTERN char* getPointer() { return data; }
- void putOctet(uint8_t i);
- void putShort(uint16_t i);
- void putLong(uint32_t i);
- void putLongLong(uint64_t i);
- void putInt8(int8_t i);
- void putInt16(int16_t i);
- void putInt32(int32_t i);
- void putInt64(int64_t i);
- void putFloat(float f);
- void putDouble(double f);
- void putBin128(uint8_t* b);
-
- uint8_t getOctet();
- uint16_t getShort();
- uint32_t getLong();
- uint64_t getLongLong();
- int8_t getInt8();
- int16_t getInt16();
- int32_t getInt32();
- int64_t getInt64();
- float getFloat();
- double getDouble();
+ QPID_COMMON_EXTERN void putOctet(uint8_t i);
+ QPID_COMMON_EXTERN void putShort(uint16_t i);
+ QPID_COMMON_EXTERN void putLong(uint32_t i);
+ QPID_COMMON_EXTERN void putLongLong(uint64_t i);
+ QPID_COMMON_EXTERN void putInt8(int8_t i);
+ QPID_COMMON_EXTERN void putInt16(int16_t i);
+ QPID_COMMON_EXTERN void putInt32(int32_t i);
+ QPID_COMMON_EXTERN void putInt64(int64_t i);
+ QPID_COMMON_EXTERN void putFloat(float f);
+ QPID_COMMON_EXTERN void putDouble(double f);
+ QPID_COMMON_EXTERN void putBin128(uint8_t* b);
+
+ QPID_COMMON_EXTERN uint8_t getOctet();
+ QPID_COMMON_EXTERN uint16_t getShort();
+ QPID_COMMON_EXTERN uint32_t getLong();
+ QPID_COMMON_EXTERN uint64_t getLongLong();
+ QPID_COMMON_EXTERN int8_t getInt8();
+ QPID_COMMON_EXTERN int16_t getInt16();
+ QPID_COMMON_EXTERN int32_t getInt32();
+ QPID_COMMON_EXTERN int64_t getInt64();
+ QPID_COMMON_EXTERN float getFloat();
+ QPID_COMMON_EXTERN double getDouble();
template <int n>
- uint64_t getUInt();
+ QPID_COMMON_EXTERN uint64_t getUInt();
template <int n>
- void putUInt(uint64_t);
+ QPID_COMMON_EXTERN void putUInt(uint64_t);
- void putShortString(const string& s);
- void putMediumString(const string& s);
- void putLongString(const string& s);
- void getShortString(string& s);
- void getMediumString(string& s);
- void getLongString(string& s);
- void getBin128(uint8_t* b);
+ QPID_COMMON_EXTERN void putShortString(const string& s);
+ QPID_COMMON_EXTERN void putMediumString(const string& s);
+ QPID_COMMON_EXTERN void putLongString(const string& s);
+ QPID_COMMON_EXTERN void getShortString(string& s);
+ QPID_COMMON_EXTERN void getMediumString(string& s);
+ QPID_COMMON_EXTERN void getLongString(string& s);
+ QPID_COMMON_EXTERN void getBin128(uint8_t* b);
- void putRawData(const string& s);
- void getRawData(string& s, uint32_t size);
+ QPID_COMMON_EXTERN void putRawData(const string& s);
+ QPID_COMMON_EXTERN void getRawData(string& s, uint32_t size);
- void putRawData(const uint8_t* data, size_t size);
- void getRawData(uint8_t* data, size_t size);
+ QPID_COMMON_EXTERN void putRawData(const uint8_t* data, size_t size);
+ QPID_COMMON_EXTERN void getRawData(uint8_t* data, size_t size);
template <class T> void put(const T& data) { data.encode(*this); }
template <class T> void get(T& data) { data.decode(*this); }
- void dump(std::ostream&) const;
+ QPID_COMMON_EXTERN void dump(std::ostream&) const;
};
std::ostream& operator<<(std::ostream&, const Buffer&);
diff --git a/qpid/cpp/src/qpid/framing/FieldTable.h b/qpid/cpp/src/qpid/framing/FieldTable.h
index 9e1214a28c..a07568559f 100644
--- a/qpid/cpp/src/qpid/framing/FieldTable.h
+++ b/qpid/cpp/src/qpid/framing/FieldTable.h
@@ -23,6 +23,7 @@
#include <boost/shared_ptr.hpp>
#include <map>
#include "amqp_types.h"
+#include "qpid/CommonImportExport.h"
#ifndef _FieldTable_
#define _FieldTable_
@@ -51,45 +52,45 @@ class FieldTable
typedef std::map<std::string, ValuePtr> ValueMap;
typedef ValueMap::iterator iterator;
- FieldTable() {};
- FieldTable(const FieldTable& ft);
- ~FieldTable();
- FieldTable& operator=(const FieldTable& ft);
- uint32_t encodedSize() const;
- void encode(Buffer& buffer) const;
- void decode(Buffer& buffer);
-
- int count() const;
- void set(const std::string& name, const ValuePtr& value);
- ValuePtr get(const std::string& name) const;
- bool isSet(const std::string& name) const { return get(name).get() != 0; }
-
- void setString(const std::string& name, const std::string& value);
- void setInt(const std::string& name, const int value);
- void setInt64(const std::string& name, const int64_t value);
- void setTimestamp(const std::string& name, const uint64_t value);
- void setUInt64(const std::string& name, const uint64_t value);
- void setTable(const std::string& name, const FieldTable& value);
- void setArray(const std::string& name, const Array& value);
- void setFloat(const std::string& name, const float value);
- void setDouble(const std::string& name, const double value);
+ QPID_COMMON_EXTERN FieldTable() {};
+ QPID_COMMON_EXTERN FieldTable(const FieldTable& ft);
+ QPID_COMMON_EXTERN ~FieldTable();
+ QPID_COMMON_EXTERN FieldTable& operator=(const FieldTable& ft);
+ QPID_COMMON_EXTERN uint32_t encodedSize() const;
+ QPID_COMMON_EXTERN void encode(Buffer& buffer) const;
+ QPID_COMMON_EXTERN void decode(Buffer& buffer);
+
+ QPID_COMMON_EXTERN int count() const;
+ QPID_COMMON_EXTERN void set(const std::string& name, const ValuePtr& value);
+ QPID_COMMON_EXTERN ValuePtr get(const std::string& name) const;
+ QPID_COMMON_EXTERN bool isSet(const std::string& name) const { return get(name).get() != 0; }
+
+ QPID_COMMON_EXTERN void setString(const std::string& name, const std::string& value);
+ QPID_COMMON_EXTERN void setInt(const std::string& name, const int value);
+ QPID_COMMON_EXTERN void setInt64(const std::string& name, const int64_t value);
+ QPID_COMMON_EXTERN void setTimestamp(const std::string& name, const uint64_t value);
+ QPID_COMMON_EXTERN void setUInt64(const std::string& name, const uint64_t value);
+ QPID_COMMON_EXTERN void setTable(const std::string& name, const FieldTable& value);
+ QPID_COMMON_EXTERN void setArray(const std::string& name, const Array& value);
+ QPID_COMMON_EXTERN void setFloat(const std::string& name, const float value);
+ QPID_COMMON_EXTERN void setDouble(const std::string& name, const double value);
//void setDecimal(string& name, xxx& value);
- int getAsInt(const std::string& name) const;
- uint64_t getAsUInt64(const std::string& name) const;
- int64_t getAsInt64(const std::string& name) const;
- std::string getAsString(const std::string& name) const;
+ QPID_COMMON_EXTERN int getAsInt(const std::string& name) const;
+ QPID_COMMON_EXTERN uint64_t getAsUInt64(const std::string& name) const;
+ QPID_COMMON_EXTERN int64_t getAsInt64(const std::string& name) const;
+ QPID_COMMON_EXTERN std::string getAsString(const std::string& name) const;
- bool getTable(const std::string& name, FieldTable& value) const;
- bool getArray(const std::string& name, Array& value) const;
- bool getFloat(const std::string& name, float& value) const;
- bool getDouble(const std::string& name, double& value) const;
+ QPID_COMMON_EXTERN bool getTable(const std::string& name, FieldTable& value) const;
+ QPID_COMMON_EXTERN bool getArray(const std::string& name, Array& value) const;
+ QPID_COMMON_EXTERN bool getFloat(const std::string& name, float& value) const;
+ QPID_COMMON_EXTERN bool getDouble(const std::string& name, double& value) const;
//bool getTimestamp(const std::string& name, uint64_t& value) const;
//bool getDecimal(string& name, xxx& value);
- void erase(const std::string& name);
+ QPID_COMMON_EXTERN void erase(const std::string& name);
- bool operator==(const FieldTable& other) const;
+ QPID_COMMON_EXTERN bool operator==(const FieldTable& other) const;
// Map-like interface.
// TODO: may need to duplicate into versions that return mutable iterator
@@ -107,7 +108,7 @@ class FieldTable
private:
ValueMap values;
- friend std::ostream& operator<<(std::ostream& out, const FieldTable& body);
+ QPID_COMMON_EXTERN friend std::ostream& operator<<(std::ostream& out, const FieldTable& body);
};
//class FieldNotFoundException{};
diff --git a/qpid/cpp/src/qpid/framing/FieldValue.h b/qpid/cpp/src/qpid/framing/FieldValue.h
index 29760619e5..0f27700ac8 100644
--- a/qpid/cpp/src/qpid/framing/FieldValue.h
+++ b/qpid/cpp/src/qpid/framing/FieldValue.h
@@ -25,6 +25,7 @@
#include "amqp_types.h"
#include "Buffer.h"
#include "FieldTable.h"
+#include "qpid/CommonImportExport.h"
#include "assert.h"
@@ -87,8 +88,8 @@ class FieldValue {
bool empty() const { return data.get() == 0; }
void encode(Buffer& buffer);
void decode(Buffer& buffer);
- bool operator==(const FieldValue&) const;
- bool operator!=(const FieldValue& v) const { return !(*this == v); }
+ QPID_COMMON_EXTERN bool operator==(const FieldValue&) const;
+ QPID_COMMON_EXTERN bool operator!=(const FieldValue& v) const { return !(*this == v); }
void print(std::ostream& out) const;
@@ -244,28 +245,28 @@ class EncodedValue : public FieldValue::Data {
class Str8Value : public FieldValue {
public:
- Str8Value(const std::string& v);
+ QPID_COMMON_EXTERN Str8Value(const std::string& v);
};
class Str16Value : public FieldValue {
public:
- Str16Value(const std::string& v);
+ QPID_COMMON_EXTERN Str16Value(const std::string& v);
};
class Struct32Value : public FieldValue {
public:
- Struct32Value(const std::string& v);
+ QPID_COMMON_EXTERN Struct32Value(const std::string& v);
};
class FloatValue : public FieldValue
{
public:
- FloatValue(float f);
+ QPID_COMMON_EXTERN FloatValue(float f);
};
class DoubleValue : public FieldValue
{
public:
- DoubleValue(double f);
+ QPID_COMMON_EXTERN DoubleValue(double f);
};
/*
@@ -273,32 +274,32 @@ class DoubleValue : public FieldValue
*/
class IntegerValue : public FieldValue {
public:
- IntegerValue(int v);
+ QPID_COMMON_EXTERN IntegerValue(int v);
};
class TimeValue : public FieldValue {
public:
- TimeValue(uint64_t v);
+ QPID_COMMON_EXTERN TimeValue(uint64_t v);
};
class Integer64Value : public FieldValue {
public:
- Integer64Value(int64_t v);
+ QPID_COMMON_EXTERN Integer64Value(int64_t v);
};
class Unsigned64Value : public FieldValue {
public:
- Unsigned64Value(uint64_t v);
+ QPID_COMMON_EXTERN Unsigned64Value(uint64_t v);
};
class FieldTableValue : public FieldValue {
public:
- FieldTableValue(const FieldTable&);
+ QPID_COMMON_EXTERN FieldTableValue(const FieldTable&);
};
class ArrayValue : public FieldValue {
public:
- ArrayValue(const Array&);
+ QPID_COMMON_EXTERN ArrayValue(const Array&);
};
template <class T>
diff --git a/qpid/cpp/src/qpid/framing/FrameDecoder.cpp b/qpid/cpp/src/qpid/framing/FrameDecoder.cpp
index cbdac181e9..1e73ee1e51 100644
--- a/qpid/cpp/src/qpid/framing/FrameDecoder.cpp
+++ b/qpid/cpp/src/qpid/framing/FrameDecoder.cpp
@@ -21,8 +21,9 @@
#include "FrameDecoder.h"
#include "Buffer.h"
#include "qpid/log/Statement.h"
-#include <algorithm>
#include "qpid/framing/reply_exceptions.h"
+#include <algorithm>
+#include <string.h>
namespace qpid {
namespace framing {
@@ -67,4 +68,13 @@ bool FrameDecoder::decode(Buffer& buffer) {
return false;
}
+void FrameDecoder::setFragment(const char* data, size_t size) {
+ fragment.resize(size);
+ ::memcpy(&fragment[0], data, size);
+}
+
+std::pair<const char*, size_t> FrameDecoder::getFragment() const {
+ return std::pair<const char*, size_t>(&fragment[0], fragment.size());
+}
+
}} // namespace qpid::framing
diff --git a/qpid/cpp/src/qpid/framing/FrameDecoder.h b/qpid/cpp/src/qpid/framing/FrameDecoder.h
index 7f974dadc3..961cc666a9 100644
--- a/qpid/cpp/src/qpid/framing/FrameDecoder.h
+++ b/qpid/cpp/src/qpid/framing/FrameDecoder.h
@@ -35,9 +35,16 @@ class FrameDecoder
{
public:
bool decode(Buffer& buffer);
- AMQFrame frame;
+ const AMQFrame& getFrame() const { return frame; }
+ AMQFrame& getFrame() { return frame; }
+
+ void setFragment(const char*, size_t);
+ std::pair<const char*, size_t> getFragment() const;
+
private:
std::vector<char> fragment;
+ AMQFrame frame;
+
};
}} // namespace qpid::framing
diff --git a/qpid/cpp/src/qpid/framing/FrameSet.h b/qpid/cpp/src/qpid/framing/FrameSet.h
index b13ca16e97..e3e8727600 100644
--- a/qpid/cpp/src/qpid/framing/FrameSet.h
+++ b/qpid/cpp/src/qpid/framing/FrameSet.h
@@ -23,6 +23,7 @@
#include "qpid/framing/amqp_framing.h"
#include "qpid/framing/AMQFrame.h"
#include "qpid/framing/SequenceNumber.h"
+#include "qpid/CommonImportExport.h"
#ifndef _FrameSet_
#define _FrameSet_
@@ -44,20 +45,20 @@ class FrameSet
public:
typedef boost::shared_ptr<FrameSet> shared_ptr;
- FrameSet(const SequenceNumber& id);
- void append(const AMQFrame& part);
- bool isComplete() const;
+ QPID_COMMON_EXTERN FrameSet(const SequenceNumber& id);
+ QPID_COMMON_EXTERN void append(const AMQFrame& part);
+ QPID_COMMON_EXTERN bool isComplete() const;
- uint64_t getContentSize() const;
+ QPID_COMMON_EXTERN uint64_t getContentSize() const;
- void getContent(std::string&) const;
- std::string getContent() const;
+ QPID_COMMON_EXTERN void getContent(std::string&) const;
+ QPID_COMMON_EXTERN std::string getContent() const;
bool isContentBearing() const;
- const AMQMethodBody* getMethod() const;
- const AMQHeaderBody* getHeaders() const;
- AMQHeaderBody* getHeaders();
+ QPID_COMMON_EXTERN const AMQMethodBody* getMethod() const;
+ QPID_COMMON_EXTERN const AMQHeaderBody* getHeaders() const;
+ QPID_COMMON_EXTERN AMQHeaderBody* getHeaders();
template <class T> bool isA() const {
const AMQMethodBody* method = getMethod();
diff --git a/qpid/cpp/src/qpid/framing/ProtocolInitiation.h b/qpid/cpp/src/qpid/framing/ProtocolInitiation.h
index 6584fee55c..7a82b3575f 100644
--- a/qpid/cpp/src/qpid/framing/ProtocolInitiation.h
+++ b/qpid/cpp/src/qpid/framing/ProtocolInitiation.h
@@ -22,6 +22,7 @@
#include "Buffer.h"
#include "AMQDataBlock.h"
#include "ProtocolVersion.h"
+#include "qpid/CommonImportExport.h"
#ifndef _ProtocolInitiation_
#define _ProtocolInitiation_
@@ -35,12 +36,12 @@ private:
ProtocolVersion version;
public:
- ProtocolInitiation();
- ProtocolInitiation(uint8_t major, uint8_t minor);
- ProtocolInitiation(ProtocolVersion p);
- virtual ~ProtocolInitiation();
- virtual void encode(Buffer& buffer) const;
- virtual bool decode(Buffer& buffer);
+ QPID_COMMON_EXTERN ProtocolInitiation();
+ QPID_COMMON_EXTERN ProtocolInitiation(uint8_t major, uint8_t minor);
+ QPID_COMMON_EXTERN ProtocolInitiation(ProtocolVersion p);
+ QPID_COMMON_EXTERN virtual ~ProtocolInitiation();
+ QPID_COMMON_EXTERN virtual void encode(Buffer& buffer) const;
+ QPID_COMMON_EXTERN virtual bool decode(Buffer& buffer);
inline virtual uint32_t encodedSize() const { return 8; }
inline uint8_t getMajor() const { return version.getMajor(); }
inline uint8_t getMinor() const { return version.getMinor(); }
@@ -48,7 +49,7 @@ public:
bool operator==(ProtocolVersion v) const { return v == getVersion(); }
};
-std::ostream& operator<<(std::ostream& o, const framing::ProtocolInitiation& pi);
+QPID_COMMON_EXTERN std::ostream& operator<<(std::ostream& o, const framing::ProtocolInitiation& pi);
}
diff --git a/qpid/cpp/src/qpid/framing/ProtocolVersion.h b/qpid/cpp/src/qpid/framing/ProtocolVersion.h
index 9a7ebec491..681c9daf21 100644
--- a/qpid/cpp/src/qpid/framing/ProtocolVersion.h
+++ b/qpid/cpp/src/qpid/framing/ProtocolVersion.h
@@ -22,6 +22,7 @@
#define _ProtocolVersion_
#include "amqp_types.h"
+#include "qpid/CommonImportExport.h"
namespace qpid
{
@@ -38,16 +39,16 @@ public:
explicit ProtocolVersion(uint8_t _major=0, uint8_t _minor=0)
: major_(_major), minor_(_minor) {}
- uint8_t getMajor() const { return major_; }
- void setMajor(uint8_t major) { major_ = major; }
- uint8_t getMinor() const { return minor_; }
- void setMinor(uint8_t minor) { minor_ = minor; }
- const std::string toString() const;
+ QPID_COMMON_EXTERN uint8_t getMajor() const { return major_; }
+ QPID_COMMON_EXTERN void setMajor(uint8_t major) { major_ = major; }
+ QPID_COMMON_EXTERN uint8_t getMinor() const { return minor_; }
+ QPID_COMMON_EXTERN void setMinor(uint8_t minor) { minor_ = minor; }
+ QPID_COMMON_EXTERN const std::string toString() const;
- ProtocolVersion& operator=(ProtocolVersion p);
+ QPID_COMMON_EXTERN ProtocolVersion& operator=(ProtocolVersion p);
- bool operator==(ProtocolVersion p) const;
- bool operator!=(ProtocolVersion p) const { return ! (*this == p); }
+ QPID_COMMON_EXTERN bool operator==(ProtocolVersion p) const;
+ QPID_COMMON_EXTERN bool operator!=(ProtocolVersion p) const { return ! (*this == p); }
};
} // namespace framing
diff --git a/qpid/cpp/src/qpid/framing/Proxy.h b/qpid/cpp/src/qpid/framing/Proxy.h
index 5e2c886af2..a9a6ce981e 100644
--- a/qpid/cpp/src/qpid/framing/Proxy.h
+++ b/qpid/cpp/src/qpid/framing/Proxy.h
@@ -22,6 +22,8 @@
#include "FrameHandler.h"
#include "ProtocolVersion.h"
+#include "qpid/CommonImportExport.h"
+
namespace qpid {
namespace framing {
@@ -37,19 +39,19 @@ class Proxy
{
Proxy& proxy;
public:
- ScopedSync(Proxy& p);
- ~ScopedSync();
+ QPID_COMMON_EXTERN ScopedSync(Proxy& p);
+ QPID_COMMON_EXTERN ~ScopedSync();
};
- Proxy(FrameHandler& h);
- virtual ~Proxy();
+ QPID_COMMON_EXTERN Proxy(FrameHandler& h);
+ QPID_COMMON_EXTERN virtual ~Proxy();
- void send(const AMQBody&);
+ QPID_COMMON_EXTERN void send(const AMQBody&);
- ProtocolVersion getVersion() const;
+ QPID_COMMON_EXTERN ProtocolVersion getVersion() const;
- FrameHandler& getHandler();
- void setHandler(FrameHandler&);
+ QPID_COMMON_EXTERN FrameHandler& getHandler();
+ QPID_COMMON_EXTERN void setHandler(FrameHandler&);
private:
FrameHandler* out;
bool sync;
diff --git a/qpid/cpp/src/qpid/framing/SendContent.h b/qpid/cpp/src/qpid/framing/SendContent.h
index dcd5202b3e..745c948c9e 100644
--- a/qpid/cpp/src/qpid/framing/SendContent.h
+++ b/qpid/cpp/src/qpid/framing/SendContent.h
@@ -22,6 +22,7 @@
#include "qpid/framing/amqp_framing.h"
#include "qpid/framing/AMQFrame.h"
#include "qpid/framing/FrameHandler.h"
+#include "qpid/CommonImportExport.h"
#ifndef _SendContent_
#define _SendContent_
@@ -44,8 +45,8 @@ class SendContent
void sendFragment(const AMQContentBody& body, uint32_t offset, uint16_t size, bool first, bool last) const;
void setFlags(AMQFrame& f, bool first, bool last) const;
public:
- SendContent(FrameHandler& _handler, uint16_t _maxFrameSize, uint frameCount);
- void operator()(const AMQFrame& f);
+ QPID_COMMON_EXTERN SendContent(FrameHandler& _handler, uint16_t _maxFrameSize, uint frameCount);
+ QPID_COMMON_EXTERN void operator()(const AMQFrame& f);
};
}
diff --git a/qpid/cpp/src/qpid/framing/SequenceNumber.h b/qpid/cpp/src/qpid/framing/SequenceNumber.h
index 930e146863..3b18ce1360 100644
--- a/qpid/cpp/src/qpid/framing/SequenceNumber.h
+++ b/qpid/cpp/src/qpid/framing/SequenceNumber.h
@@ -23,6 +23,7 @@
#include "amqp_types.h"
#include <iosfwd>
+#include "qpid/CommonImportExport.h"
namespace qpid {
namespace framing {
@@ -37,22 +38,22 @@ class SequenceNumber
int32_t value;
public:
- SequenceNumber();
- SequenceNumber(uint32_t v);
+ QPID_COMMON_EXTERN SequenceNumber();
+ QPID_COMMON_EXTERN SequenceNumber(uint32_t v);
- SequenceNumber& operator++();//prefix ++
- const SequenceNumber operator++(int);//postfix ++
- SequenceNumber& operator--();//prefix ++
- bool operator==(const SequenceNumber& other) const;
- bool operator!=(const SequenceNumber& other) const;
- bool operator<(const SequenceNumber& other) const;
- bool operator>(const SequenceNumber& other) const;
- bool operator<=(const SequenceNumber& other) const;
- bool operator>=(const SequenceNumber& other) const;
+ QPID_COMMON_EXTERN SequenceNumber& operator++();//prefix ++
+ QPID_COMMON_EXTERN const SequenceNumber operator++(int);//postfix ++
+ QPID_COMMON_EXTERN SequenceNumber& operator--();//prefix ++
+ QPID_COMMON_EXTERN bool operator==(const SequenceNumber& other) const;
+ QPID_COMMON_EXTERN bool operator!=(const SequenceNumber& other) const;
+ QPID_COMMON_EXTERN bool operator<(const SequenceNumber& other) const;
+ QPID_COMMON_EXTERN bool operator>(const SequenceNumber& other) const;
+ QPID_COMMON_EXTERN bool operator<=(const SequenceNumber& other) const;
+ QPID_COMMON_EXTERN bool operator>=(const SequenceNumber& other) const;
uint32_t getValue() const { return (uint32_t) value; }
operator uint32_t() const { return (uint32_t) value; }
- friend int32_t operator-(const SequenceNumber& a, const SequenceNumber& b);
+ QPID_COMMON_EXTERN friend int32_t operator-(const SequenceNumber& a, const SequenceNumber& b);
void encode(Buffer& buffer) const;
void decode(Buffer& buffer);
@@ -67,7 +68,7 @@ struct Window
SequenceNumber lwm;
};
-std::ostream& operator<<(std::ostream& o, const SequenceNumber& n);
+QPID_COMMON_EXTERN std::ostream& operator<<(std::ostream& o, const SequenceNumber& n);
}} // namespace qpid::framing
diff --git a/qpid/cpp/src/qpid/framing/SequenceNumberSet.h b/qpid/cpp/src/qpid/framing/SequenceNumberSet.h
index 666307f9d9..8e023ba535 100644
--- a/qpid/cpp/src/qpid/framing/SequenceNumberSet.h
+++ b/qpid/cpp/src/qpid/framing/SequenceNumberSet.h
@@ -27,6 +27,7 @@
#include "SequenceNumber.h"
#include "qpid/framing/reply_exceptions.h"
#include "qpid/InlineVector.h"
+#include "qpid/CommonImportExport.h"
namespace qpid {
namespace framing {
@@ -41,8 +42,8 @@ public:
void encode(Buffer& buffer) const;
void decode(Buffer& buffer);
uint32_t encodedSize() const;
- SequenceNumberSet condense() const;
- void addRange(const SequenceNumber& start, const SequenceNumber& end);
+ QPID_COMMON_EXTERN SequenceNumberSet condense() const;
+ QPID_COMMON_EXTERN void addRange(const SequenceNumber& start, const SequenceNumber& end);
template <class T>
void processRanges(T& t) const
@@ -58,7 +59,7 @@ public:
}
}
- friend std::ostream& operator<<(std::ostream&, const SequenceNumberSet&);
+ friend QPID_COMMON_EXTERN std::ostream& operator<<(std::ostream&, const SequenceNumberSet&);
};
diff --git a/qpid/cpp/src/qpid/framing/SequenceSet.h b/qpid/cpp/src/qpid/framing/SequenceSet.h
index 57b9c2c8e1..a5ee6cd649 100644
--- a/qpid/cpp/src/qpid/framing/SequenceSet.h
+++ b/qpid/cpp/src/qpid/framing/SequenceSet.h
@@ -23,6 +23,7 @@
#include "SequenceNumber.h"
#include "qpid/RangeSet.h"
+#include "qpid/CommonImportExport.h"
namespace qpid {
namespace framing {
@@ -41,13 +42,13 @@ class SequenceSet : public RangeSet<SequenceNumber> {
void decode(Buffer& buffer);
uint32_t encodedSize() const;
- bool contains(const SequenceNumber& s) const;
- void add(const SequenceNumber& s);
- void add(const SequenceNumber& start, const SequenceNumber& finish); // Closed range
- void add(const SequenceSet& set);
- void remove(const SequenceNumber& s);
- void remove(const SequenceNumber& start, const SequenceNumber& finish); // Closed range
- void remove(const SequenceSet& set);
+ QPID_COMMON_EXTERN bool contains(const SequenceNumber& s) const;
+ QPID_COMMON_EXTERN void add(const SequenceNumber& s);
+ QPID_COMMON_EXTERN void add(const SequenceNumber& start, const SequenceNumber& finish); // Closed range
+ QPID_COMMON_EXTERN void add(const SequenceSet& set);
+ QPID_COMMON_EXTERN void remove(const SequenceNumber& s);
+ QPID_COMMON_EXTERN void remove(const SequenceNumber& start, const SequenceNumber& finish); // Closed range
+ QPID_COMMON_EXTERN void remove(const SequenceSet& set);
template <class T> void for_each(T& t) const {
for (RangeIterator i = rangesBegin(); i != rangesEnd(); i++)
@@ -59,7 +60,7 @@ class SequenceSet : public RangeSet<SequenceNumber> {
t(i->first(), i->last());
}
- friend std::ostream& operator<<(std::ostream&, const SequenceSet&);
+ friend QPID_COMMON_EXTERN std::ostream& operator<<(std::ostream&, const SequenceSet&);
};
}} // namespace qpid::framing
diff --git a/qpid/cpp/src/qpid/framing/StructHelper.h b/qpid/cpp/src/qpid/framing/StructHelper.h
index e3dce4f5ec..89f556ad3c 100644
--- a/qpid/cpp/src/qpid/framing/StructHelper.h
+++ b/qpid/cpp/src/qpid/framing/StructHelper.h
@@ -22,6 +22,7 @@
#define _StructHelper_
#include "qpid/Exception.h"
+#include "qpid/CommonImportExport.h"
#include "Buffer.h"
#include <stdlib.h> // For alloca
diff --git a/qpid/cpp/src/qpid/framing/TransferContent.h b/qpid/cpp/src/qpid/framing/TransferContent.h
index e3f6666fa4..236a0b6d93 100644
--- a/qpid/cpp/src/qpid/framing/TransferContent.h
+++ b/qpid/cpp/src/qpid/framing/TransferContent.h
@@ -26,6 +26,7 @@
#include "qpid/Exception.h"
#include "qpid/framing/MessageProperties.h"
#include "qpid/framing/DeliveryProperties.h"
+#include "qpid/CommonImportExport.h"
namespace qpid {
namespace framing {
@@ -36,27 +37,27 @@ class TransferContent : public MethodContent
AMQHeaderBody header;
std::string data;
public:
- TransferContent(const std::string& data = std::string(), const std::string& key=std::string());
+ QPID_COMMON_EXTERN TransferContent(const std::string& data = std::string(), const std::string& key=std::string());
///@internal
- AMQHeaderBody getHeader() const;
+ QPID_COMMON_EXTERN AMQHeaderBody getHeader() const;
- void setData(const std::string&);
- const std::string& getData() const;
- std::string& getData();
+ QPID_COMMON_EXTERN void setData(const std::string&);
+ QPID_COMMON_EXTERN const std::string& getData() const;
+ QPID_COMMON_EXTERN std::string& getData();
- void appendData(const std::string&);
+ QPID_COMMON_EXTERN void appendData(const std::string&);
- bool hasMessageProperties() const;
- MessageProperties& getMessageProperties();
- const MessageProperties& getMessageProperties() const;
+ QPID_COMMON_EXTERN bool hasMessageProperties() const;
+ QPID_COMMON_EXTERN MessageProperties& getMessageProperties();
+ QPID_COMMON_EXTERN const MessageProperties& getMessageProperties() const;
- bool hasDeliveryProperties() const;
- DeliveryProperties& getDeliveryProperties();
- const DeliveryProperties& getDeliveryProperties() const;
+ QPID_COMMON_EXTERN bool hasDeliveryProperties() const;
+ QPID_COMMON_EXTERN DeliveryProperties& getDeliveryProperties();
+ QPID_COMMON_EXTERN const DeliveryProperties& getDeliveryProperties() const;
///@internal
- void populate(const FrameSet& frameset);
+ QPID_COMMON_EXTERN void populate(const FrameSet& frameset);
};
}}
diff --git a/qpid/cpp/src/qpid/framing/Uuid.h b/qpid/cpp/src/qpid/framing/Uuid.h
index 2fcbb5a261..fe0c32dc0b 100644
--- a/qpid/cpp/src/qpid/framing/Uuid.h
+++ b/qpid/cpp/src/qpid/framing/Uuid.h
@@ -19,7 +19,9 @@
*
*/
+#include "qpid/CommonImportExport.h"
#include "qpid/sys/uuid.h"
+#include "qpid/sys/IntegerTypes.h"
#include <boost/array.hpp>
@@ -63,12 +65,12 @@ struct Uuid : public boost::array<uint8_t, 16> {
// Default op= and copy ctor are fine.
// boost::array gives us ==, < etc.
- void encode(framing::Buffer& buf) const;
- void decode(framing::Buffer& buf);
- uint32_t encodedSize() const { return size(); }
+ QPID_COMMON_EXTERN void encode(framing::Buffer& buf) const;
+ QPID_COMMON_EXTERN void decode(framing::Buffer& buf);
+ QPID_COMMON_EXTERN uint32_t encodedSize() const { return size(); }
/** String value in format 1b4e28ba-2fa1-11d2-883f-b9a761bde3fb. */
- std::string str() const;
+ QPID_COMMON_EXTERN std::string str() const;
template <class S> void serialize(S& s) {
s.raw(begin(), size());
@@ -76,10 +78,10 @@ struct Uuid : public boost::array<uint8_t, 16> {
};
/** Print in format 1b4e28ba-2fa1-11d2-883f-b9a761bde3fb. */
-std::ostream& operator<<(std::ostream&, Uuid);
+QPID_COMMON_EXTERN std::ostream& operator<<(std::ostream&, Uuid);
/** Read from format 1b4e28ba-2fa1-11d2-883f-b9a761bde3fb. */
-std::istream& operator>>(std::istream&, Uuid&);
+QPID_COMMON_EXTERN std::istream& operator>>(std::istream&, Uuid&);
}} // namespace qpid::framing
diff --git a/qpid/cpp/src/qpid/log/Logger.h b/qpid/cpp/src/qpid/log/Logger.h
index 539c1c851b..0cbd7685d6 100644
--- a/qpid/cpp/src/qpid/log/Logger.h
+++ b/qpid/cpp/src/qpid/log/Logger.h
@@ -18,6 +18,7 @@
#include <boost/ptr_container/ptr_vector.hpp>
#include <boost/noncopyable.hpp>
#include <set>
+#include "qpid/CommonImportExport.h"
namespace qpid {
namespace log {
@@ -48,48 +49,48 @@ class Logger : private boost::noncopyable {
*/
class Output {
public:
- Output();
- virtual ~Output();
+ QPID_COMMON_EXTERN Output();
+ QPID_COMMON_EXTERN virtual ~Output();
/** Receives the statemnt of origin and formatted message to log. */
virtual void log(const Statement&, const std::string&) =0;
};
- static Logger& instance();
+ QPID_COMMON_EXTERN static Logger& instance();
- Logger();
- ~Logger();
+ QPID_COMMON_EXTERN Logger();
+ QPID_COMMON_EXTERN ~Logger();
/** Select the messages to be logged. */
- void select(const Selector& s);
+ QPID_COMMON_EXTERN void select(const Selector& s);
/** Set the formatting flags, bitwise OR of FormatFlag values. */
- void format(int formatFlags);
+ QPID_COMMON_EXTERN void format(int formatFlags);
/** Set format flags from options object.
*@returns computed flags.
*/
- int format(const Options&);
+ QPID_COMMON_EXTERN int format(const Options&);
/** Configure logger from Options */
- void configure(const Options& o);
+ QPID_COMMON_EXTERN void configure(const Options& o);
/** Add a statement. */
- void add(Statement& s);
+ QPID_COMMON_EXTERN void add(Statement& s);
/** Log a message. */
- void log(const Statement&, const std::string&);
+ QPID_COMMON_EXTERN void log(const Statement&, const std::string&);
/** Add an output destination for messages */
- void output(std::auto_ptr<Output> out);
+ QPID_COMMON_EXTERN void output(std::auto_ptr<Output> out);
/** Set a prefix for all messages */
- void setPrefix(const std::string& prefix);
+ QPID_COMMON_EXTERN void setPrefix(const std::string& prefix);
/** Reset the logger. */
- void clear();
+ QPID_COMMON_EXTERN void clear();
/** Get the options used to configure the logger. */
- const Options& getOptions() const { return options; }
+ QPID_COMMON_EXTERN const Options& getOptions() const { return options; }
private:
diff --git a/qpid/cpp/src/qpid/log/Options.h b/qpid/cpp/src/qpid/log/Options.h
index 8a3c352d14..5e7bd433af 100644
--- a/qpid/cpp/src/qpid/log/Options.h
+++ b/qpid/cpp/src/qpid/log/Options.h
@@ -19,6 +19,7 @@
*
*/
#include "qpid/Options.h"
+#include "qpid/CommonImportExport.h"
#include "SinkOptions.h"
#include <iosfwd>
#include <memory>
@@ -29,11 +30,11 @@ namespace log {
/** Logging options for config parser. */
struct Options : public qpid::Options {
/** Pass argv[0] for use in syslog output */
- Options(const std::string& argv0_=std::string(),
+ QPID_COMMON_EXTERN Options(const std::string& argv0_=std::string(),
const std::string& name_="Logging options");
- Options(const Options &);
+ QPID_COMMON_EXTERN Options(const Options &);
- Options& operator=(const Options&);
+ QPID_COMMON_EXTERN Options& operator=(const Options&);
std::string argv0;
std::string name;
diff --git a/qpid/cpp/src/qpid/log/OstreamOutput.h b/qpid/cpp/src/qpid/log/OstreamOutput.h
index 8bbfc8c38b..8df38468ad 100644
--- a/qpid/cpp/src/qpid/log/OstreamOutput.h
+++ b/qpid/cpp/src/qpid/log/OstreamOutput.h
@@ -26,8 +26,8 @@ namespace log {
*/
class OstreamOutput : public qpid::log::Logger::Output {
public:
- OstreamOutput(std::ostream& o);
- OstreamOutput(const std::string& file);
+ QPID_COMMON_EXTERN OstreamOutput(std::ostream& o);
+ QPID_COMMON_EXTERN OstreamOutput(const std::string& file);
virtual void log(const Statement&, const std::string& m);
diff --git a/qpid/cpp/src/qpid/log/Selector.cpp b/qpid/cpp/src/qpid/log/Selector.cpp
index 4d1c5b6e0c..0a629edc3e 100644
--- a/qpid/cpp/src/qpid/log/Selector.cpp
+++ b/qpid/cpp/src/qpid/log/Selector.cpp
@@ -20,6 +20,7 @@
#include "Options.h"
#include <boost/bind.hpp>
#include <algorithm>
+#include <string.h>
namespace qpid {
namespace log {
diff --git a/qpid/cpp/src/qpid/log/Selector.h b/qpid/cpp/src/qpid/log/Selector.h
index 705abfeb5d..070ffd4abf 100644
--- a/qpid/cpp/src/qpid/log/Selector.h
+++ b/qpid/cpp/src/qpid/log/Selector.h
@@ -20,6 +20,7 @@
*/
#include "Statement.h"
+#include "qpid/CommonImportExport.h"
#include <vector>
namespace qpid {
@@ -37,7 +38,7 @@ class Selector {
Selector() {}
/** Set selector from Options */
- Selector(const Options&);
+ QPID_COMMON_EXTERN Selector(const Options&);
/** Equavlient to: Selector s; s.enable(l, s) */
Selector(Level l, const std::string& s=std::string()) {
@@ -54,10 +55,10 @@ class Selector {
}
/** Enable based on a 'level[+]:file' string */
- void enable(const std::string& enableStr);
+ QPID_COMMON_EXTERN void enable(const std::string& enableStr);
/** True if level is enabled for file. */
- bool isEnabled(Level level, const char* function);
+ QPID_COMMON_EXTERN bool isEnabled(Level level, const char* function);
private:
std::vector<std::string> substrings[LevelTraits::COUNT];
diff --git a/qpid/cpp/src/qpid/log/Statement.h b/qpid/cpp/src/qpid/log/Statement.h
index 3c67b04b20..445f635cdd 100644
--- a/qpid/cpp/src/qpid/log/Statement.h
+++ b/qpid/cpp/src/qpid/log/Statement.h
@@ -20,7 +20,7 @@
*/
#include "qpid/Msg.h"
-
+#include "qpid/CommonImportExport.h"
#include <boost/current_function.hpp>
namespace qpid {
@@ -63,10 +63,10 @@ struct Statement {
const char* function;
Level level;
- void log(const std::string& message);
+ QPID_COMMON_EXTERN void log(const std::string& message);
struct Initializer {
- Initializer(Statement& s);
+ QPID_COMMON_EXTERN Initializer(Statement& s);
Statement& statement;
};
};
diff --git a/qpid/cpp/src/qpid/log/posix/SinkOptions.cpp b/qpid/cpp/src/qpid/log/posix/SinkOptions.cpp
index 9d51358e2e..985cb32c5c 100644
--- a/qpid/cpp/src/qpid/log/posix/SinkOptions.cpp
+++ b/qpid/cpp/src/qpid/log/posix/SinkOptions.cpp
@@ -42,10 +42,14 @@ public:
struct NameValue { const char* name; int value; };
NameValue nameValue[] = {
{ "AUTH", LOG_AUTH },
+#ifdef HAVE_LOG_AUTHPRIV
{ "AUTHPRIV", LOG_AUTHPRIV },
+#endif
{ "CRON", LOG_CRON },
{ "DAEMON", LOG_DAEMON },
+#ifdef HAVE_LOG_FTP
{ "FTP", LOG_FTP },
+#endif
{ "KERN", LOG_KERN },
{ "LOCAL0", LOG_LOCAL0 },
{ "LOCAL1", LOG_LOCAL1 },
@@ -72,7 +76,7 @@ public:
int value(const string& name) const {
string key(name);
- transform(key.begin(), key.end(), key.begin(), ::toupper);
+ std::transform(key.begin(), key.end(), key.begin(), ::toupper);
ByName::const_iterator i = byName.find(key);
if (i == byName.end())
throw Exception("Not a valid syslog facility: " + name);
diff --git a/qpid/cpp/src/qpid/log/windows/SinkOptions.h b/qpid/cpp/src/qpid/log/windows/SinkOptions.h
index d14e9352be..605822fd46 100644
--- a/qpid/cpp/src/qpid/log/windows/SinkOptions.h
+++ b/qpid/cpp/src/qpid/log/windows/SinkOptions.h
@@ -27,20 +27,20 @@ namespace log {
namespace windows {
struct SinkOptions : public qpid::log::SinkOptions {
- SinkOptions(const std::string& argv0);
+ QPID_COMMON_EXTERN SinkOptions(const std::string& argv0);
virtual ~SinkOptions() {}
- virtual qpid::log::SinkOptions& operator=(const qpid::log::SinkOptions& rhs);
+ QPID_COMMON_EXTERN virtual qpid::log::SinkOptions& operator=(const qpid::log::SinkOptions& rhs);
// This allows the caller to indicate that there's no normal outputs
// available. For example, when running as a service. In these cases, the
// platform's "syslog"-type output should replace the default stderr
// unless some other sink has been selected.
- virtual void detached(void);
+ QPID_COMMON_EXTERN virtual void detached(void);
// The Logger acting on these options calls setup() to request any
// Sinks be set up and fed back to the logger.
- virtual void setup(qpid::log::Logger *logger);
+ QPID_COMMON_EXTERN virtual void setup(qpid::log::Logger *logger);
bool logToStderr;
bool logToStdout;
diff --git a/qpid/cpp/src/qpid/management/Manageable.h b/qpid/cpp/src/qpid/management/Manageable.h
index b4d80d8fad..ededa6141e 100644
--- a/qpid/cpp/src/qpid/management/Manageable.h
+++ b/qpid/cpp/src/qpid/management/Manageable.h
@@ -23,11 +23,12 @@
#include "ManagementObject.h"
#include "Args.h"
#include <string>
+#include "qpid/CommonImportExport.h"
namespace qpid {
namespace management {
-class Manageable
+class QPID_COMMON_EXTERN Manageable
{
public:
diff --git a/qpid/cpp/src/qpid/management/ManagementBroker.cpp b/qpid/cpp/src/qpid/management/ManagementBroker.cpp
index 0f96e97fb0..19300ef1af 100644
--- a/qpid/cpp/src/qpid/management/ManagementBroker.cpp
+++ b/qpid/cpp/src/qpid/management/ManagementBroker.cpp
@@ -80,7 +80,7 @@ ManagementBroker::RemoteAgent::~RemoteAgent ()
}
ManagementBroker::ManagementBroker () :
- threadPoolSize(1), interval(10), broker(0)
+ threadPoolSize(1), interval(10), broker(0), startTime(uint64_t(Duration(now())))
{
nextObjectId = 1;
brokerBank = 1;
@@ -346,6 +346,9 @@ void ManagementBroker::periodicProcessing (void)
string routingKey;
list<pair<ObjectId, ManagementObject*> > deleteList;
+ uint64_t uptime = uint64_t(Duration(now())) - startTime;
+ static_cast<_qmf::Broker*>(broker->GetManagementObject())->set_uptime(uptime);
+
moveNewObjectsLH();
if (clientWasAdded) {
@@ -515,6 +518,7 @@ void ManagementBroker::handleMethodRequestLH (Buffer& inBuffer, string replyToKe
else
try {
outBuffer.record();
+ Mutex::ScopedUnlock u(userLock);
iter->second->doMethod(methodName, inBuffer, outBuffer);
} catch(exception& e) {
outBuffer.restore();
@@ -844,6 +848,9 @@ void ManagementBroker::handleGetQueryLH (Buffer& inBuffer, string replyToKey, ui
Buffer outBuffer (outputBuffer, MA_BUFFER_SIZE);
uint32_t outLen;
+ if (object->getConfigChanged() || object->getInstChanged())
+ object->setUpdateTime();
+
encodeHeader(outBuffer, 'g', sequence);
object->writeProperties(outBuffer);
object->writeStatistics(outBuffer, true);
@@ -865,6 +872,9 @@ void ManagementBroker::handleGetQueryLH (Buffer& inBuffer, string replyToKey, ui
Buffer outBuffer (outputBuffer, MA_BUFFER_SIZE);
uint32_t outLen;
+ if (object->getConfigChanged() || object->getInstChanged())
+ object->setUpdateTime();
+
encodeHeader(outBuffer, 'g', sequence);
object->writeProperties(outBuffer);
object->writeStatistics(outBuffer, true);
diff --git a/qpid/cpp/src/qpid/management/ManagementBroker.h b/qpid/cpp/src/qpid/management/ManagementBroker.h
index f65d6a345e..a57f73be15 100644
--- a/qpid/cpp/src/qpid/management/ManagementBroker.h
+++ b/qpid/cpp/src/qpid/management/ManagementBroker.h
@@ -182,6 +182,7 @@ private:
uint32_t nextRemoteBank;
uint32_t nextRequestSequence;
bool clientWasAdded;
+ const uint64_t startTime;
std::auto_ptr<IdAllocator> allocator;
diff --git a/qpid/cpp/src/qpid/management/ManagementObject.h b/qpid/cpp/src/qpid/management/ManagementObject.h
index fbdad347b8..498169318d 100644
--- a/qpid/cpp/src/qpid/management/ManagementObject.h
+++ b/qpid/cpp/src/qpid/management/ManagementObject.h
@@ -25,6 +25,7 @@
#include "qpid/sys/Time.h"
#include "qpid/sys/Mutex.h"
#include <qpid/framing/Buffer.h>
+#include "qpid/CommonImportExport.h"
#include <map>
namespace qpid {
@@ -41,7 +42,7 @@ private:
uint64_t first;
public:
AgentAttachment() : first(0) {}
- void setBanks(uint32_t broker, uint32_t bank);
+ QPID_COMMON_EXTERN void setBanks(uint32_t broker, uint32_t bank);
uint64_t getFirst() const { return first; }
};
@@ -53,17 +54,17 @@ protected:
uint64_t second;
void fromString(const std::string&);
public:
- ObjectId() : agent(0), first(0), second(0) {}
- ObjectId(framing::Buffer& buf) : agent(0) { decode(buf); }
- ObjectId(uint8_t flags, uint16_t seq, uint32_t broker, uint32_t bank, uint64_t object);
- ObjectId(AgentAttachment* _agent, uint8_t flags, uint16_t seq, uint64_t object);
- ObjectId(std::istream&);
- ObjectId(const std::string&);
- bool operator==(const ObjectId &other) const;
- bool operator<(const ObjectId &other) const;
- void encode(framing::Buffer& buffer);
- void decode(framing::Buffer& buffer);
- friend std::ostream& operator<<(std::ostream&, const ObjectId&);
+ QPID_COMMON_EXTERN ObjectId() : agent(0), first(0), second(0) {}
+ QPID_COMMON_EXTERN ObjectId(framing::Buffer& buf) : agent(0) { decode(buf); }
+ QPID_COMMON_EXTERN ObjectId(uint8_t flags, uint16_t seq, uint32_t broker, uint32_t bank, uint64_t object);
+ QPID_COMMON_EXTERN ObjectId(AgentAttachment* _agent, uint8_t flags, uint16_t seq, uint64_t object);
+ QPID_COMMON_EXTERN ObjectId(std::istream&);
+ QPID_COMMON_EXTERN ObjectId(const std::string&);
+ QPID_COMMON_EXTERN bool operator==(const ObjectId &other) const;
+ QPID_COMMON_EXTERN bool operator<(const ObjectId &other) const;
+ QPID_COMMON_EXTERN void encode(framing::Buffer& buffer);
+ QPID_COMMON_EXTERN void decode(framing::Buffer& buffer);
+ friend QPID_COMMON_EXTERN std::ostream& operator<<(std::ostream&, const ObjectId&);
};
class ManagementItem {
@@ -128,8 +129,8 @@ class ManagementObject : public ManagementItem
static int nextThreadIndex;
bool forcePublish;
- int getThreadIndex();
- void writeTimestamps(qpid::framing::Buffer& buf);
+ QPID_COMMON_EXTERN int getThreadIndex();
+ QPID_COMMON_EXTERN void writeTimestamps(qpid::framing::Buffer& buf);
public:
typedef void (*writeSchemaCall_t) (qpid::framing::Buffer&);
@@ -148,7 +149,7 @@ class ManagementObject : public ManagementItem
virtual void doMethod(std::string& methodName,
qpid::framing::Buffer& inBuf,
qpid::framing::Buffer& outBuf) = 0;
- virtual void setReference(ObjectId objectId);
+ QPID_COMMON_EXTERN virtual void setReference(ObjectId objectId);
virtual std::string& getClassName() const = 0;
virtual std::string& getPackageName() const = 0;
diff --git a/qpid/cpp/src/qpid/replication/ReplicatingEventListener.cpp b/qpid/cpp/src/qpid/replication/ReplicatingEventListener.cpp
index 2d8af3b052..60d5fffc0b 100644
--- a/qpid/cpp/src/qpid/replication/ReplicatingEventListener.cpp
+++ b/qpid/cpp/src/qpid/replication/ReplicatingEventListener.cpp
@@ -21,6 +21,7 @@
#include "ReplicatingEventListener.h"
#include "constants.h"
#include "qpid/broker/Broker.h"
+#include "qpid/broker/DeliverableMessage.h"
#include "qpid/broker/QueueEvents.h"
#include "qpid/framing/AMQFrame.h"
#include "qpid/framing/FrameHandler.h"
@@ -57,11 +58,12 @@ void ReplicatingEventListener::deliverDequeueMessage(const QueuedMessage& dequeu
{
FieldTable headers;
headers.setString(REPLICATION_TARGET_QUEUE, dequeued.queue->getName());
- headers.setInt(REPLICATION_EVENT_SEQNO, ++sequence);
headers.setInt(REPLICATION_EVENT_TYPE, DEQUEUE);
headers.setInt(DEQUEUED_MESSAGE_POSITION, dequeued.position);
boost::intrusive_ptr<Message> msg(createMessage(headers));
- queue->deliver(msg);
+ DeliveryProperties* props = msg->getFrames().getHeaders()->get<DeliveryProperties>(true);
+ props->setRoutingKey(dequeued.queue->getName());
+ route(msg);
}
void ReplicatingEventListener::deliverEnqueueMessage(const QueuedMessage& enqueued)
@@ -69,11 +71,27 @@ void ReplicatingEventListener::deliverEnqueueMessage(const QueuedMessage& enqueu
boost::intrusive_ptr<Message> msg(cloneMessage(*(enqueued.queue), enqueued.payload));
FieldTable& headers = msg->getProperties<MessageProperties>()->getApplicationHeaders();
headers.setString(REPLICATION_TARGET_QUEUE, enqueued.queue->getName());
- headers.setInt(REPLICATION_EVENT_SEQNO, ++sequence);
headers.setInt(REPLICATION_EVENT_TYPE, ENQUEUE);
- queue->deliver(msg);
+ route(msg);
}
+void ReplicatingEventListener::route(boost::intrusive_ptr<qpid::broker::Message> msg)
+{
+ try {
+ if (exchange) {
+ DeliverableMessage deliverable(msg);
+ exchange->route(deliverable, msg->getRoutingKey(), msg->getApplicationHeaders());
+ } else if (queue) {
+ queue->deliver(msg);
+ } else {
+ QPID_LOG(error, "Cannot route replication event, neither replication queue nor exchange configured");
+ }
+ } catch (const std::exception& e) {
+ QPID_LOG(error, "Error enqueing replication event: " << e.what());
+ }
+}
+
+
boost::intrusive_ptr<Message> ReplicatingEventListener::createMessage(const FieldTable& headers)
{
boost::intrusive_ptr<Message> msg(new Message());
@@ -129,30 +147,49 @@ Options* ReplicatingEventListener::getOptions()
void ReplicatingEventListener::initialize(Plugin::Target& target)
{
- Broker* broker = dynamic_cast<broker::Broker*>(&target);
- if (broker && !options.queue.empty()) {
- if (options.createQueue) {
- queue = broker->getQueues().declare(options.queue).first;
- } else {
- queue = broker->getQueues().find(options.queue);
- }
- if (queue) {
- QueueEvents::EventListener callback = boost::bind(&ReplicatingEventListener::handle, this, _1);
- broker->getQueueEvents().registerListener(options.name, callback);
- QPID_LOG(info, "Registered replicating queue event listener");
- } else {
- QPID_LOG(error, "Replication queue named '" << options.queue << "' does not exist; replication plugin disabled.");
- }
- }
+ Broker* broker = dynamic_cast<broker::Broker*>(&target);
+ if (broker) {
+ broker->addFinalizer(boost::bind(&ReplicatingEventListener::shutdown, this));
+ if (!options.exchange.empty()) {
+ if (!options.queue.empty()) {
+ QPID_LOG(warning, "Replication queue option ignored as replication exchange has been specified");
+ }
+ try {
+ exchange = broker->getExchanges().declare(options.exchange, options.exchangeType).first;
+ } catch (const UnknownExchangeTypeException&) {
+ QPID_LOG(error, "Replication disabled due to invalid type: " << options.exchangeType);
+ }
+ } else if (!options.queue.empty()) {
+ if (options.createQueue) {
+ queue = broker->getQueues().declare(options.queue).first;
+ } else {
+ queue = broker->getQueues().find(options.queue);
+ }
+ if (queue) {
+ queue->insertSequenceNumbers(REPLICATION_EVENT_SEQNO);
+ } else {
+ QPID_LOG(error, "Replication queue named '" << options.queue << "' does not exist; replication plugin disabled.");
+ }
+ }
+ if (queue || exchange) {
+ QueueEvents::EventListener callback = boost::bind(&ReplicatingEventListener::handle, this, _1);
+ broker->getQueueEvents().registerListener(options.name, callback);
+ QPID_LOG(info, "Registered replicating queue event listener");
+ }
+ }
}
void ReplicatingEventListener::earlyInitialize(Target&) {}
+void ReplicatingEventListener::shutdown() { queue.reset(); exchange.reset(); }
ReplicatingEventListener::PluginOptions::PluginOptions() : Options("Queue Replication Options"),
- name("replicator"),
+ exchangeType("direct"),
+ name("replicator"),
createQueue(false)
{
addOptions()
+ ("replication-exchange-name", optValue(exchange, "EXCHANGE"), "Exchange to which events for other queues are routed")
+ ("replication-exchange-type", optValue(exchangeType, "direct|topic etc"), "Type of exchange to use")
("replication-queue", optValue(queue, "QUEUE"), "Queue on which events for other queues are recorded")
("replication-listener-name", optValue(name, "NAME"), "name by which to register the replicating event listener")
("create-replication-queue", optValue(createQueue), "if set, the replication will be created if it does not exist");
diff --git a/qpid/cpp/src/qpid/replication/ReplicatingEventListener.h b/qpid/cpp/src/qpid/replication/ReplicatingEventListener.h
index 7616c7ac8a..74418d00e6 100644
--- a/qpid/cpp/src/qpid/replication/ReplicatingEventListener.h
+++ b/qpid/cpp/src/qpid/replication/ReplicatingEventListener.h
@@ -24,6 +24,7 @@
#include "qpid/Plugin.h"
#include "qpid/Options.h"
+#include "qpid/broker/Exchange.h"
#include "qpid/broker/Message.h"
#include "qpid/broker/Queue.h"
#include "qpid/broker/QueueEvents.h"
@@ -50,6 +51,8 @@ class ReplicatingEventListener : public Plugin
struct PluginOptions : public Options
{
std::string queue;
+ std::string exchange;
+ std::string exchangeType;
std::string name;
bool createQueue;
@@ -58,10 +61,12 @@ class ReplicatingEventListener : public Plugin
PluginOptions options;
qpid::broker::Queue::shared_ptr queue;
- qpid::framing::SequenceNumber sequence;
+ qpid::broker::Exchange::shared_ptr exchange;
void deliverDequeueMessage(const qpid::broker::QueuedMessage& enqueued);
void deliverEnqueueMessage(const qpid::broker::QueuedMessage& enqueued);
+ void route(boost::intrusive_ptr<qpid::broker::Message>);
+ void shutdown();
boost::intrusive_ptr<qpid::broker::Message> createMessage(const qpid::framing::FieldTable& headers);
boost::intrusive_ptr<qpid::broker::Message> cloneMessage(qpid::broker::Queue& queue,
diff --git a/qpid/cpp/src/qpid/replication/ReplicationExchange.cpp b/qpid/cpp/src/qpid/replication/ReplicationExchange.cpp
index 639cfb5d2e..29cdf21bc6 100644
--- a/qpid/cpp/src/qpid/replication/ReplicationExchange.cpp
+++ b/qpid/cpp/src/qpid/replication/ReplicationExchange.cpp
@@ -34,11 +34,13 @@ using namespace qpid::broker;
using namespace qpid::framing;
using namespace qpid::replication::constants;
+const std::string SEQUENCE_VALUE("qpid.replication-event.sequence");
ReplicationExchange::ReplicationExchange(const std::string& name, bool durable,
const FieldTable& args,
QueueRegistry& qr,
Manageable* parent)
- : Exchange(name, durable, args, parent), queues(qr), init(false) {}
+ : Exchange(name, durable, args, parent), queues(qr), sequence(args.getAsInt64(SEQUENCE_VALUE)), init(false)
+ {}
std::string ReplicationExchange::getType() const { return typeName; }
@@ -68,31 +70,39 @@ void ReplicationExchange::handleEnqueueEvent(const FieldTable* args, Deliverable
{
std::string queueName = args->getAsString(REPLICATION_TARGET_QUEUE);
Queue::shared_ptr queue = queues.find(queueName);
- FieldTable& headers = msg.getMessage().getProperties<MessageProperties>()->getApplicationHeaders();
- headers.erase(REPLICATION_TARGET_QUEUE);
- headers.erase(REPLICATION_EVENT_SEQNO);
- headers.erase(REPLICATION_EVENT_TYPE);
- msg.deliverTo(queue);
- QPID_LOG(debug, "Enqueued replicated message onto " << queue);
+ if (queue) {
+ FieldTable& headers = msg.getMessage().getProperties<MessageProperties>()->getApplicationHeaders();
+ headers.erase(REPLICATION_TARGET_QUEUE);
+ headers.erase(REPLICATION_EVENT_SEQNO);
+ headers.erase(REPLICATION_EVENT_TYPE);
+ msg.deliverTo(queue);
+ QPID_LOG(debug, "Enqueued replicated message onto " << queueName);
+ } else {
+ QPID_LOG(error, "Cannot enqueue replicated message. Queue " << queueName << " does not exist");
+ }
}
void ReplicationExchange::handleDequeueEvent(const FieldTable* args)
{
std::string queueName = args->getAsString(REPLICATION_TARGET_QUEUE);
Queue::shared_ptr queue = queues.find(queueName);
- SequenceNumber position(args->getAsInt(DEQUEUED_MESSAGE_POSITION));
-
- QueuedMessage dequeued;
- if (queue->acquireMessageAt(position, dequeued)) {
- queue->dequeue(0, dequeued);
- QPID_LOG(debug, "Processed replicated 'dequeue' event from " << queueName << " at position " << position);
+ if (queue) {
+ SequenceNumber position(args->getAsInt(DEQUEUED_MESSAGE_POSITION));
+ QueuedMessage dequeued;
+ if (queue->acquireMessageAt(position, dequeued)) {
+ queue->dequeue(0, dequeued);
+ QPID_LOG(debug, "Processed replicated 'dequeue' event from " << queueName << " at position " << position);
+ } else {
+ QPID_LOG(warning, "Could not acquire message " << position << " from " << queueName);
+ }
} else {
- QPID_LOG(warning, "Could not acquire message " << position << " from " << queueName);
+ QPID_LOG(error, "Cannot process replicated 'dequeue' event. Queue " << queueName << " does not exist");
}
}
bool ReplicationExchange::isDuplicate(const FieldTable* args)
{
+ if (!args->get(REPLICATION_EVENT_SEQNO)) return false;
SequenceNumber seqno(args->getAsInt(REPLICATION_EVENT_SEQNO));
if (!init) {
init = true;
@@ -128,6 +138,13 @@ bool ReplicationExchange::isBound(Queue::shared_ptr /*queue*/, const string* con
const std::string ReplicationExchange::typeName("replication");
+void ReplicationExchange::encode(Buffer& buffer) const
+{
+ args.setInt64(std::string(SEQUENCE_VALUE), sequence);
+ Exchange::encode(buffer);
+}
+
+
struct ReplicationExchangePlugin : Plugin
{
Broker* broker;
diff --git a/qpid/cpp/src/qpid/replication/ReplicationExchange.h b/qpid/cpp/src/qpid/replication/ReplicationExchange.h
index 897e4a954e..4cc45ed5f5 100644
--- a/qpid/cpp/src/qpid/replication/ReplicationExchange.h
+++ b/qpid/cpp/src/qpid/replication/ReplicationExchange.h
@@ -22,6 +22,7 @@
*
*/
#include "qpid/broker/Exchange.h"
+#include "qpid/framing/Buffer.h"
#include "qpid/framing/SequenceNumber.h"
namespace qpid {
@@ -58,6 +59,7 @@ class ReplicationExchange : public qpid::broker::Exchange
bool isDuplicate(const qpid::framing::FieldTable* args);
void handleEnqueueEvent(const qpid::framing::FieldTable* args, qpid::broker::Deliverable& msg);
void handleDequeueEvent(const qpid::framing::FieldTable* args);
+ void encode(framing::Buffer& buffer) const;
};
}} // namespace qpid::replication
diff --git a/qpid/cpp/src/qpid/sys/AggregateOutput.h b/qpid/cpp/src/qpid/sys/AggregateOutput.h
index 1cda4456b4..fcd0d4c2f7 100644
--- a/qpid/cpp/src/qpid/sys/AggregateOutput.h
+++ b/qpid/cpp/src/qpid/sys/AggregateOutput.h
@@ -24,6 +24,7 @@
#include "Mutex.h"
#include "OutputControl.h"
#include "OutputTask.h"
+#include "qpid/CommonImportExport.h"
#include <algorithm>
#include <vector>
@@ -42,15 +43,15 @@ namespace sys {
public:
AggregateOutput(OutputControl& c) : next(0), control(c) {};
//this may be called on any thread
- void activateOutput();
- void giveReadCredit(int32_t);
+ QPID_COMMON_EXTERN void activateOutput();
+ QPID_COMMON_EXTERN void giveReadCredit(int32_t);
//all the following will be called on the same thread
- bool doOutput();
- bool hasOutput();
- void addOutputTask(OutputTask* t);
- void removeOutputTask(OutputTask* t);
- void removeAll();
+ QPID_COMMON_EXTERN bool doOutput();
+ QPID_COMMON_EXTERN bool hasOutput();
+ QPID_COMMON_EXTERN void addOutputTask(OutputTask* t);
+ QPID_COMMON_EXTERN void removeOutputTask(OutputTask* t);
+ QPID_COMMON_EXTERN void removeAll();
/** Apply f to each OutputTask* in the tasks list */
template <class F> void eachOutput(F f) {
diff --git a/qpid/cpp/src/qpid/sys/AsynchIO.h b/qpid/cpp/src/qpid/sys/AsynchIO.h
index ffd4436c2a..fb02183359 100644
--- a/qpid/cpp/src/qpid/sys/AsynchIO.h
+++ b/qpid/cpp/src/qpid/sys/AsynchIO.h
@@ -22,7 +22,7 @@
*/
#include "qpid/sys/IntegerTypes.h"
-
+#include "qpid/CommonImportExport.h"
#include <boost/function.hpp>
#include <boost/shared_ptr.hpp>
@@ -45,9 +45,9 @@ private:
AsynchAcceptorPrivate* impl;
public:
- AsynchAcceptor(const Socket& s, Callback callback);
- ~AsynchAcceptor();
- void start(boost::shared_ptr<Poller> poller);
+ QPID_COMMON_EXTERN AsynchAcceptor(const Socket& s, Callback callback);
+ QPID_COMMON_EXTERN ~AsynchAcceptor();
+ QPID_COMMON_EXTERN void start(boost::shared_ptr<Poller> poller);
};
/*
@@ -65,7 +65,7 @@ public:
// create a correctly typed object. The platform code also manages
// deletes. To correctly manage heaps when needed, the allocate and
// delete should both be done from the same class/library.
- static AsynchConnector* create(const Socket& s,
+ QPID_COMMON_EXTERN static AsynchConnector* create(const Socket& s,
boost::shared_ptr<Poller> poller,
std::string hostname,
uint16_t port,
@@ -121,7 +121,7 @@ public:
// create a correctly typed object. The platform code also manages
// deletes. To correctly manage heaps when needed, the allocate and
// delete should both be done from the same class/library.
- static AsynchIO* create(const Socket& s,
+ QPID_COMMON_EXTERN static AsynchIO* create(const Socket& s,
ReadCallback rCb,
EofCallback eofCb,
DisconnectCallback disCb,
diff --git a/qpid/cpp/src/qpid/sys/AsynchIOHandler.cpp b/qpid/cpp/src/qpid/sys/AsynchIOHandler.cpp
index 3bc05e4bf9..6b7e7b5145 100644
--- a/qpid/cpp/src/qpid/sys/AsynchIOHandler.cpp
+++ b/qpid/cpp/src/qpid/sys/AsynchIOHandler.cpp
@@ -84,10 +84,11 @@ void AsynchIOHandler::giveReadCredit(int32_t credit) {
// Check whether we started in the don't about credit state
if (readCredit.boolCompareAndSwap(InfiniteCredit, credit))
return;
- else if (readCredit.fetchAndAdd(credit) != 0)
- return;
- // Lock and retest credit to make sure we don't race with decreasing credit
+ // TODO In theory should be able to use an atomic operation before taking the lock
+ // but in practice there seems to be an unexplained race in that case
ScopedLock<Mutex> l(creditLock);
+ if (readCredit.fetchAndAdd(credit) != 0)
+ return;
assert(readCredit.get() >= 0);
if (readCredit.get() != 0)
aio->startReading();
@@ -141,9 +142,10 @@ bool AsynchIOHandler::readbuff(AsynchIO& , AsynchIO::BufferBase* buff) {
}
// Check here for read credit
if (readCredit.get() != InfiniteCredit) {
+ // TODO In theory should be able to use an atomic operation before taking the lock
+ // but in practice there seems to be an unexplained race in that case
+ ScopedLock<Mutex> l(creditLock);
if (--readCredit == 0) {
- // Lock and retest credit to make sure we don't race with increasing credit
- ScopedLock<Mutex> l(creditLock);
assert(readCredit.get() >= 0);
if (readCredit.get() == 0) {
aio->stopReading();
diff --git a/qpid/cpp/src/qpid/sys/AsynchIOHandler.h b/qpid/cpp/src/qpid/sys/AsynchIOHandler.h
index fa020fbce4..9f1d043b62 100644
--- a/qpid/cpp/src/qpid/sys/AsynchIOHandler.h
+++ b/qpid/cpp/src/qpid/sys/AsynchIOHandler.h
@@ -25,6 +25,7 @@
#include "ConnectionCodec.h"
#include "AtomicValue.h"
#include "Mutex.h"
+#include "qpid/CommonImportExport.h"
namespace qpid {
@@ -52,26 +53,26 @@ class AsynchIOHandler : public OutputControl {
void write(const framing::ProtocolInitiation&);
public:
- AsynchIOHandler(std::string id, ConnectionCodec::Factory* f);
- ~AsynchIOHandler();
- void init(AsynchIO* a, int numBuffs);
+ QPID_COMMON_EXTERN AsynchIOHandler(std::string id, ConnectionCodec::Factory* f);
+ QPID_COMMON_EXTERN ~AsynchIOHandler();
+ QPID_COMMON_EXTERN void init(AsynchIO* a, int numBuffs);
- void setClient() { isClient = true; }
+ QPID_COMMON_EXTERN void setClient() { isClient = true; }
// Output side
- void close();
- void activateOutput();
- void giveReadCredit(int32_t credit);
+ QPID_COMMON_EXTERN void close();
+ QPID_COMMON_EXTERN void activateOutput();
+ QPID_COMMON_EXTERN void giveReadCredit(int32_t credit);
// Input side
- bool readbuff(AsynchIO& aio, AsynchIOBufferBase* buff);
- void eof(AsynchIO& aio);
- void disconnect(AsynchIO& aio);
+ QPID_COMMON_EXTERN bool readbuff(AsynchIO& aio, AsynchIOBufferBase* buff);
+ QPID_COMMON_EXTERN void eof(AsynchIO& aio);
+ QPID_COMMON_EXTERN void disconnect(AsynchIO& aio);
// Notifications
- void nobuffs(AsynchIO& aio);
- void idle(AsynchIO& aio);
- void closedSocket(AsynchIO& aio, const Socket& s);
+ QPID_COMMON_EXTERN void nobuffs(AsynchIO& aio);
+ QPID_COMMON_EXTERN void idle(AsynchIO& aio);
+ QPID_COMMON_EXTERN void closedSocket(AsynchIO& aio, const Socket& s);
};
}} // namespace qpid::sys
diff --git a/qpid/cpp/src/qpid/sys/Codec.h b/qpid/cpp/src/qpid/sys/Codec.h
index f9645f554e..ace721fbcc 100644
--- a/qpid/cpp/src/qpid/sys/Codec.h
+++ b/qpid/cpp/src/qpid/sys/Codec.h
@@ -38,11 +38,11 @@ class Codec
* @return may be less than size if there was incomplete
* data at the end of the buffer.
*/
- virtual size_t decode(const char* buffer, size_t size) = 0;
+ virtual std::size_t decode(const char* buffer, std::size_t size) = 0;
/** Encode into buffer, return number of bytes encoded */
- virtual size_t encode(const char* buffer, size_t size) = 0;
+ virtual std::size_t encode(const char* buffer, std::size_t size) = 0;
/** Return true if we have data to encode */
virtual bool canEncode() = 0;
diff --git a/qpid/cpp/src/qpid/sys/ConnectionOutputHandlerPtr.h b/qpid/cpp/src/qpid/sys/ConnectionOutputHandlerPtr.h
index df6de89982..32809d86a1 100644
--- a/qpid/cpp/src/qpid/sys/ConnectionOutputHandlerPtr.h
+++ b/qpid/cpp/src/qpid/sys/ConnectionOutputHandlerPtr.h
@@ -30,7 +30,7 @@ namespace sys {
/**
* A ConnectionOutputHandler that delegates to another
* ConnectionOutputHandler. Allows the "real" ConnectionOutputHandler
- * to be changed modified without updating all the pointers/references
+ * to be changed without updating all the pointers/references
* using the ConnectionOutputHandlerPtr
*/
class ConnectionOutputHandlerPtr : public ConnectionOutputHandler
diff --git a/qpid/cpp/src/qpid/sys/CopyOnWriteArray.h b/qpid/cpp/src/qpid/sys/CopyOnWriteArray.h
index a09ee9d441..577a475afd 100644
--- a/qpid/cpp/src/qpid/sys/CopyOnWriteArray.h
+++ b/qpid/cpp/src/qpid/sys/CopyOnWriteArray.h
@@ -80,7 +80,7 @@ public:
bool add_unless(T& t, F f)
{
Mutex::ScopedLock l(lock);
- if (array && find_if(array->begin(), array->end(), f) != array->end()) {
+ if (array && std::find_if(array->begin(), array->end(), f) != array->end()) {
return false;
} else {
ArrayPtr copy(array ? new std::vector<T>(*array) : new std::vector<T>());
diff --git a/qpid/cpp/src/qpid/sys/DispatchHandle.cpp b/qpid/cpp/src/qpid/sys/DispatchHandle.cpp
index cbdee7eda6..cd7dec7fa6 100644
--- a/qpid/cpp/src/qpid/sys/DispatchHandle.cpp
+++ b/qpid/cpp/src/qpid/sys/DispatchHandle.cpp
@@ -21,6 +21,8 @@
#include "DispatchHandle.h"
+#include <algorithm>
+
#include <boost/cast.hpp>
#include <assert.h>
@@ -29,7 +31,6 @@ namespace qpid {
namespace sys {
DispatchHandle::~DispatchHandle() {
- stopWatch();
}
void DispatchHandle::startWatch(Poller::shared_ptr poller0) {
@@ -37,13 +38,21 @@ void DispatchHandle::startWatch(Poller::shared_ptr poller0) {
bool w = writableCallback;
ScopedLock<Mutex> lock(stateLock);
- assert(state == IDLE);
+ assert(state == IDLE || state == DELAYED_IDLE);
// If no callbacks set then do nothing (that is what we were asked to do!)
// TODO: Maybe this should be an assert instead
if (!r && !w) {
- state = INACTIVE;
- return;
+ switch (state) {
+ case IDLE:
+ state = INACTIVE;
+ return;
+ case DELAYED_IDLE:
+ state = DELAYED_INACTIVE;
+ return;
+ default:
+ assert(state == IDLE || state == DELAYED_IDLE);
+ }
}
Poller::Direction d = r ?
@@ -53,9 +62,20 @@ void DispatchHandle::startWatch(Poller::shared_ptr poller0) {
poller = poller0;
poller->addFd(*this, d);
- state = r ?
- (w ? ACTIVE_RW : ACTIVE_R) :
- ACTIVE_W;
+ switch (state) {
+ case IDLE:
+ state = r ?
+ (w ? ACTIVE_RW : ACTIVE_R) :
+ ACTIVE_W;
+ return;
+ case DELAYED_IDLE:
+ state = r ?
+ (w ? DELAYED_RW : DELAYED_R) :
+ DELAYED_W;
+ return;
+ default:
+ assert(state == IDLE || state == DELAYED_IDLE);
+ }
}
void DispatchHandle::rewatch() {
@@ -93,6 +113,8 @@ void DispatchHandle::rewatch() {
case ACTIVE_RW:
// Don't need to do anything already waiting for readable/writable
break;
+ case ACTIVE_DELETE:
+ assert(state != ACTIVE_DELETE);
}
}
@@ -130,6 +152,8 @@ void DispatchHandle::rewatchRead() {
poller->modFd(*this, Poller::INOUT);
state = ACTIVE_RW;
break;
+ case ACTIVE_DELETE:
+ assert(state != ACTIVE_DELETE);
}
}
@@ -167,6 +191,8 @@ void DispatchHandle::rewatchWrite() {
case ACTIVE_RW:
// Nothing to do: already waiting for writable
break;
+ case ACTIVE_DELETE:
+ assert(state != ACTIVE_DELETE);
}
}
@@ -203,6 +229,8 @@ void DispatchHandle::unwatchRead() {
case ACTIVE_W:
case INACTIVE:
break;
+ case ACTIVE_DELETE:
+ assert(state != ACTIVE_DELETE);
}
}
@@ -239,6 +267,8 @@ void DispatchHandle::unwatchWrite() {
case ACTIVE_R:
case INACTIVE:
break;
+ case ACTIVE_DELETE:
+ assert(state != ACTIVE_DELETE);
}
}
@@ -261,6 +291,8 @@ void DispatchHandle::unwatch() {
poller->modFd(*this, Poller::NONE);
state = INACTIVE;
break;
+ case ACTIVE_DELETE:
+ assert(state != ACTIVE_DELETE);
}
}
@@ -280,47 +312,72 @@ void DispatchHandle::stopWatch() {
default:
state = IDLE;
break;
+ case ACTIVE_DELETE:
+ assert(state != ACTIVE_DELETE);
}
assert(poller);
poller->delFd(*this);
poller.reset();
}
+// If we are already in the IDLE state we can't do the callback as we might
+// race to delete and callback at the same time
+// TODO: might be able to fix this by adding a new state, but would make
+// the state machine even more complex
void DispatchHandle::call(Callback iCb) {
assert(iCb);
ScopedLock<Mutex> lock(stateLock);
- interruptedCallbacks.push(iCb);
-
- (void) poller->interrupt(*this);
+ switch (state) {
+ case IDLE:
+ case ACTIVE_DELETE:
+ assert(false);
+ return;
+ default:
+ interruptedCallbacks.push(iCb);
+ assert(poller);
+ (void) poller->interrupt(*this);
+ }
}
// The slightly strange switch structure
// is to ensure that the lock is released before
// we do the delete
void DispatchHandle::doDelete() {
- // Ensure that we're no longer watching anything
- stopWatch();
-
- // If we're in the middle of a callback defer the delete
{
ScopedLock<Mutex> lock(stateLock);
+ // Ensure that we're no longer watching anything
switch (state) {
+ case DELAYED_R:
+ case DELAYED_W:
+ case DELAYED_RW:
+ case DELAYED_INACTIVE:
+ assert(poller);
+ poller->delFd(*this);
+ poller.reset();
+ // Fallthrough
case DELAYED_IDLE:
- case DELAYED_DELETE:
state = DELAYED_DELETE;
+ // Fallthrough
+ case DELAYED_DELETE:
+ case ACTIVE_DELETE:
return;
case IDLE:
break;
default:
- // Can only get out of stopWatch() in DELAYED_IDLE/DELAYED_DELETE/IDLE states
- assert(false);
+ state = ACTIVE_DELETE;
+ assert(poller);
+ (void) poller->interrupt(*this);
+ poller->delFd(*this);
+ return;
}
}
- // If we're not then do it right away
+ // If we're IDLE we can do this right away
delete this;
}
void DispatchHandle::processEvent(Poller::EventType type) {
+ CallbackQueue callbacks;
+
// Note that we are now doing the callbacks
{
ScopedLock<Mutex> lock(stateLock);
@@ -336,6 +393,16 @@ void DispatchHandle::processEvent(Poller::EventType type) {
case ACTIVE_RW:
state = DELAYED_RW;
break;
+ case ACTIVE_DELETE:
+ // Need to make sure we clean up any pending callbacks in this case
+ std::swap(callbacks, interruptedCallbacks);
+ goto saybyebye;
+ // Can get here in idle if we are stopped in a different thread
+ // just after we return with this handle in Poller::wait
+ case IDLE:
+ // Can get here in INACTIVE if a non connection thread unwatches
+ // whilst we were stuck in the above lock
+ case INACTIVE:
// Can only get here in a DELAYED_* state in the rare case
// that we're already here for reading and we get activated for
// writing and we can write (it might be possible the other way
@@ -348,9 +415,9 @@ void DispatchHandle::processEvent(Poller::EventType type) {
case DELAYED_IDLE:
case DELAYED_DELETE:
return;
- default:
- assert(false);
}
+
+ std::swap(callbacks, interruptedCallbacks);
}
// Do callbacks - whilst we are doing the callbacks we are prevented from processing
@@ -378,8 +445,8 @@ void DispatchHandle::processEvent(Poller::EventType type) {
break;
case Poller::INTERRUPTED:
{
- ScopedLock<Mutex> lock(stateLock);
- assert(interruptedCallbacks.size() > 0);
+ // We could only be interrupted if we also had a callback to do
+ assert(callbacks.size() > 0);
// We'll actually do the interrupt below
}
break;
@@ -387,16 +454,18 @@ void DispatchHandle::processEvent(Poller::EventType type) {
assert(false);
}
- {
- ScopedLock<Mutex> lock(stateLock);
- // If we've got a pending interrupt do it now
- while (interruptedCallbacks.size() > 0) {
- Callback cb = interruptedCallbacks.front();
+ // If we have any callbacks do them now -
+ // (because we use a copy from before the previous callbacks we won't
+ // do anything yet that was just added)
+ while (callbacks.size() > 0) {
+ Callback cb = callbacks.front();
assert(cb);
cb(*this);
- interruptedCallbacks.pop();
+ callbacks.pop();
}
+ {
+ ScopedLock<Mutex> lock(stateLock);
// If any of the callbacks re-enabled reading/writing then actually
// do it now
switch (state) {
@@ -425,7 +494,9 @@ void DispatchHandle::processEvent(Poller::EventType type) {
case DELAYED_DELETE:
break;
}
- }
+ }
+
+saybyebye:
delete this;
}
diff --git a/qpid/cpp/src/qpid/sys/DispatchHandle.h b/qpid/cpp/src/qpid/sys/DispatchHandle.h
index ffcbd80f7e..bc9f98775e 100644
--- a/qpid/cpp/src/qpid/sys/DispatchHandle.h
+++ b/qpid/cpp/src/qpid/sys/DispatchHandle.h
@@ -24,7 +24,7 @@
#include "Poller.h"
#include "Mutex.h"
-
+#include "qpid/CommonImportExport.h"
#include <boost/function.hpp>
#include <queue>
@@ -65,6 +65,7 @@ private:
Mutex stateLock;
enum {
IDLE, INACTIVE, ACTIVE_R, ACTIVE_W, ACTIVE_RW,
+ ACTIVE_DELETE,
DELAYED_IDLE, DELAYED_INACTIVE, DELAYED_R, DELAYED_W, DELAYED_RW,
DELAYED_DELETE
} state;
@@ -82,7 +83,7 @@ public:
*@param wCb Callback called when the handle is writable.
*@param dCb Callback called when the handle is disconnected.
*/
- DispatchHandle(const IOHandle& h, Callback rCb, Callback wCb, Callback dCb) :
+ QPID_COMMON_EXTERN DispatchHandle(const IOHandle& h, Callback rCb, Callback wCb, Callback dCb) :
PollerHandle(h),
readableCallback(rCb),
writableCallback(wCb),
@@ -90,42 +91,42 @@ public:
state(IDLE)
{}
- ~DispatchHandle();
+ QPID_COMMON_EXTERN ~DispatchHandle();
/** Add this DispatchHandle to the poller to be watched. */
- void startWatch(Poller::shared_ptr poller);
+ QPID_COMMON_EXTERN void startWatch(Poller::shared_ptr poller);
/** Resume watching for all non-0 callbacks. */
- void rewatch();
+ QPID_COMMON_EXTERN void rewatch();
/** Resume watching for read only. */
- void rewatchRead();
+ QPID_COMMON_EXTERN void rewatchRead();
/** Resume watching for write only. */
- void rewatchWrite();
+ QPID_COMMON_EXTERN void rewatchWrite();
/** Stop watching temporarily. The DispatchHandle remains
associated with the poller and can be re-activated using
rewatch. */
- void unwatch();
+ QPID_COMMON_EXTERN void unwatch();
/** Stop watching for read */
- void unwatchRead();
+ QPID_COMMON_EXTERN void unwatchRead();
/** Stop watching for write */
- void unwatchWrite();
+ QPID_COMMON_EXTERN void unwatchWrite();
/** Stop watching permanently. Disassociates from the poller. */
- void stopWatch();
+ QPID_COMMON_EXTERN void stopWatch();
/** Interrupt watching this handle and make a serialised callback that respects the
* same exclusivity guarantees as the other callbacks
*/
- void call(Callback iCb);
+ QPID_COMMON_EXTERN void call(Callback iCb);
protected:
/** Override to get extra processing done when the DispatchHandle is deleted. */
- void doDelete();
+ QPID_COMMON_EXTERN void doDelete();
private:
- void processEvent(Poller::EventType dir);
+ QPID_COMMON_EXTERN void processEvent(Poller::EventType dir);
};
class DispatchHandleRef {
diff --git a/qpid/cpp/src/qpid/sys/Dispatcher.h b/qpid/cpp/src/qpid/sys/Dispatcher.h
index f7c9e8d731..2f3ed10901 100644
--- a/qpid/cpp/src/qpid/sys/Dispatcher.h
+++ b/qpid/cpp/src/qpid/sys/Dispatcher.h
@@ -24,6 +24,7 @@
#include "Poller.h"
#include "Runnable.h"
+#include "qpid/CommonImportExport.h"
namespace qpid {
namespace sys {
@@ -32,10 +33,10 @@ class Dispatcher : public Runnable {
const Poller::shared_ptr poller;
public:
- Dispatcher(Poller::shared_ptr poller);
- ~Dispatcher();
+ QPID_COMMON_EXTERN Dispatcher(Poller::shared_ptr poller);
+ QPID_COMMON_EXTERN ~Dispatcher();
- void run();
+ QPID_COMMON_EXTERN void run();
};
}}
diff --git a/qpid/cpp/src/qpid/sys/IOHandle.h b/qpid/cpp/src/qpid/sys/IOHandle.h
index 0bf2abbafa..656e5e1efd 100644
--- a/qpid/cpp/src/qpid/sys/IOHandle.h
+++ b/qpid/cpp/src/qpid/sys/IOHandle.h
@@ -22,6 +22,8 @@
*
*/
+#include "qpid/CommonImportExport.h"
+
namespace qpid {
namespace sys {
@@ -50,8 +52,8 @@ class IOHandle {
protected:
IOHandlePrivate* const impl;
- IOHandle(IOHandlePrivate*);
- virtual ~IOHandle();
+ IOHandle(IOHandlePrivate*);
+ QPID_COMMON_EXTERN virtual ~IOHandle();
};
}}
diff --git a/qpid/cpp/src/qpid/sys/PollableCondition.h b/qpid/cpp/src/qpid/sys/PollableCondition.h
index 56d38f90da..f49fb22cb4 100644
--- a/qpid/cpp/src/qpid/sys/PollableCondition.h
+++ b/qpid/cpp/src/qpid/sys/PollableCondition.h
@@ -22,7 +22,58 @@
*
*/
-// Currently only has a posix implementation, add #ifdefs for other platforms as needed.
-#include "posix/PollableCondition.h"
+#include "qpid/sys/Poller.h"
+#include "qpid/CommonImportExport.h"
+#include <boost/function.hpp>
+#include <boost/shared_ptr.hpp>
+
+
+namespace qpid {
+namespace sys {
+
+class PollableConditionPrivate;
+
+class PollableCondition {
+public:
+ typedef boost::function1<void, PollableCondition&> Callback;
+
+ QPID_COMMON_EXTERN PollableCondition(const Callback& cb,
+ const boost::shared_ptr<sys::Poller>& poller);
+
+ QPID_COMMON_EXTERN ~PollableCondition();
+
+ /**
+ * Set the condition. Triggers callback to Callback from Poller.
+ * When callback is made, condition is suspended. Call rearm() to
+ * resume reacting to the condition.
+ */
+ QPID_COMMON_EXTERN void set();
+
+ /**
+ * Get the current state of the condition, then clear it.
+ *
+ * @return The state of the condition before it was cleared.
+ */
+ QPID_COMMON_EXTERN bool clear();
+
+ /**
+ * Temporarily suspend the ability for the poller to react to the
+ * condition. It can be rearm()ed later.
+ */
+ QPID_COMMON_EXTERN void disarm();
+
+ /**
+ * Reset the ability for the poller to react to the condition.
+ */
+ QPID_COMMON_EXTERN void rearm();
+
+ private:
+ PollableConditionPrivate *impl;
+
+ Callback callback;
+ boost::shared_ptr<sys::Poller> poller;
+};
+
+}} // namespace qpid::sys
#endif /*!QPID_SYS_POLLABLECONDITION_H*/
diff --git a/qpid/cpp/src/qpid/sys/PollableQueue.h b/qpid/cpp/src/qpid/sys/PollableQueue.h
index b5ff98c2c7..f8acf0a5f6 100644
--- a/qpid/cpp/src/qpid/sys/PollableQueue.h
+++ b/qpid/cpp/src/qpid/sys/PollableQueue.h
@@ -23,8 +23,6 @@
*/
#include "qpid/sys/PollableCondition.h"
-#include "qpid/sys/Dispatcher.h"
-#include "qpid/sys/DispatchHandle.h"
#include "qpid/sys/Monitor.h"
#include "qpid/sys/Thread.h"
#include <boost/function.hpp>
@@ -38,9 +36,10 @@ namespace sys {
class Poller;
/**
- * A queue that can be polled by sys::Poller. Any thread can push to
- * the queue, on wakeup the poller thread processes all items on the
- * queue by passing them to a callback in a batch.
+ * A queue whose item processing is dispatched by sys::Poller.
+ * Any thread can push to the queue; items pushed trigger an event the Poller
+ * recognizes. When a Poller I/O thread dispatches the event, a
+ * user-specified callback is invoked with all items on the queue.
*/
template <class T>
class PollableQueue {
@@ -50,12 +49,21 @@ class PollableQueue {
/**
* Callback to process a batch of items from the queue.
- * @param values to process, any items remaining after call are put back on the queue.
+ *
+ * @param values Queue of values to process. Any items remaining
+ * on return from Callback are put back on the queue.
*/
- typedef boost::function<void (Queue& values)> Callback;
+ typedef boost::function<void (Queue&)> Callback;
- /** When the queue is selected by the poller, values are passed to callback cb. */
- PollableQueue(const Callback& cb, const boost::shared_ptr<sys::Poller>& poller);
+ /**
+ * Constructor; sets necessary parameters.
+ *
+ * @param cb Callback that will be called to process items on the
+ * queue. Will be called from a Poller I/O thread.
+ * @param poller Poller to use for dispatching queue events.
+ */
+ PollableQueue(const Callback& cb,
+ const boost::shared_ptr<sys::Poller>& poller);
~PollableQueue();
@@ -85,14 +93,12 @@ class PollableQueue {
typedef sys::Monitor::ScopedLock ScopedLock;
typedef sys::Monitor::ScopedUnlock ScopedUnlock;
- void dispatch(sys::DispatchHandle&);
+ void dispatch(PollableCondition& cond);
void process();
mutable sys::Monitor lock;
Callback callback;
- boost::shared_ptr<sys::Poller> poller;
PollableCondition condition;
- DispatchHandleRef handle;
Queue queue, batch;
Thread dispatcher;
bool stopped;
@@ -100,11 +106,10 @@ class PollableQueue {
template <class T> PollableQueue<T>::PollableQueue(
const Callback& cb, const boost::shared_ptr<sys::Poller>& p)
- : callback(cb), poller(p),
- handle(condition, boost::bind(&PollableQueue<T>::dispatch, this, _1), 0, 0), stopped(true)
+ : callback(cb),
+ condition(boost::bind(&PollableQueue<T>::dispatch, this, _1), p),
+ stopped(true)
{
- handle.startWatch(poller);
- handle.unwatch();
}
template <class T> void PollableQueue<T>::start() {
@@ -112,11 +117,10 @@ template <class T> void PollableQueue<T>::start() {
if (!stopped) return;
stopped = false;
if (!queue.empty()) condition.set();
- handle.rewatch();
+ condition.rearm();
}
template <class T> PollableQueue<T>::~PollableQueue() {
- handle.stopWatch();
}
template <class T> void PollableQueue<T>::push(const T& t) {
@@ -125,15 +129,15 @@ template <class T> void PollableQueue<T>::push(const T& t) {
queue.push_back(t);
}
-template <class T> void PollableQueue<T>::dispatch(sys::DispatchHandle& h) {
+template <class T> void PollableQueue<T>::dispatch(PollableCondition& cond) {
ScopedLock l(lock);
assert(dispatcher.id() == 0);
dispatcher = Thread::current();
process();
dispatcher = Thread();
- if (queue.empty()) condition.clear();
+ if (queue.empty()) cond.clear();
if (stopped) lock.notifyAll();
- else h.rewatch();
+ else cond.rearm();
}
template <class T> void PollableQueue<T>::process() {
@@ -159,7 +163,7 @@ template <class T> void PollableQueue<T>::shutdown() {
template <class T> void PollableQueue<T>::stop() {
ScopedLock l(lock);
if (stopped) return;
- handle.unwatch();
+ condition.disarm();
stopped = true;
// Avoid deadlock if stop is called from the dispatch thread
while (dispatcher.id() && dispatcher.id() != Thread::current().id())
diff --git a/qpid/cpp/src/qpid/sys/Poller.h b/qpid/cpp/src/qpid/sys/Poller.h
index 8e9f67fefd..825ad8bfed 100644
--- a/qpid/cpp/src/qpid/sys/Poller.h
+++ b/qpid/cpp/src/qpid/sys/Poller.h
@@ -24,7 +24,7 @@
#include "Time.h"
#include "Runnable.h"
-
+#include "qpid/CommonImportExport.h"
#include <boost/shared_ptr.hpp>
namespace qpid {
@@ -74,10 +74,10 @@ public:
void process();
};
- Poller();
- ~Poller();
+ QPID_COMMON_EXTERN Poller();
+ QPID_COMMON_EXTERN ~Poller();
/** Note: this function is async-signal safe */
- void shutdown();
+ QPID_COMMON_EXTERN void shutdown();
// Interrupt waiting for a specific poller handle
// returns true if we could interrupt the handle
@@ -86,18 +86,19 @@ public:
// with the handle and the INTERRUPTED event type
// if it returns false then the handle is not being monitored by the poller
// - This can either be because it has just received an event which has been
- // reported and has not been reenabled since. Or because it was removed
- // from the monitoring set
- bool interrupt(PollerHandle& handle);
+ // reported and has not been reenabled since.
+ // - Because it was removed from the monitoring set
+ // - Or because it is already being interrupted
+ QPID_COMMON_EXTERN bool interrupt(PollerHandle& handle);
// Poller run loop
- void run();
+ QPID_COMMON_EXTERN void run();
- void addFd(PollerHandle& handle, Direction dir);
- void delFd(PollerHandle& handle);
- void modFd(PollerHandle& handle, Direction dir);
- void rearmFd(PollerHandle& handle);
- Event wait(Duration timeout = TIME_INFINITE);
+ QPID_COMMON_EXTERN void addFd(PollerHandle& handle, Direction dir);
+ QPID_COMMON_EXTERN void delFd(PollerHandle& handle);
+ QPID_COMMON_EXTERN void modFd(PollerHandle& handle, Direction dir);
+ QPID_COMMON_EXTERN void rearmFd(PollerHandle& handle);
+ QPID_COMMON_EXTERN Event wait(Duration timeout = TIME_INFINITE);
};
/**
@@ -110,11 +111,11 @@ class PollerHandle {
friend struct Poller::Event;
PollerHandlePrivate* const impl;
- virtual void processEvent(Poller::EventType) {};
+ QPID_COMMON_EXTERN virtual void processEvent(Poller::EventType) {};
public:
- PollerHandle(const IOHandle& h);
- virtual ~PollerHandle();
+ QPID_COMMON_EXTERN PollerHandle(const IOHandle& h);
+ QPID_COMMON_EXTERN virtual ~PollerHandle();
};
inline void Poller::Event::process() {
diff --git a/qpid/cpp/src/qpid/sys/Runnable.h b/qpid/cpp/src/qpid/sys/Runnable.h
index fb3927c612..4bf43c93d1 100644
--- a/qpid/cpp/src/qpid/sys/Runnable.h
+++ b/qpid/cpp/src/qpid/sys/Runnable.h
@@ -22,6 +22,7 @@
*/
#include <boost/function.hpp>
+#include "qpid/CommonImportExport.h"
namespace qpid {
namespace sys {
@@ -35,7 +36,7 @@ class Runnable
/** Type to represent a runnable as a Functor */
typedef boost::function0<void> Functor;
- virtual ~Runnable();
+ QPID_COMMON_EXTERN virtual ~Runnable();
/** Derived classes override run(). */
virtual void run() = 0;
diff --git a/qpid/cpp/src/qpid/sys/Shlib.h b/qpid/cpp/src/qpid/sys/Shlib.h
index a6d94b42d4..7f66cfec14 100644
--- a/qpid/cpp/src/qpid/sys/Shlib.h
+++ b/qpid/cpp/src/qpid/sys/Shlib.h
@@ -21,7 +21,8 @@
* under the License.
*
*/
-
+
+#include "qpid/CommonImportExport.h"
#include <boost/noncopyable.hpp>
#include <iostream>
@@ -40,10 +41,10 @@ class Shlib {
Shlib(const std::string& libname) { load(libname.c_str()); }
/** Unload shared library. */
- void unload();
+ QPID_COMMON_EXTERN void unload();
/** Look up symbol. */
- void* getSymbol(const char* symbol);
+ QPID_COMMON_EXTERN void* getSymbol(const char* symbol);
/** Look up symbol in shared library, cast it to the desired
* pointer type, void* by default.
@@ -57,7 +58,7 @@ class Shlib {
private:
void* handle;
- void load(const char* libname);
+ QPID_COMMON_EXTERN void load(const char* libname);
};
/** A shared library handle that unloads the shlib in it's dtor */
@@ -66,7 +67,7 @@ class AutoShlib : public Shlib {
/** Load shared library */
AutoShlib(const std::string& libname) : Shlib(libname) {}
/** Calls unload() */
- ~AutoShlib() throw();
+ QPID_COMMON_EXTERN ~AutoShlib() throw();
};
diff --git a/qpid/cpp/src/qpid/sys/Socket.h b/qpid/cpp/src/qpid/sys/Socket.h
index ae48b8104d..e6555f5774 100644
--- a/qpid/cpp/src/qpid/sys/Socket.h
+++ b/qpid/cpp/src/qpid/sys/Socket.h
@@ -24,11 +24,9 @@
#include "IOHandle.h"
#include "qpid/sys/IntegerTypes.h"
-
+#include "qpid/CommonImportExport.h"
#include <string>
-struct sockaddr;
-
namespace qpid {
namespace sys {
@@ -38,7 +36,7 @@ class Socket : public IOHandle
{
public:
/** Create a socket wrapper for descriptor. */
- Socket();
+ QPID_COMMON_EXTERN Socket();
/** Create an initialized TCP socket */
void createTcp() const;
@@ -49,21 +47,21 @@ public:
/** Set socket non blocking */
void setNonblocking() const;
- void connect(const std::string& host, uint16_t port) const;
+ QPID_COMMON_EXTERN void connect(const std::string& host, uint16_t port) const;
- void close() const;
+ QPID_COMMON_EXTERN void close() const;
/** Bind to a port and start listening.
*@param port 0 means choose an available port.
*@param backlog maximum number of pending connections.
*@return The bound port.
*/
- int listen(uint16_t port = 0, int backlog = 10) const;
+ QPID_COMMON_EXTERN int listen(uint16_t port = 0, int backlog = 10) const;
/** Returns the "socket name" ie the address bound to
* the near end of the socket
*/
- std::string getSockname() const;
+ QPID_COMMON_EXTERN std::string getSockname() const;
/** Returns the "peer name" ie the address bound to
* the remote end of the socket
@@ -74,14 +72,14 @@ public:
* Returns an address (host and port) for the remote end of the
* socket
*/
- std::string getPeerAddress() const;
+ QPID_COMMON_EXTERN std::string getPeerAddress() const;
/**
* Returns an address (host and port) for the local end of the
* socket
*/
std::string getLocalAddress() const;
- uint16_t getLocalPort() const;
+ QPID_COMMON_EXTERN uint16_t getLocalPort() const;
uint16_t getRemotePort() const;
/**
@@ -93,13 +91,13 @@ public:
/** Accept a connection from a socket that is already listening
* and has an incoming connection
*/
- Socket* accept(struct sockaddr *addr, socklen_t *addrlen) const;
+ QPID_COMMON_EXTERN Socket* accept() const;
// TODO The following are raw operations, maybe they need better wrapping?
- int read(void *buf, size_t count) const;
- int write(const void *buf, size_t count) const;
+ QPID_COMMON_EXTERN int read(void *buf, size_t count) const;
+ QPID_COMMON_EXTERN int write(const void *buf, size_t count) const;
- void setTcpNoDelay(bool nodelay) const;
+ QPID_COMMON_EXTERN void setTcpNoDelay(bool nodelay) const;
private:
Socket(IOHandlePrivate*);
diff --git a/qpid/cpp/src/qpid/sys/StrError.h b/qpid/cpp/src/qpid/sys/StrError.h
index 3843f2abe1..69cc7e714c 100644
--- a/qpid/cpp/src/qpid/sys/StrError.h
+++ b/qpid/cpp/src/qpid/sys/StrError.h
@@ -23,12 +23,13 @@
*/
#include <string>
+#include "qpid/CommonImportExport.h"
namespace qpid {
namespace sys {
/** Get the error message for a system number err, e.g. errno. */
-std::string strError(int err);
+QPID_COMMON_EXTERN std::string strError(int err);
}} // namespace qpid
diff --git a/qpid/cpp/src/qpid/sys/SystemInfo.h b/qpid/cpp/src/qpid/sys/SystemInfo.h
index d43fe34b04..6e97022b36 100644
--- a/qpid/cpp/src/qpid/sys/SystemInfo.h
+++ b/qpid/cpp/src/qpid/sys/SystemInfo.h
@@ -23,6 +23,7 @@
#include "qpid/sys/IntegerTypes.h"
#include "qpid/Address.h"
+#include "qpid/CommonImportExport.h"
namespace qpid {
namespace sys {
@@ -36,15 +37,15 @@ namespace SystemInfo {
* Estimate available concurrency, e.g. number of CPU cores.
* -1 means estimate not available on this platform.
*/
- long concurrency();
+ QPID_COMMON_EXTERN long concurrency();
/**
* Get the local host name and set it in the specified TcpAddress.
* Returns false if it can't be obtained and sets errno to any error value.
*/
- bool getLocalHostname (TcpAddress &address);
+ QPID_COMMON_EXTERN bool getLocalHostname (TcpAddress &address);
- void getLocalIpAddresses (uint16_t port, std::vector<Address> &addrList);
+ QPID_COMMON_EXTERN void getLocalIpAddresses (uint16_t port, std::vector<Address> &addrList);
/**
* Retrieve system identifiers and versions. This is information that can
@@ -57,7 +58,7 @@ namespace SystemInfo {
* @param version Receives the OS release version (kernel, build, sp, etc.)
* @param machine Receives the hardware type.
*/
- void getSystemId (std::string &osName,
+ QPID_COMMON_EXTERN void getSystemId (std::string &osName,
std::string &nodeName,
std::string &release,
std::string &version,
@@ -66,12 +67,17 @@ namespace SystemInfo {
/**
* Get the process ID of the current process.
*/
- uint32_t getProcessId();
+ QPID_COMMON_EXTERN uint32_t getProcessId();
/**
* Get the process ID of the parent of the current process.
*/
- uint32_t getParentProcessId();
+ QPID_COMMON_EXTERN uint32_t getParentProcessId();
+
+ /**
+ * Get the name of the current process (i.e. the name of the executable)
+ */
+ QPID_COMMON_EXTERN std::string getProcessName();
}}} // namespace qpid::sys::SystemInfo
diff --git a/qpid/cpp/src/qpid/sys/Thread.h b/qpid/cpp/src/qpid/sys/Thread.h
index e2b904aa1a..b532d4d80a 100644
--- a/qpid/cpp/src/qpid/sys/Thread.h
+++ b/qpid/cpp/src/qpid/sys/Thread.h
@@ -22,11 +22,14 @@
*
*/
#include <boost/shared_ptr.hpp>
+#include "qpid/CommonImportExport.h"
#ifdef _WIN32
# define QPID_TSS __declspec(thread)
#elif defined (__GNUC__)
# define QPID_TSS __thread
+#elif defined (__SUNPRO_CC)
+# define QPID_TSS __thread
#else
# error "Dont know how to define QPID_TSS for this platform"
#endif
@@ -42,15 +45,15 @@ class Thread
boost::shared_ptr<ThreadPrivate> impl;
public:
- Thread();
- explicit Thread(qpid::sys::Runnable*);
- explicit Thread(qpid::sys::Runnable&);
+ QPID_COMMON_EXTERN Thread();
+ QPID_COMMON_EXTERN explicit Thread(qpid::sys::Runnable*);
+ QPID_COMMON_EXTERN explicit Thread(qpid::sys::Runnable&);
- void join();
+ QPID_COMMON_EXTERN void join();
- unsigned long id();
+ QPID_COMMON_EXTERN unsigned long id();
- static Thread current();
+ QPID_COMMON_EXTERN static Thread current();
/** ID of current thread for logging.
* Workaround for broken Thread::current() in APR
diff --git a/qpid/cpp/src/qpid/sys/Time.h b/qpid/cpp/src/qpid/sys/Time.h
index d39be95434..b7173406ca 100644
--- a/qpid/cpp/src/qpid/sys/Time.h
+++ b/qpid/cpp/src/qpid/sys/Time.h
@@ -33,6 +33,8 @@
# include "posix/Time.h"
#endif
+#include "qpid/CommonImportExport.h"
+
#include <limits>
#include <iosfwd>
@@ -86,23 +88,23 @@ class AbsTime {
TimePrivate timepoint;
public:
- inline AbsTime() {}
- AbsTime(const AbsTime& time0, const Duration& duration);
+ QPID_COMMON_EXTERN inline AbsTime() {}
+ QPID_COMMON_EXTERN AbsTime(const AbsTime& time0, const Duration& duration);
// Default assignment operation fine
// Default copy constructor fine
- static AbsTime now();
- static AbsTime FarFuture();
+ QPID_COMMON_EXTERN static AbsTime now();
+ QPID_COMMON_EXTERN static AbsTime FarFuture();
const TimePrivate& getPrivate(void) const { return timepoint; }
bool operator==(const AbsTime& t) const { return t.timepoint == timepoint; }
template <class S> void serialize(S& s) { s(timepoint); }
friend bool operator<(const AbsTime& a, const AbsTime& b);
friend bool operator>(const AbsTime& a, const AbsTime& b);
- friend std::ostream& operator << (std::ostream&, const AbsTime&);
+ QPID_COMMON_EXTERN friend std::ostream& operator << (std::ostream&, const AbsTime&);
};
-std::ostream& operator << (std::ostream&, const AbsTime&);
+QPID_COMMON_EXTERN std::ostream& operator << (std::ostream&, const AbsTime&);
/**
* @class Duration
@@ -120,9 +122,9 @@ class Duration {
friend class AbsTime;
public:
- inline Duration(int64_t time0);
- explicit Duration(const AbsTime& time0);
- explicit Duration(const AbsTime& start, const AbsTime& finish);
+ QPID_COMMON_EXTERN inline Duration(int64_t time0);
+ QPID_COMMON_EXTERN explicit Duration(const AbsTime& time0);
+ QPID_COMMON_EXTERN explicit Duration(const AbsTime& start, const AbsTime& finish);
inline operator int64_t() const;
};
@@ -158,10 +160,10 @@ const Duration TIME_INFINITE = std::numeric_limits<int64_t>::max();
const AbsTime FAR_FUTURE = AbsTime::FarFuture();
/** Portable sleep for a number of seconds */
-void sleep(int secs);
+QPID_COMMON_EXTERN void sleep(int secs);
/** Portable sleep for a number of microseconds */
-void usleep(uint64_t usecs);
+QPID_COMMON_EXTERN void usleep(uint64_t usecs);
}}
diff --git a/qpid/cpp/src/qpid/sys/Timer.h b/qpid/cpp/src/qpid/sys/Timer.h
index 2561e41034..dab2f55edb 100644
--- a/qpid/cpp/src/qpid/sys/Timer.h
+++ b/qpid/cpp/src/qpid/sys/Timer.h
@@ -25,7 +25,7 @@
#include "qpid/sys/Thread.h"
#include "qpid/sys/Runnable.h"
#include "qpid/RefCounted.h"
-
+#include "qpid/CommonImportExport.h"
#include <memory>
#include <queue>
@@ -49,15 +49,15 @@ class TimerTask : public RefCounted {
void fireTask();
public:
- TimerTask(Duration period);
- TimerTask(AbsTime fireTime);
- virtual ~TimerTask();
+ QPID_COMMON_EXTERN TimerTask(Duration period);
+ QPID_COMMON_EXTERN TimerTask(AbsTime fireTime);
+ QPID_COMMON_EXTERN virtual ~TimerTask();
- void setupNextFire();
- void restart();
- void delayTill(AbsTime fireTime);
- void cancel();
- bool isCancelled() const;
+ QPID_COMMON_EXTERN void setupNextFire();
+ QPID_COMMON_EXTERN void restart();
+ QPID_COMMON_EXTERN void delayTill(AbsTime fireTime);
+ QPID_COMMON_EXTERN void cancel();
+ QPID_COMMON_EXTERN bool isCancelled() const;
protected:
// Must be overridden with callback
@@ -78,12 +78,12 @@ class Timer : private Runnable {
void run();
public:
- Timer();
- ~Timer();
+ QPID_COMMON_EXTERN Timer();
+ QPID_COMMON_EXTERN ~Timer();
- void add(boost::intrusive_ptr<TimerTask> task);
- void start();
- void stop();
+ QPID_COMMON_EXTERN void add(boost::intrusive_ptr<TimerTask> task);
+ QPID_COMMON_EXTERN void start();
+ QPID_COMMON_EXTERN void stop();
};
diff --git a/qpid/cpp/src/qpid/sys/alloca.h b/qpid/cpp/src/qpid/sys/alloca.h
new file mode 100644
index 0000000000..e989670e4f
--- /dev/null
+++ b/qpid/cpp/src/qpid/sys/alloca.h
@@ -0,0 +1,39 @@
+#ifndef QPID_SYS_ALLOCA_H
+#define QPID_SYS_ALLOCA_H
+
+/*
+ * 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.
+ *
+ */
+
+#if (defined(_WINDOWS) || defined (WIN32)) && defined(_MSC_VER)
+#include <malloc.h>
+#ifdef alloc
+# undef alloc
+#endif
+#define alloc _alloc
+#ifdef alloca
+# undef alloca
+#endif
+#define alloca _alloca
+#endif
+#if !defined _WINDOWS && !defined WIN32
+#include <alloca.h>
+#endif
+
+#endif /*!QPID_SYS_ALLOCA_H*/
diff --git a/qpid/cpp/src/qpid/sys/epoll/EpollPoller.cpp b/qpid/cpp/src/qpid/sys/epoll/EpollPoller.cpp
index 10705e12da..42b5d8b1aa 100644
--- a/qpid/cpp/src/qpid/sys/epoll/EpollPoller.cpp
+++ b/qpid/cpp/src/qpid/sys/epoll/EpollPoller.cpp
@@ -54,17 +54,20 @@ class PollerHandlePrivate {
INACTIVE,
HUNGUP,
MONITORED_HUNGUP,
+ INTERRUPTED,
DELETED
};
int fd;
::__uint32_t events;
+ PollerHandle* pollerHandle;
FDStat stat;
Mutex lock;
- PollerHandlePrivate(int f) :
+ PollerHandlePrivate(int f, PollerHandle* p) :
fd(f),
events(0),
+ pollerHandle(p),
stat(ABSENT) {
}
@@ -101,6 +104,14 @@ class PollerHandlePrivate {
stat = HUNGUP;
}
+ bool isInterrupted() const {
+ return stat == INTERRUPTED;
+ }
+
+ void setInterrupted() {
+ stat = INTERRUPTED;
+ }
+
bool isDeleted() const {
return stat == DELETED;
}
@@ -111,7 +122,7 @@ class PollerHandlePrivate {
};
PollerHandle::PollerHandle(const IOHandle& h) :
- impl(new PollerHandlePrivate(toFd(h.impl)))
+ impl(new PollerHandlePrivate(toFd(h.impl), this))
{}
PollerHandle::~PollerHandle() {
@@ -120,6 +131,10 @@ PollerHandle::~PollerHandle() {
if (impl->isDeleted()) {
return;
}
+ if (impl->isInterrupted()) {
+ impl->setDeleted();
+ return;
+ }
if (impl->isActive()) {
impl->setDeleted();
}
@@ -243,23 +258,21 @@ class PollerPrivate {
::close(epollFd);
}
- void interrupt(bool all=false) {
+ void interrupt() {
::epoll_event epe;
- if (all) {
- // Not EPOLLONESHOT, so we eventually get all threads
- epe.events = ::EPOLLIN;
- epe.data.u64 = 0; // Keep valgrind happy
- } else {
- // Use EPOLLONESHOT so we only wake a single thread
- epe.events = ::EPOLLIN | ::EPOLLONESHOT;
- epe.data.u64 = 0; // Keep valgrind happy
- epe.data.ptr = &static_cast<PollerHandle&>(interruptHandle);
- }
+ // Use EPOLLONESHOT so we only wake a single thread
+ epe.events = ::EPOLLIN | ::EPOLLONESHOT;
+ epe.data.u64 = 0; // Keep valgrind happy
+ epe.data.ptr = &static_cast<PollerHandle&>(interruptHandle);
QPID_POSIX_CHECK(::epoll_ctl(epollFd, EPOLL_CTL_MOD, alwaysReadableFd, &epe));
}
void interruptAll() {
- interrupt(true);
+ ::epoll_event epe;
+ // Not EPOLLONESHOT, so we eventually get all threads
+ epe.events = ::EPOLLIN;
+ epe.data.u64 = 0; // Keep valgrind happy
+ QPID_POSIX_CHECK(::epoll_ctl(epollFd, EPOLL_CTL_MOD, alwaysReadableFd, &epe));
}
};
@@ -281,7 +294,7 @@ void Poller::addFd(PollerHandle& handle, Direction dir) {
epe.events = eh.events | PollerPrivate::directionToEpollEvent(dir);
}
epe.data.u64 = 0; // Keep valgrind happy
- epe.data.ptr = &handle;
+ epe.data.ptr = &eh;
QPID_POSIX_CHECK(::epoll_ctl(impl->epollFd, op, eh.fd, &epe));
@@ -312,7 +325,7 @@ void Poller::modFd(PollerHandle& handle, Direction dir) {
::epoll_event epe;
epe.events = PollerPrivate::directionToEpollEvent(dir) | ::EPOLLONESHOT;
epe.data.u64 = 0; // Keep valgrind happy
- epe.data.ptr = &handle;
+ epe.data.ptr = &eh;
QPID_POSIX_CHECK(::epoll_ctl(impl->epollFd, EPOLL_CTL_MOD, eh.fd, &epe));
@@ -329,7 +342,7 @@ void Poller::rearmFd(PollerHandle& handle) {
::epoll_event epe;
epe.events = eh.events;
epe.data.u64 = 0; // Keep valgrind happy
- epe.data.ptr = &handle;
+ epe.data.ptr = &eh;
QPID_POSIX_CHECK(::epoll_ctl(impl->epollFd, EPOLL_CTL_MOD, eh.fd, &epe));
@@ -355,15 +368,14 @@ bool Poller::interrupt(PollerHandle& handle) {
{
PollerHandlePrivate& eh = *handle.impl;
ScopedLock<Mutex> l(eh.lock);
- if (eh.isInactive()) {
+ if (!eh.isActive()) {
return false;
}
::epoll_event epe;
epe.events = 0;
epe.data.u64 = 0; // Keep valgrind happy
- epe.data.ptr = &eh;
QPID_POSIX_CHECK(::epoll_ctl(impl->epollFd, EPOLL_CTL_MOD, eh.fd, &epe));
- eh.setInactive();
+ eh.setInterrupted();
}
PollerPrivate::InterruptHandle& ih = impl->interruptHandle;
@@ -422,37 +434,54 @@ Poller::Event Poller::wait(Duration timeout) {
#else
int rc = ::epoll_pwait(impl->epollFd, &epe, 1, timeoutMs, &impl->sigMask);
#endif
- // Check for shutdown
- if (impl->isShutdown) {
- PollerHandleDeletionManager.markAllUnusedInThisThread();
- return Event(0, SHUTDOWN);
- }
if (rc ==-1 && errno != EINTR) {
QPID_POSIX_CHECK(rc);
} else if (rc > 0) {
assert(rc == 1);
- PollerHandle* handle = static_cast<PollerHandle*>(epe.data.ptr);
+ void* dataPtr = epe.data.ptr;
+
+ // Check if this is an interrupt
+ PollerPrivate::InterruptHandle& interruptHandle = impl->interruptHandle;
+ if (dataPtr == &interruptHandle) {
+ PollerHandle* wrappedHandle = 0;
+ {
+ ScopedLock<Mutex> l(interruptHandle.impl->lock);
+ if (interruptHandle.impl->isActive()) {
+ wrappedHandle = interruptHandle.getHandle();
+ // If there is an interrupt queued behind this one we need to arm it
+ // We do it this way so that another thread can pick it up
+ if (interruptHandle.queuedHandles()) {
+ impl->interrupt();
+ interruptHandle.impl->setActive();
+ } else {
+ interruptHandle.impl->setInactive();
+ }
+ }
+ }
+ if (wrappedHandle) {
+ ScopedLock<Mutex> l(wrappedHandle->impl->lock);
+ if (!wrappedHandle->impl->isDeleted()) {
+ wrappedHandle->impl->setInactive();
+ return Event(wrappedHandle, INTERRUPTED);
+ }
+ PollerHandleDeletionManager.markForDeletion(wrappedHandle->impl);
+ }
+ continue;
+ }
+
+ // Check for shutdown
+ if (impl->isShutdown) {
+ PollerHandleDeletionManager.markAllUnusedInThisThread();
+ return Event(0, SHUTDOWN);
+ }
- PollerHandlePrivate& eh = *handle->impl;
+ PollerHandlePrivate& eh = *static_cast<PollerHandlePrivate*>(dataPtr);
ScopedLock<Mutex> l(eh.lock);
// the handle could have gone inactive since we left the epoll_wait
if (eh.isActive()) {
-
- // Check if this is an interrupt
- if (handle == &impl->interruptHandle) {
- PollerHandle* wrappedHandle = impl->interruptHandle.getHandle();
- // If there is an interrupt queued behind this one we need to arm it
- // We do it this way so that another thread can pick it up
- if (impl->interruptHandle.queuedHandles()) {
- impl->interrupt();
- eh.setActive();
- } else {
- eh.setInactive();
- }
- return Event(wrappedHandle, INTERRUPTED);
- }
+ PollerHandle* handle = eh.pollerHandle;
// If the connection has been hungup we could still be readable
// (just not writable), allow us to readable until we get here again
diff --git a/qpid/cpp/src/qpid/sys/posix/AsynchIO.cpp b/qpid/cpp/src/qpid/sys/posix/AsynchIO.cpp
index a356a72650..a914dc817a 100644
--- a/qpid/cpp/src/qpid/sys/posix/AsynchIO.cpp
+++ b/qpid/cpp/src/qpid/sys/posix/AsynchIO.cpp
@@ -123,7 +123,7 @@ void AsynchAcceptorPrivate::readable(DispatchHandle& h) {
// TODO: Currently we ignore the peers address, perhaps we should
// log it or use it for connection acceptance.
try {
- s = socket.accept(0, 0);
+ s = socket.accept();
if (s) {
acceptedCallback(*s);
} else {
@@ -474,7 +474,7 @@ void AsynchIO::readable(DispatchHandle& h) {
break;
} else {
// Report error then just treat as a socket disconnect
- QPID_LOG(error, "Error reading socket: " << qpid::sys::strError(rc) << "(" << rc << ")" );
+ QPID_LOG(error, "Error reading socket: " << qpid::sys::strError(errno) << "(" << errno << ")" );
eofCallback(*this);
h.unwatchRead();
break;
diff --git a/qpid/cpp/src/qpid/sys/posix/PollableCondition.cpp b/qpid/cpp/src/qpid/sys/posix/PollableCondition.cpp
index 0c55fd3c0d..0991e5fd76 100644
--- a/qpid/cpp/src/qpid/sys/posix/PollableCondition.cpp
+++ b/qpid/cpp/src/qpid/sys/posix/PollableCondition.cpp
@@ -22,17 +22,46 @@
*
*/
-#include "PollableCondition.h"
+#include "qpid/sys/PollableCondition.h"
+#include "qpid/sys/DispatchHandle.h"
+#include "qpid/sys/IOHandle.h"
#include "qpid/sys/posix/PrivatePosix.h"
#include "qpid/Exception.h"
+#include <boost/bind.hpp>
+
#include <unistd.h>
#include <fcntl.h>
namespace qpid {
namespace sys {
-PollableCondition::PollableCondition() : IOHandle(new sys::IOHandlePrivate) {
+class PollableConditionPrivate : public sys::IOHandle {
+ friend class PollableCondition;
+
+private:
+ PollableConditionPrivate(const sys::PollableCondition::Callback& cb,
+ sys::PollableCondition& parent,
+ const boost::shared_ptr<sys::Poller>& poller);
+ ~PollableConditionPrivate();
+
+ void dispatch(sys::DispatchHandle& h);
+ void rewatch();
+ void unwatch();
+
+private:
+ PollableCondition::Callback cb;
+ PollableCondition& parent;
+ boost::shared_ptr<sys::Poller> poller;
+ int writeFd;
+ std::auto_ptr<DispatchHandleRef> handle;
+};
+
+PollableConditionPrivate::PollableConditionPrivate(const sys::PollableCondition::Callback& cb,
+ sys::PollableCondition& parent,
+ const boost::shared_ptr<sys::Poller>& poller)
+ : IOHandle(new sys::IOHandlePrivate), cb(cb), parent(parent)
+{
int fds[2];
if (::pipe(fds) == -1)
throw ErrnoException(QPID_MSG("Can't create PollableCondition"));
@@ -42,22 +71,71 @@ PollableCondition::PollableCondition() : IOHandle(new sys::IOHandlePrivate) {
throw ErrnoException(QPID_MSG("Can't create PollableCondition"));
if (::fcntl(writeFd, F_SETFL, O_NONBLOCK) == -1)
throw ErrnoException(QPID_MSG("Can't create PollableCondition"));
+ handle.reset (new DispatchHandleRef(*this,
+ boost::bind(&sys::PollableConditionPrivate::dispatch, this, _1),
+ 0, 0));
+ handle->startWatch(poller);
+ handle->unwatch();
+}
+
+PollableConditionPrivate::~PollableConditionPrivate()
+{
+ handle->stopWatch();
+ close(writeFd);
+}
+
+void PollableConditionPrivate::dispatch(sys::DispatchHandle& /*h*/)
+{
+ cb(parent);
+}
+
+void PollableConditionPrivate::rewatch()
+{
+ handle->rewatch();
+}
+
+void PollableConditionPrivate::unwatch()
+{
+ handle->unwatch();
+}
+
+ /* PollableCondition */
+
+PollableCondition::PollableCondition(const Callback& cb,
+ const boost::shared_ptr<sys::Poller>& poller)
+ : impl(new PollableConditionPrivate(cb, *this, poller))
+{
+}
+
+PollableCondition::~PollableCondition()
+{
+ delete impl;
+}
+
+void PollableCondition::set() {
+ static const char dummy=0;
+ ssize_t n = ::write(impl->writeFd, &dummy, 1);
+ if (n == -1 && errno != EAGAIN)
+ throw ErrnoException("Error setting PollableCondition");
}
bool PollableCondition::clear() {
char buf[256];
ssize_t n;
bool wasSet = false;
- while ((n = ::read(impl->fd, buf, sizeof(buf))) > 0)
+ while ((n = ::read(impl->impl->fd, buf, sizeof(buf))) > 0)
wasSet = true;
- if (n == -1 && errno != EAGAIN) throw ErrnoException(QPID_MSG("Error clearing PollableCondition"));
+ if (n == -1 && errno != EAGAIN)
+ throw ErrnoException(QPID_MSG("Error clearing PollableCondition"));
return wasSet;
}
-void PollableCondition::set() {
- static const char dummy=0;
- ssize_t n = ::write(writeFd, &dummy, 1);
- if (n == -1 && errno != EAGAIN) throw ErrnoException("Error setting PollableCondition");
+void PollableCondition::disarm() {
+ impl->unwatch();
+}
+
+void PollableCondition::rearm() {
+ impl->rewatch();
}
@@ -71,22 +149,35 @@ void PollableCondition::set() {
namespace qpid {
namespace sys {
-PollableCondition::PollableCondition() : IOHandle(new sys::IOHandlePrivate) {
+PollableConditionPrivate::PollableConditionPrivate(const PollableCondition::Callback& cb,
+ sys::PollableCondition& parent,
+ const boost::shared_ptr<sys::Poller>& poller)
+ : cb(cb), parent(parent), poller(poller),
+ IOHandle(new sys::IOHandlePrivate) {
impl->fd = ::eventfd(0, 0);
if (impl->fd < 0) throw ErrnoException("conditionfd() failed");
}
+void PollableCondition::set() {
+ static const uint64_t value=1;
+ ssize_t n = ::write(impl->impl->fd,
+ reinterpret_cast<const void*>(&value), 8);
+ if (n != 8) throw ErrnoException("write failed on conditionfd");
+}
+
bool PollableCondition::clear() {
char buf[8];
- ssize_t n = ::read(impl->fd, buf, 8);
+ ssize_t n = ::read(impl->impl->fd, buf, 8);
if (n != 8) throw ErrnoException("read failed on conditionfd");
return *reinterpret_cast<uint64_t*>(buf);
}
-void PollableCondition::set() {
- static const uint64_t value=1;
- ssize_t n = ::write(impl->fd, reinterpret_cast<const void*>(&value), 8);
- if (n != 8) throw ErrnoException("write failed on conditionfd");
+void PollableCondition::disarm() {
+ // ????
+}
+
+void PollableCondition::rearm() {
+ // ????
}
#endif
diff --git a/qpid/cpp/src/qpid/sys/posix/Socket.cpp b/qpid/cpp/src/qpid/sys/posix/Socket.cpp
index 415d5293ef..ab0c28c48c 100644
--- a/qpid/cpp/src/qpid/sys/posix/Socket.cpp
+++ b/qpid/cpp/src/qpid/sys/posix/Socket.cpp
@@ -108,7 +108,7 @@ void Socket::createTcp() const
{
int& socket = impl->fd;
if (socket != -1) Socket::close();
- int s = ::socket (PF_INET, SOCK_STREAM, 0);
+ int s = ::socket (AF_INET, SOCK_STREAM, 0);
if (s < 0) throw QPID_POSIX_ERROR(errno);
socket = s;
}
@@ -138,25 +138,30 @@ const char* h_errstr(int e) {
}
}
-void Socket::connect(const std::string& host, uint16_t port) const
+void Socket::connect(const std::string& host, uint16_t p) const
{
- std::stringstream namestream;
- namestream << host << ":" << port;
- connectname = namestream.str();
+ std::stringstream portstream;
+ portstream << p;
+ std::string port = portstream.str();
+ connectname = host + ":" + port;
const int& socket = impl->fd;
- struct sockaddr_in name;
- name.sin_family = AF_INET;
- name.sin_port = htons(port);
- // TODO: Be good to make this work for IPv6 as well as IPv4
- // Use more modern lookup functions
- struct hostent* hp = gethostbyname ( host.c_str() );
- if (hp == 0)
- throw Exception(QPID_MSG("Cannot resolve " << host << ": " << h_errstr(h_errno)));
- ::memcpy(&name.sin_addr.s_addr, hp->h_addr_list[0], hp->h_length);
- if ((::connect(socket, (struct sockaddr*)(&name), sizeof(name)) < 0) &&
- (errno != EINPROGRESS))
+
+ ::addrinfo *res;
+ ::addrinfo hints;
+ ::memset(&hints, 0, sizeof(hints));
+ hints.ai_family = AF_INET; // In order to allow AF_INET6 we'd have to change createTcp() as well
+ hints.ai_socktype = SOCK_STREAM;
+ int n = ::getaddrinfo(host.c_str(), port.c_str(), &hints, &res);
+ if (n != 0)
+ throw Exception(QPID_MSG("Cannot resolve " << host << ": " << ::gai_strerror(n)));
+ // TODO the correct thing to do here is loop on failure until you've used all the returned addresses
+ if ((::connect(socket, res->ai_addr, res->ai_addrlen) < 0) &&
+ (errno != EINPROGRESS)) {
+ ::freeaddrinfo(res);
throw qpid::Exception(QPID_MSG(strError(errno) << ": " << host << ":" << port));
+ }
+ ::freeaddrinfo(res);
}
void
@@ -189,9 +194,9 @@ int Socket::listen(uint16_t port, int backlog) const
return ntohs(name.sin_port);
}
-Socket* Socket::accept(struct sockaddr *addr, socklen_t *addrlen) const
+Socket* Socket::accept() const
{
- int afd = ::accept(impl->fd, addr, addrlen);
+ int afd = ::accept(impl->fd, 0, 0);
if ( afd >= 0)
return new Socket(new IOHandlePrivate(afd));
else if (errno == EAGAIN)
@@ -238,7 +243,7 @@ uint16_t Socket::getLocalPort() const
uint16_t Socket::getRemotePort() const
{
- return atoi(getService(impl->fd, true).c_str());
+ return std::atoi(getService(impl->fd, true).c_str());
}
int Socket::getError() const
diff --git a/qpid/cpp/src/qpid/sys/posix/SystemInfo.cpp b/qpid/cpp/src/qpid/sys/posix/SystemInfo.cpp
index 938d4861c4..5d9eda605d 100755
--- a/qpid/cpp/src/qpid/sys/posix/SystemInfo.cpp
+++ b/qpid/cpp/src/qpid/sys/posix/SystemInfo.cpp
@@ -27,6 +27,9 @@
#include <arpa/inet.h>
#include <stdio.h>
#include <unistd.h>
+#include <iostream>
+#include <fstream>
+#include <sstream>
#ifndef HOST_NAME_MAX
# define HOST_NAME_MAX 256
@@ -104,6 +107,27 @@ uint32_t SystemInfo::getParentProcessId()
return (uint32_t) ::getppid();
}
+string SystemInfo::getProcessName()
+{
+ uint32_t pid = getProcessId();
+ string value;
+
+ stringstream pathStream;
+ pathStream << "/proc/" << pid << "/status";
+ ifstream input(pathStream.str().c_str());
+ if (input.good()) {
+ while (!input.eof()) {
+ string key;
+ input >> key;
+ if (key == "Name:") {
+ input >> value;
+ break;
+ }
+ }
+ input.close();
+ }
+ return value;
+}
}} // namespace qpid::sys
diff --git a/qpid/cpp/src/qpid/sys/solaris/ECFPoller.cpp b/qpid/cpp/src/qpid/sys/solaris/ECFPoller.cpp
index 783f84576b..f12012cbb0 100644
--- a/qpid/cpp/src/qpid/sys/solaris/ECFPoller.cpp
+++ b/qpid/cpp/src/qpid/sys/solaris/ECFPoller.cpp
@@ -30,9 +30,11 @@
#include <port.h>
#include <poll.h>
#include <errno.h>
+#include <pthread.h>
+#include <signal.h>
#include <assert.h>
-#include <vector>
+#include <queue>
#include <exception>
@@ -43,11 +45,11 @@ namespace qpid {
namespace sys {
// Deletion manager to handle deferring deletion of PollerHandles to when they definitely aren't being used
-DeletionManager<PollerHandle> PollerHandleDeletionManager;
+DeletionManager<PollerHandlePrivate> PollerHandleDeletionManager;
// Instantiate (and define) class static for DeletionManager
template <>
-DeletionManager<PollerHandle>::AllThreadsStatuses DeletionManager<PollerHandle>::allThreadsStatuses(0);
+DeletionManager<PollerHandlePrivate>::AllThreadsStatuses DeletionManager<PollerHandlePrivate>::allThreadsStatuses(0);
class PollerHandlePrivate {
friend class Poller;
@@ -58,7 +60,8 @@ class PollerHandlePrivate {
MONITORED,
INACTIVE,
HUNGUP,
- MONITORED_HUNGUP
+ MONITORED_HUNGUP,
+ DELETED
};
int fd;
@@ -104,6 +107,14 @@ class PollerHandlePrivate {
assert(stat == MONITORED);
stat = HUNGUP;
}
+
+ bool isDeleted() const {
+ return stat == DELETED;
+ }
+
+ void setDeleted() {
+ stat = DELETED;
+ }
};
PollerHandle::PollerHandle(const IOHandle& h) :
@@ -111,11 +122,16 @@ PollerHandle::PollerHandle(const IOHandle& h) :
{}
PollerHandle::~PollerHandle() {
- delete impl;
-}
-
-void PollerHandle::deferDelete() {
- PollerHandleDeletionManager.markForDeletion(this);
+ {
+ ScopedLock<Mutex> l(impl->lock);
+ if (impl->isDeleted()) {
+ return;
+ }
+ if (impl->isActive()) {
+ impl->setDeleted();
+ }
+ }
+ PollerHandleDeletionManager.markForDeletion(impl);
}
/**
@@ -125,35 +141,82 @@ void PollerHandle::deferDelete() {
class PollerPrivate {
friend class Poller;
- const int portId;
+ class InterruptHandle: public PollerHandle {
+ std::queue<PollerHandle*> handles;
+
+ void processEvent(Poller::EventType) {
+ PollerHandle* handle = handles.front();
+ handles.pop();
+ assert(handle);
+
+ //Synthesise event
+ Poller::Event event(handle, Poller::INTERRUPTED);
+
+ //Process synthesised event
+ event.process();
+ }
+ public:
+ InterruptHandle() : PollerHandle(DummyIOHandle) {}
+
+ void addHandle(PollerHandle& h) {
+ handles.push(&h);
+ }
+
+ PollerHandle *getHandle() {
+ PollerHandle* handle = handles.front();
+ handles.pop();
+ return handle;
+ }
+
+ bool queuedHandles() {
+ return handles.size() > 0;
+ }
+ };
+
+ const int portId;
+ bool isShutdown;
+ InterruptHandle interruptHandle;
+
static uint32_t directionToPollEvent(Poller::Direction dir) {
switch (dir) {
- case Poller::INPUT: return POLLIN;
- case Poller::OUTPUT: return POLLOUT;
- case Poller::INOUT: return POLLIN | POLLOUT;
- default: return 0;
+ case Poller::INPUT: return POLLIN;
+ case Poller::OUTPUT: return POLLOUT;
+ case Poller::INOUT: return POLLIN | POLLOUT;
+ default: return 0;
}
}
static Poller::EventType pollToDirection(uint32_t events) {
uint32_t e = events & (POLLIN | POLLOUT);
switch (e) {
- case POLLIN: return Poller::READABLE;
- case POLLOUT: return Poller::WRITABLE;
- case POLLIN | POLLOUT: return Poller::READ_WRITABLE;
- default:
- return (events & (POLLHUP | POLLERR)) ?
- Poller::DISCONNECTED : Poller::INVALID;
+ case POLLIN: return Poller::READABLE;
+ case POLLOUT: return Poller::WRITABLE;
+ case POLLIN | POLLOUT: return Poller::READ_WRITABLE;
+ default:
+ return (events & (POLLHUP | POLLERR)) ?
+ Poller::DISCONNECTED : Poller::INVALID;
}
}
-
+
PollerPrivate() :
- portId(::port_create()) {
+ portId(::port_create()),
+ isShutdown(false) {
+ QPID_POSIX_CHECK(portId);
+ QPID_LOG(trace, "port_create returned port Id: " << portId);
}
~PollerPrivate() {
}
+
+ void interrupt() {
+ //Send an Alarm to the port
+ //We need to send a nonzero event mask, using POLLHUP,
+ //nevertheless the wait method will only look for a PORT_ALERT_SET
+ QPID_LOG(trace, "Sending a port_alert to " << portId);
+ QPID_POSIX_CHECK(::port_alert(portId, PORT_ALERT_SET, POLLHUP,
+ &static_cast<PollerHandle&>(interruptHandle)));
+ }
};
void Poller::addFd(PollerHandle& handle, Direction dir) {
@@ -177,7 +240,6 @@ void Poller::addFd(PollerHandle& handle, Direction dir) {
QPID_LOG(trace, "Poller::addFd(handle=" << &handle
<< "[" << typeid(&handle).name()
<< "], fd=" << eh.fd << ")");
- //assert(dynamic_cast<DispatchHandle*>(&handle));
}
void Poller::delFd(PollerHandle& handle) {
@@ -223,17 +285,56 @@ void Poller::rearmFd(PollerHandle& handle) {
}
void Poller::shutdown() {
- //Send an Alarm to the port
- //We need to send a nonzero event mask, using POLLHUP, but
- //The wait method will only look for a PORT_ALERT_SET
- QPID_POSIX_CHECK(::port_alert(impl->portId, PORT_ALERT_SET, POLLHUP, NULL));
- QPID_LOG(trace, "Poller::shutdown");
+ //Allow sloppy code to shut us down more than once
+ if (impl->isShutdown)
+ return;
+
+ impl->isShutdown = true;
+ impl->interrupt();
+}
+
+bool Poller::interrupt(PollerHandle& handle) {
+ PollerPrivate::InterruptHandle& ih = impl->interruptHandle;
+ PollerHandlePrivate& eh = *static_cast<PollerHandle&>(ih).impl;
+ ScopedLock<Mutex> l(eh.lock);
+ ih.addHandle(handle);
+ impl->interrupt();
+ eh.setActive();
+ return true;
+}
+
+void Poller::run() {
+ // Make sure we can't be interrupted by signals at a bad time
+ ::sigset_t ss;
+ ::sigfillset(&ss);
+ ::pthread_sigmask(SIG_SETMASK, &ss, 0);
+
+ do {
+ Event event = wait();
+
+ // If can read/write then dispatch appropriate callbacks
+ if (event.handle) {
+ event.process();
+ } else {
+ // Handle shutdown
+ switch (event.type) {
+ case SHUTDOWN:
+ return;
+ default:
+ // This should be impossible
+ assert(false);
+ }
+ }
+ } while (true);
}
Poller::Event Poller::wait(Duration timeout) {
timespec_t tout;
timespec_t* ptout = NULL;
port_event_t pe;
+
+ AbsTime targetTimeout = (timeout == TIME_INFINITE) ? FAR_FUTURE :
+ AbsTime(now(), timeout);
if (timeout != TIME_INFINITE) {
tout.tv_sec = 0;
@@ -243,12 +344,21 @@ Poller::Event Poller::wait(Duration timeout) {
do {
PollerHandleDeletionManager.markAllUnusedInThisThread();
- QPID_LOG(trace, "About to enter port_get. Thread "
- << pthread_self()
+ QPID_LOG(trace, "About to enter port_get on " << impl->portId
+ << ". Thread " << pthread_self()
<< ", timeout=" << timeout);
-
+
+
int rc = ::port_get(impl->portId, &pe, ptout);
+ QPID_LOG(trace, "port_get on " << impl->portId
+ << " returned " << rc);
+
+ if (impl->isShutdown) {
+ PollerHandleDeletionManager.markAllUnusedInThisThread();
+ return Event(0, SHUTDOWN);
+ }
+
if (rc < 0) {
switch (errno) {
case EINTR:
@@ -259,33 +369,61 @@ Poller::Event Poller::wait(Duration timeout) {
QPID_POSIX_CHECK(rc);
}
} else {
- //We use alert mode to notify the shutdown of the Poller
- if (pe.portev_source == PORT_SOURCE_ALERT) {
- return Event(0, SHUTDOWN);
- }
- if (pe.portev_source == PORT_SOURCE_FD) {
- PollerHandle *handle = static_cast<PollerHandle*>(pe.portev_user);
- PollerHandlePrivate& eh = *handle->impl;
- ScopedLock<Mutex> l(eh.lock);
- QPID_LOG(trace, "About to send handle: " << handle);
+ PollerHandle* handle = static_cast<PollerHandle*>(pe.portev_user);
+ PollerHandlePrivate& eh = *handle->impl;
+ ScopedLock<Mutex> l(eh.lock);
+
+ if (eh.isActive()) {
+ QPID_LOG(trace, "Handle is active");
+ //We use alert mode to notify interrupts
+ if (pe.portev_source == PORT_SOURCE_ALERT &&
+ handle == &impl->interruptHandle) {
+ QPID_LOG(trace, "Interrupt notified");
+
+ PollerHandle* wrappedHandle = impl->interruptHandle.getHandle();
+
+ if (impl->interruptHandle.queuedHandles()) {
+ impl->interrupt();
+ eh.setActive();
+ } else {
+ eh.setInactive();
+ }
+ return Event(wrappedHandle, INTERRUPTED);
+ }
- if (eh.isActive()) {
- if (pe.portev_events & POLLHUP) {
- if (eh.isHungup()) {
- return Event(handle, DISCONNECTED);
+ if (pe.portev_source == PORT_SOURCE_FD) {
+ QPID_LOG(trace, "About to send handle: " << handle);
+ if (pe.portev_events & POLLHUP) {
+ if (eh.isHungup()) {
+ return Event(handle, DISCONNECTED);
+ }
+ eh.setHungup();
+ } else {
+ eh.setInactive();
}
- eh.setHungup();
- } else {
- eh.setInactive();
- }
- QPID_LOG(trace, "Sending event (thread: "
- << pthread_self() << ") for handle " << handle
- << ", direction= "
- << PollerPrivate::pollToDirection(pe.portev_events));
- return Event(handle, PollerPrivate::pollToDirection(pe.portev_events));
+ QPID_LOG(trace, "Sending event (thread: "
+ << pthread_self() << ") for handle " << handle
+ << ", direction= "
+ << PollerPrivate::pollToDirection(pe.portev_events));
+ return Event(handle, PollerPrivate::pollToDirection(pe.portev_events));
+ }
+ } else if (eh.isDeleted()) {
+ //Remove the handle from the poller
+ int rc = ::port_dissociate(impl->portId, PORT_SOURCE_FD,
+ (uintptr_t) eh.fd);
+ if (rc == -1 && errno != EBADFD) {
+ QPID_POSIX_CHECK(rc);
}
}
}
+
+ if (timeout == TIME_INFINITE) {
+ continue;
+ }
+ if (rc == 0 && now() > targetTimeout) {
+ PollerHandleDeletionManager.markAllUnusedInThisThread();
+ return Event(0, TIMEOUT);
+ }
} while (true);
}
diff --git a/qpid/cpp/src/qpid/sys/solaris/SystemInfo.cpp b/qpid/cpp/src/qpid/sys/solaris/SystemInfo.cpp
new file mode 100755
index 0000000000..0075a89021
--- /dev/null
+++ b/qpid/cpp/src/qpid/sys/solaris/SystemInfo.cpp
@@ -0,0 +1,123 @@
+/*
+ * 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.
+ *
+ */
+
+#include "qpid/sys/SystemInfo.h"
+
+#define BSD_COMP
+#include <sys/ioctl.h>
+#include <netdb.h>
+#undef BDS_COMP
+
+
+#include <unistd.h>
+#include <net/if.h>
+#include <sys/types.h>
+#include <sys/utsname.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <stdio.h>
+#include <errno.h>
+#include <limits.h>
+#include <procfs.h>
+#include <fcntl.h>
+#include <sys/types.h>
+
+using namespace std;
+
+namespace qpid {
+namespace sys {
+
+long SystemInfo::concurrency() {
+ return sysconf(_SC_NPROCESSORS_ONLN);
+}
+
+bool SystemInfo::getLocalHostname(TcpAddress &address) {
+ char name[MAXHOSTNAMELEN];
+ if (::gethostname(name, sizeof(name)) != 0)
+ return false;
+ address.host = name;
+ return true;
+}
+
+static const string LOCALHOST("127.0.0.1");
+
+void SystemInfo::getLocalIpAddresses(uint16_t port,
+ std::vector<Address> &addrList) {
+ int s = socket(PF_INET, SOCK_STREAM, 0);
+ for (int i=1;;i++) {
+ struct lifreq ifr;
+ ifr.lifr_index = i;
+ if (::ioctl(s, SIOCGIFADDR, &ifr) < 0) {
+ break;
+ }
+ struct sockaddr_in *sin = (struct sockaddr_in *) &ifr.lifr_addr;
+ std::string addr(inet_ntoa(sin->sin_addr));
+ if (addr != LOCALHOST)
+ addrList.push_back(TcpAddress(addr, port));
+ }
+ if (addrList.empty()) {
+ addrList.push_back(TcpAddress(LOCALHOST, port));
+ }
+ close (s);
+}
+
+void SystemInfo::getSystemId(std::string &osName,
+ std::string &nodeName,
+ std::string &release,
+ std::string &version,
+ std::string &machine) {
+ struct utsname _uname;
+ if (uname (&_uname) == 0) {
+ osName = _uname.sysname;
+ nodeName = _uname.nodename;
+ release = _uname.release;
+ version = _uname.version;
+ machine = _uname.machine;
+ }
+}
+
+uint32_t SystemInfo::getProcessId()
+{
+ return (uint32_t) ::getpid();
+}
+
+uint32_t SystemInfo::getParentProcessId()
+{
+ return (uint32_t) ::getppid();
+}
+
+string SystemInfo::getProcessName()
+{
+ psinfo processInfo;
+ char procfile[PATH_MAX];
+ int fd;
+ string value;
+
+ snprintf(procfile, PATH_MAX, "/proc/%d/psinfo", getProcessId());
+ if ((fd = open(procfile, O_RDONLY)) >= 0) {
+ if (read(fd, (void *) &processInfo, sizeof(processInfo)) == sizeof(processInfo)) {
+ value = processInfo.pr_fname;
+ }
+ }
+ return value;
+}
+
+}} // namespace qpid::sys
diff --git a/qpid/cpp/src/qpid/sys/ssl/SslIo.cpp b/qpid/cpp/src/qpid/sys/ssl/SslIo.cpp
index 9be75af47d..624683ae7d 100644
--- a/qpid/cpp/src/qpid/sys/ssl/SslIo.cpp
+++ b/qpid/cpp/src/qpid/sys/ssl/SslIo.cpp
@@ -90,7 +90,7 @@ void SslAcceptor::readable(DispatchHandle& h) {
// TODO: Currently we ignore the peers address, perhaps we should
// log it or use it for connection acceptance.
try {
- s = socket.accept(0, 0);
+ s = socket.accept();
if (s) {
acceptedCallback(*s);
} else {
diff --git a/qpid/cpp/src/qpid/sys/ssl/SslSocket.cpp b/qpid/cpp/src/qpid/sys/ssl/SslSocket.cpp
index 597fbe57db..dc816b403b 100644
--- a/qpid/cpp/src/qpid/sys/ssl/SslSocket.cpp
+++ b/qpid/cpp/src/qpid/sys/ssl/SslSocket.cpp
@@ -201,9 +201,9 @@ int SslSocket::listen(uint16_t port, int backlog, const std::string& certName, b
return ntohs(name.sin_port);
}
-SslSocket* SslSocket::accept(struct sockaddr *addr, socklen_t *addrlen) const
+SslSocket* SslSocket::accept() const
{
- int afd = ::accept(impl->fd, addr, addrlen);
+ int afd = ::accept(impl->fd, 0, 0);
if ( afd >= 0) {
return new SslSocket(new IOHandlePrivate(afd), prototype);
} else if (errno == EAGAIN) {
diff --git a/qpid/cpp/src/qpid/sys/ssl/SslSocket.h b/qpid/cpp/src/qpid/sys/ssl/SslSocket.h
index a82e9133e8..7434667b78 100644
--- a/qpid/cpp/src/qpid/sys/ssl/SslSocket.h
+++ b/qpid/cpp/src/qpid/sys/ssl/SslSocket.h
@@ -64,7 +64,7 @@ public:
* Accept a connection from a socket that is already listening
* and has an incoming connection
*/
- SslSocket* accept(struct sockaddr *addr, socklen_t *addrlen) const;
+ SslSocket* accept() const;
// TODO The following are raw operations, maybe they need better wrapping?
int read(void *buf, size_t count) const;
diff --git a/qpid/cpp/src/qpid/sys/windows/AsynchIO.cpp b/qpid/cpp/src/qpid/sys/windows/AsynchIO.cpp
index 37d87947a2..0a3c36452c 100644
--- a/qpid/cpp/src/qpid/sys/windows/AsynchIO.cpp
+++ b/qpid/cpp/src/qpid/sys/windows/AsynchIO.cpp
@@ -690,10 +690,9 @@ void AsynchIO::writeComplete(AsynchWriteResult *result) {
}
}
- // If there are no writes outstanding, the priority is to write any
- // remaining buffers first (either queued or via idle), then close the
- // socket if that's queued.
- // opsInProgress handled in completion()
+ // If there are no writes outstanding, check for more writes to initiate
+ // (either queued or via idle). The opsInProgress count is handled in
+ // completion()
if (!writeInProgress) {
bool writing = false;
{
@@ -706,11 +705,8 @@ void AsynchIO::writeComplete(AsynchWriteResult *result) {
writing = true;
}
}
- if (!writing) {
- if (queuedClose)
- close();
- else
- notifyIdle();
+ if (!writing && !queuedClose) {
+ notifyIdle();
}
}
return;
@@ -757,9 +753,11 @@ void AsynchIO::completion(AsynchIoResult *result) {
}
working = false;
}
- // Lock released; ok to delete if all is done.
- if (opsInProgress == 0 && queuedDelete)
- delete this;
+ // Lock released; ok to close if ops are done and close requested.
+ // Layer above will call back to queueForDeletion()
+ if (opsInProgress == 0 && queuedClose) {
+ close();
+ }
}
} // namespace windows
diff --git a/qpid/cpp/src/qpid/sys/windows/IntegerTypes.h b/qpid/cpp/src/qpid/sys/windows/IntegerTypes.h
index 80168fab88..47b1d16a76 100755
--- a/qpid/cpp/src/qpid/sys/windows/IntegerTypes.h
+++ b/qpid/cpp/src/qpid/sys/windows/IntegerTypes.h
@@ -32,8 +32,6 @@ typedef __int64 int64_t;
// Visual Studio doesn't define other common types, so set them up here too.
typedef int pid_t;
-typedef int socklen_t;
-typedef unsigned int size_t;
typedef int ssize_t;
typedef unsigned int uint;
diff --git a/qpid/cpp/src/qpid/sys/windows/PollableCondition.cpp b/qpid/cpp/src/qpid/sys/windows/PollableCondition.cpp
new file mode 100644
index 0000000000..ed0f7c3917
--- /dev/null
+++ b/qpid/cpp/src/qpid/sys/windows/PollableCondition.cpp
@@ -0,0 +1,125 @@
+#ifndef QPID_SYS_WINDOWS_POLLABLECONDITION_CPP
+#define QPID_SYS_WINDOWS_POLLABLECONDITION_CPP
+
+/*
+ *
+ * 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.
+ *
+ */
+
+#include "qpid/sys/PollableCondition.h"
+#include "qpid/sys/IOHandle.h"
+#include "AsynchIoResult.h"
+#include "IoHandlePrivate.h"
+
+#include <boost/bind.hpp>
+#include <windows.h>
+
+namespace qpid {
+namespace sys {
+
+// PollableConditionPrivate will reuse the IocpPoller's ability to queue
+// a completion to the IOCP and have it dispatched to the completer callback
+// noted in the IOHandlePrivate when the request is queued. The
+// AsynchCallbackRequest object is not really used - we already have the
+// desired callback for the user of PollableCondition.
+class PollableConditionPrivate : private IOHandle {
+ friend class PollableCondition;
+
+private:
+ PollableConditionPrivate(const sys::PollableCondition::Callback& cb,
+ sys::PollableCondition& parent,
+ const boost::shared_ptr<sys::Poller>& poller);
+ ~PollableConditionPrivate();
+
+ void poke();
+ void dispatch(AsynchIoResult *result);
+
+private:
+ PollableCondition::Callback cb;
+ PollableCondition& parent;
+ boost::shared_ptr<sys::Poller> poller;
+ LONG isSet;
+ LONG armed;
+};
+
+PollableConditionPrivate::PollableConditionPrivate(const sys::PollableCondition::Callback& cb,
+ sys::PollableCondition& parent,
+ const boost::shared_ptr<sys::Poller>& poller)
+ : IOHandle(new sys::IOHandlePrivate(INVALID_SOCKET,
+ boost::bind(&PollableConditionPrivate::dispatch, this, _1))),
+ cb(cb), parent(parent), poller(poller), isSet(0), armed(0)
+{
+}
+
+PollableConditionPrivate::~PollableConditionPrivate()
+{
+}
+
+void PollableConditionPrivate::poke()
+{
+ if (!armed)
+ return;
+
+ // addFd will queue a completion for the IOCP; when it's handled, a
+ // poller thread will call back to dispatch() below.
+ PollerHandle ph(*this);
+ poller->addFd(ph, Poller::INPUT);
+}
+
+void PollableConditionPrivate::dispatch(AsynchIoResult *result)
+{
+ delete result; // Poller::addFd() allocates this
+ cb(parent);
+}
+
+ /* PollableCondition */
+
+PollableCondition::PollableCondition(const Callback& cb,
+ const boost::shared_ptr<sys::Poller>& poller)
+ : impl(new PollableConditionPrivate(cb, *this, poller))
+{
+}
+
+PollableCondition::~PollableCondition()
+{
+ delete impl;
+}
+
+void PollableCondition::set() {
+ // Add one to the set count and poke it to provoke a callback
+ ::InterlockedIncrement(&impl->isSet);
+ impl->poke();
+}
+
+bool PollableCondition::clear() {
+ return (0 != ::InterlockedExchange(&impl->isSet, 0));
+}
+
+void PollableCondition::disarm() {
+ ::InterlockedExchange(&impl->armed, 0);
+}
+
+void PollableCondition::rearm() {
+ if (0 == ::InterlockedExchange(&impl->armed, 1) && impl->isSet)
+ impl->poke();
+}
+
+}} // namespace qpid::sys
+
+#endif /*!QPID_SYS_WINDOWS_POLLABLECONDITION_CPP*/
diff --git a/qpid/cpp/src/qpid/sys/windows/Socket.cpp b/qpid/cpp/src/qpid/sys/windows/Socket.cpp
index a9959bf43e..93059d03ef 100755
--- a/qpid/cpp/src/qpid/sys/windows/Socket.cpp
+++ b/qpid/cpp/src/qpid/sys/windows/Socket.cpp
@@ -262,9 +262,9 @@ int Socket::listen(uint16_t port, int backlog) const
return ntohs(name.sin_port);
}
-Socket* Socket::accept(struct sockaddr *addr, socklen_t *addrlen) const
+Socket* Socket::accept() const
{
- SOCKET afd = ::accept(impl->fd, addr, addrlen);
+ SOCKET afd = ::accept(impl->fd, 0, 0);
if (afd != INVALID_SOCKET)
return new Socket(new IOHandlePrivate(afd));
else if (WSAGetLastError() == EAGAIN)
diff --git a/qpid/cpp/src/qpid/sys/windows/SystemInfo.cpp b/qpid/cpp/src/qpid/sys/windows/SystemInfo.cpp
index b887cac58b..3e2fcb1517 100755
--- a/qpid/cpp/src/qpid/sys/windows/SystemInfo.cpp
+++ b/qpid/cpp/src/qpid/sys/windows/SystemInfo.cpp
@@ -29,6 +29,7 @@
#include <winsock2.h>
#include <ws2tcpip.h>
#include <windows.h>
+#include <tlhelp32.h>
#ifndef HOST_NAME_MAX
# define HOST_NAME_MAX 256
@@ -157,4 +158,41 @@ void SystemInfo::getSystemId (std::string &osName,
}
}
+uint32_t SystemInfo::getProcessId()
+{
+ return static_cast<uint32_t>(::GetCurrentProcessId());
+}
+
+uint32_t SystemInfo::getParentProcessId()
+{
+ // Only want info for the current process, so ask for something specific.
+ // The module info won't be used here but it keeps the snapshot limited to
+ // the current process so a search through all processes is not needed.
+ HANDLE snap = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, 0);
+ if (snap == INVALID_HANDLE_VALUE)
+ return 0;
+ PROCESSENTRY32 entry;
+ entry.dwSize = sizeof(entry);
+ if (!Process32First(snap, &entry))
+ entry.th32ParentProcessID = 0;
+ CloseHandle(snap);
+ return static_cast<uint32_t>(entry.th32ParentProcessID);
+}
+
+std::string SystemInfo::getProcessName()
+{
+ // Only want info for the current process, so ask for something specific.
+ // The module info won't be used here but it keeps the snapshot limited to
+ // the current process so a search through all processes is not needed.
+ HANDLE snap = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, 0);
+ if (snap == INVALID_HANDLE_VALUE)
+ return 0;
+ PROCESSENTRY32 entry;
+ entry.dwSize = sizeof(entry);
+ if (!Process32First(snap, &entry))
+ entry.szExeFile[0] = '\0';
+ CloseHandle(snap);
+ return std::string(entry.szExeFile);
+}
+
}} // namespace qpid::sys
diff --git a/qpid/cpp/src/qpid/sys/windows/uuid.h b/qpid/cpp/src/qpid/sys/windows/uuid.h
index a44ef2e9a3..7d003c3739 100644
--- a/qpid/cpp/src/qpid/sys/windows/uuid.h
+++ b/qpid/cpp/src/qpid/sys/windows/uuid.h
@@ -23,6 +23,7 @@
*/
#include <Rpc.h>
+#include "qpid/CommonImportExport.h"
#ifdef uuid_t /* Done in rpcdce.h */
# undef uuid_t
@@ -31,11 +32,11 @@
namespace qpid { namespace sys { const size_t UuidSize = 16; }}
typedef uint8_t uuid_t[qpid::sys::UuidSize];
-void uuid_clear (uuid_t uu);
-void uuid_copy (uuid_t dst, const uuid_t src);
-void uuid_generate (uuid_t out);
-int uuid_is_null (const uuid_t uu); // Returns 1 if null, else 0
-int uuid_parse (const char *in, uuid_t uu); // Returns 0 on success, else -1
-void uuid_unparse (const uuid_t uu, char *out);
+QPID_COMMON_EXTERN void uuid_clear (uuid_t uu);
+QPID_COMMON_EXTERN void uuid_copy (uuid_t dst, const uuid_t src);
+QPID_COMMON_EXTERN void uuid_generate (uuid_t out);
+QPID_COMMON_EXTERN int uuid_is_null (const uuid_t uu); // Returns 1 if null, else 0
+QPID_COMMON_EXTERN int uuid_parse (const char *in, uuid_t uu); // Returns 0 on success, else -1
+QPID_COMMON_EXTERN void uuid_unparse (const uuid_t uu, char *out);
#endif /*!_sys_windows_uuid_h*/
diff --git a/qpid/cpp/src/qpid/xml/XmlExchange.cpp b/qpid/cpp/src/qpid/xml/XmlExchange.cpp
index 5197b239d0..4e9de49ad5 100644
--- a/qpid/cpp/src/qpid/xml/XmlExchange.cpp
+++ b/qpid/cpp/src/qpid/xml/XmlExchange.cpp
@@ -33,6 +33,9 @@
#include "qpid/Plugin.h"
#include <xercesc/framework/MemBufInputSource.hpp>
+
+#include <xqilla/ast/XQGlobalVariable.hpp>
+
#include <xqilla/context/ItemFactory.hpp>
#include <xqilla/xqilla-simple.hpp>
@@ -62,17 +65,6 @@ XmlExchange::XmlExchange(const std::string& _name, bool _durable,
mgmtExchange->set_type (typeName);
}
-/*
- * Use the name of the query as the binding key.
- *
- * The first time a given name is used in a binding, the query body
- * must be provided.After that, no query body should be present.
- *
- * To modify an installed query, the user must first unbind the
- * existing query, then replace it by binding again with the same
- * name.
- *
- */
// #### TODO: The Binding should take the query text
// #### only. Consider encapsulating the entire block, including
@@ -94,6 +86,21 @@ bool XmlExchange::bind(Queue::shared_ptr queue, const string& routingKey, const
bindings.add(binding);
QPID_LOG(trace, "Bound successfully with query: " << queryText );
+ binding->parse_message_content = false;
+
+ if (query->getQueryBody()->getStaticAnalysis().areContextFlagsUsed()) {
+ binding->parse_message_content = true;
+ }
+ else {
+ GlobalVariables &vars = const_cast<GlobalVariables&>(query->getVariables());
+ for(GlobalVariables::iterator it = vars.begin(); it != vars.end(); ++it) {
+ if ((*it)->getStaticAnalysis().areContextFlagsUsed()) {
+ binding->parse_message_content = true;
+ break;
+ }
+ }
+ }
+
if (mgmtExchange != 0) {
mgmtExchange->inc_bindingCount();
((_qmf::Queue*) queue->GetManagementObject())->inc_bindingCount();
@@ -126,59 +133,74 @@ bool XmlExchange::unbind(Queue::shared_ptr queue, const string& routingKey, cons
}
}
-bool XmlExchange::matches(Query& query, Deliverable& msg, const qpid::framing::FieldTable* args)
+bool XmlExchange::matches(Query& query, Deliverable& msg, const qpid::framing::FieldTable* args, bool parse_message_content)
{
- // ### TODO: Need istream for frameset
- // Hack alert - the following code does not work for really large messages
-
string msgContent;
try {
- msg.getMessage().getFrames().getContent(msgContent);
-
- QPID_LOG(trace, "matches: query is [" << UTF8(query->getQueryText()) << "]");
- QPID_LOG(trace, "matches: message content is [" << msgContent << "]");
-
- boost::scoped_ptr<DynamicContext> context(query->createDynamicContext());
- if (!context.get()) {
- throw InternalErrorException(QPID_MSG("Query context looks munged ..."));
- }
-
- XERCES_CPP_NAMESPACE::MemBufInputSource xml((const XMLByte*) msgContent.c_str(),
- msgContent.length(), "input" );
- Sequence seq(context->parseDocument(xml));
-
- if (args) {
- FieldTable::ValueMap::const_iterator v = args->begin();
- for(; v != args->end(); ++v) {
- // ### TODO: Do types properly
- if (v->second->convertsTo<std::string>()) {
- QPID_LOG(trace, "XmlExchange, external variable: " << v->first << " = " << v->second->getData().getString().c_str());
- Item::Ptr value = context->getItemFactory()->createString(X(v->second->getData().getString().c_str()), context.get());
- context->setExternalVariable(X(v->first.c_str()), value);
- }
- }
- }
-
- if(!seq.isEmpty() && seq.first()->isNode()) {
- context->setContextItem(seq.first());
- context->setContextPosition(1);
- context->setContextSize(1);
- }
- Result result = query->execute(context.get());
- return result->getEffectiveBooleanValue(context.get(), 0);
+ QPID_LOG(trace, "matches: query is [" << UTF8(query->getQueryText()) << "]");
+
+ boost::scoped_ptr<DynamicContext> context(query->createDynamicContext());
+ if (!context.get()) {
+ throw InternalErrorException(QPID_MSG("Query context looks munged ..."));
+ }
+
+ if (parse_message_content) {
+
+ msg.getMessage().getFrames().getContent(msgContent);
+
+ QPID_LOG(trace, "matches: message content is [" << msgContent << "]");
+
+ XERCES_CPP_NAMESPACE::MemBufInputSource xml((const XMLByte*) msgContent.c_str(),
+ msgContent.length(), "input" );
+
+ // This will parse the document using either Xerces or FastXDM, depending
+ // on your XQilla configuration. FastXDM can be as much as 10x faster.
+
+ Sequence seq(context->parseDocument(xml));
+
+ if(!seq.isEmpty() && seq.first()->isNode()) {
+ context->setContextItem(seq.first());
+ context->setContextPosition(1);
+ context->setContextSize(1);
+ }
+ }
+
+ if (args) {
+ FieldTable::ValueMap::const_iterator v = args->begin();
+ for(; v != args->end(); ++v) {
+ // ### TODO: Do types properly
+ if (v->second->convertsTo<std::string>()) {
+ QPID_LOG(trace, "XmlExchange, external variable: " << v->first << " = " << v->second->getData().getString().c_str());
+ Item::Ptr value = context->getItemFactory()->createString(X(v->second->getData().getString().c_str()), context.get());
+ context->setExternalVariable(X(v->first.c_str()), value);
+ }
+ }
+ }
+
+ Result result = query->execute(context.get());
+ return result->getEffectiveBooleanValue(context.get(), 0);
}
catch (XQException& e) {
- QPID_LOG(warning, "Could not parse XML content (or message headers):" << msgContent);
- return 0;
+ QPID_LOG(warning, "Could not parse XML content (or message headers):" << msgContent);
}
catch (...) {
- QPID_LOG(warning, "Unexpected error routing message: " << msgContent);
- return 0;
+ QPID_LOG(warning, "Unexpected error routing message: " << msgContent);
}
return 0;
}
+// Future optimization: If any query in a binding for a given routing key requires
+// message content, parse the message once, and use that parsed form for all bindings.
+//
+// Future optimization: XQilla does not currently do document projection for data
+// accessed via the context item. If there is a single query for a given routing key,
+// and it accesses document data, this could be a big win.
+//
+// Document projection often is not a win if you have multiple queries on the same data.
+// But for very large messages, if all these queries are on the first part of the data,
+// it could still be a big win.
+
void XmlExchange::route(Deliverable& msg, const string& routingKey, const FieldTable* args)
{
PreRoute pr(msg, this);
@@ -192,7 +214,7 @@ void XmlExchange::route(Deliverable& msg, const string& routingKey, const FieldT
int count(0);
for (std::vector<XmlBinding::shared_ptr>::const_iterator i = p->begin(); i != p->end(); i++) {
- if ((*i)->xquery && matches((*i)->xquery, msg, args)) { // Overly defensive? There should always be a query ...
+ if (matches((*i)->xquery, msg, args, (*i)->parse_message_content)) {
msg.deliverTo((*i)->queue);
count++;
QPID_LOG(trace, "Delivered to queue" );
diff --git a/qpid/cpp/src/qpid/xml/XmlExchange.h b/qpid/cpp/src/qpid/xml/XmlExchange.h
index 066a26489d..7bec480bde 100644
--- a/qpid/cpp/src/qpid/xml/XmlExchange.h
+++ b/qpid/cpp/src/qpid/xml/XmlExchange.h
@@ -46,9 +46,10 @@ class XmlExchange : public virtual Exchange {
typedef qpid::sys::CopyOnWriteArray<XmlBinding::shared_ptr> vector;
boost::shared_ptr<XQQuery> xquery;
+ bool parse_message_content;
XmlBinding(const std::string& key, const Queue::shared_ptr queue, Exchange* parent, Query query):
- Binding(key, queue, parent), xquery(query) {}
+ Binding(key, queue, parent), xquery(query), parse_message_content(true) {}
};
@@ -58,7 +59,7 @@ class XmlExchange : public virtual Exchange {
XQilla xqilla;
qpid::sys::RWlock lock;
- bool matches(Query& query, Deliverable& msg, const qpid::framing::FieldTable* args);
+ bool matches(Query& query, Deliverable& msg, const qpid::framing::FieldTable* args, bool parse_message_content);
public:
static const std::string typeName;
diff --git a/qpid/cpp/src/replication.mk b/qpid/cpp/src/replication.mk
index 6830f99d36..c65a7ae3b9 100644
--- a/qpid/cpp/src/replication.mk
+++ b/qpid/cpp/src/replication.mk
@@ -29,6 +29,9 @@ replicating_listener_la_SOURCES = \
qpid/replication/ReplicatingEventListener.h
replicating_listener_la_LIBADD = libqpidbroker.la
+if SUNOS
+ replicating_listener_la_LIBADD += libqpidcommon.la -lboost_program_options -luuid $(SUNCC_RUNTIME_LIBS)
+endif
replicating_listener_la_LDFLAGS = $(PLUGINLDFLAGS)
@@ -43,4 +46,7 @@ replication_exchange_la_SOURCES = \
replication_exchange_la_LIBADD = libqpidbroker.la
+if SUNOS
+ replication_exchange_la_LIBADD += libqpidcommon.la -lboost_program_options -lCrun -luuid
+endif
replication_exchange_la_LDFLAGS = $(PLUGINLDFLAGS)
diff --git a/qpid/cpp/src/tests/ClientSessionTest.cpp b/qpid/cpp/src/tests/ClientSessionTest.cpp
index 1658f3d4ec..589e1154e1 100644
--- a/qpid/cpp/src/tests/ClientSessionTest.cpp
+++ b/qpid/cpp/src/tests/ClientSessionTest.cpp
@@ -428,8 +428,8 @@ QPID_AUTO_TEST_CASE(testConcurrentSenders)
for (size_t i = 0; i < 5; i++) {
publishers.push_back(new Publisher(connection, message, 100));
}
- for_each(publishers.begin(), publishers.end(), boost::bind(&Publisher::start, _1));
- for_each(publishers.begin(), publishers.end(), boost::bind(&Publisher::join, _1));
+ std::for_each(publishers.begin(), publishers.end(), boost::bind(&Publisher::start, _1));
+ std::for_each(publishers.begin(), publishers.end(), boost::bind(&Publisher::join, _1));
connection.close();
}
@@ -564,6 +564,24 @@ QPID_AUTO_TEST_CASE(testSessionManagerSetFlowControl) {
BOOST_CHECK_EQUAL("my-message", got.getData());
}
+QPID_AUTO_TEST_CASE(testGetThenSubscribe) {
+ ClientSessionFixture fix;
+ std::string name("myqueue");
+ fix.session.queueDeclare(arg::queue=name, arg::exclusive=true, arg::autoDelete=true);
+ fix.session.messageTransfer(arg::content=Message("one", name));
+ fix.session.messageTransfer(arg::content=Message("two", name));
+ Message got;
+ BOOST_CHECK(fix.subs.get(got, name));
+ BOOST_CHECK_EQUAL("one", got.getData());
+
+ DummyListener listener(fix.session, name, 1);
+ listener.run();
+ BOOST_CHECK_EQUAL(1u, listener.messages.size());
+ if (!listener.messages.empty()) {
+ BOOST_CHECK_EQUAL("two", listener.messages[0].getData());
+ }
+}
+
QPID_AUTO_TEST_SUITE_END()
diff --git a/qpid/cpp/src/tests/ClusterFixture.cpp b/qpid/cpp/src/tests/ClusterFixture.cpp
index 3a0ea74098..5658957b48 100644
--- a/qpid/cpp/src/tests/ClusterFixture.cpp
+++ b/qpid/cpp/src/tests/ClusterFixture.cpp
@@ -109,7 +109,7 @@ void ClusterFixture::addLocal() {
Args args(makeArgs(prefix));
vector<const char*> argv(args.size());
transform(args.begin(), args.end(), argv.begin(), boost::bind(&string::c_str, _1));
- qpid::log::Logger::instance().setPrefix(os.str());
+ qpid::log::Logger::instance().setPrefix(prefix);
localBroker.reset(new BrokerFixture(parseOpts(argv.size(), &argv[0])));
push_back(localBroker->getPort());
forkedBrokers.push_back(shared_ptr<ForkedBroker>());
diff --git a/qpid/cpp/src/tests/DispatcherTest.cpp b/qpid/cpp/src/tests/DispatcherTest.cpp
index c2f6bca12a..c619a36438 100644
--- a/qpid/cpp/src/tests/DispatcherTest.cpp
+++ b/qpid/cpp/src/tests/DispatcherTest.cpp
@@ -78,9 +78,6 @@ void reader(DispatchHandle& h, int fd) {
h.rewatch();
}
-DispatchHandle* rh = 0;
-DispatchHandle* wh = 0;
-
void rInterrupt(DispatchHandle&) {
cerr << "R";
}
@@ -92,9 +89,27 @@ void wInterrupt(DispatchHandle&) {
DispatchHandle::Callback rcb = rInterrupt;
DispatchHandle::Callback wcb = wInterrupt;
+DispatchHandleRef *volatile rh = 0;
+DispatchHandleRef *volatile wh = 0;
+
+volatile bool stopWait = false;
+volatile bool phase1finished = false;
+
+timer_t timer;
+
+void stop_handler(int /*signo*/, siginfo_t* /*info*/, void* /*context*/) {
+ stopWait = true;
+}
+
void timer_handler(int /*signo*/, siginfo_t* /*info*/, void* /*context*/) {
- rh->call(rcb);
- wh->call(wcb);
+ static int count = 0;
+ if (count++ < 10) {
+ rh->call(rcb);
+ wh->call(wcb);
+ } else {
+ phase1finished = true;
+ assert(::timer_delete(timer) == 0);
+ }
}
int main(int /*argc*/, char** /*argv*/)
@@ -114,7 +129,7 @@ int main(int /*argc*/, char** /*argv*/)
// Setup sender and receiver
int sv[2];
- int rc = ::socketpair(AF_LOCAL, SOCK_STREAM, 0, sv);
+ int rc = ::socketpair(AF_UNIX, SOCK_STREAM, 0, sv);
assert(rc >= 0);
// Set non-blocking
@@ -132,8 +147,8 @@ int main(int /*argc*/, char** /*argv*/)
PosixIOHandle f0(sv[0]);
PosixIOHandle f1(sv[1]);
- rh = new DispatchHandle(f0, boost::bind(reader, _1, sv[0]), 0, 0);
- wh = new DispatchHandle(f1, 0, boost::bind(writer, _1, sv[1], testString), 0);
+ rh = new DispatchHandleRef(f0, boost::bind(reader, _1, sv[0]), 0, 0);
+ wh = new DispatchHandleRef(f1, 0, boost::bind(writer, _1, sv[1], testString), 0);
rh->startWatch(poller);
wh->startWatch(poller);
@@ -155,10 +170,9 @@ int main(int /*argc*/, char** /*argv*/)
assert(rc == 0);
::sigevent se;
+ ::memset(&se, 0, sizeof(se)); // Clear to make valgrind happy (this *is* the neatest way to do this portably - sigh)
se.sigev_notify = SIGEV_SIGNAL;
se.sigev_signo = SIGRTMIN;
- se.sigev_value.sival_ptr = 0;
- timer_t timer;
rc = ::timer_create(CLOCK_REALTIME, &se, &timer);
assert(rc == 0);
@@ -169,11 +183,52 @@ int main(int /*argc*/, char** /*argv*/)
rc = ::timer_settime(timer, 0, &ts, 0);
assert(rc == 0);
- // wait 2 minutes then shutdown
- ::sleep(60);
+ // wait
+ while (!phase1finished) {
+ ::sleep(1);
+ }
+
+ // Now test deleting/creating DispatchHandles in tight loop, so that we are likely to still be using the
+ // attached PollerHandles after deleting the DispatchHandle
+ DispatchHandleRef* t = wh;
+ wh = 0;
+ delete t;
+ t = rh;
+ rh = 0;
+ delete t;
+
+ sa.sa_sigaction = stop_handler;
+ rc = ::sigaction(SIGRTMIN, &sa,0);
+ assert(rc == 0);
+
+ itimerspec nts = {
+ /*.it_value = */ {30, 0}, // s, ns
+ /*.it_interval = */ {30, 0}}; // s, ns
+
+ rc = ::timer_create(CLOCK_REALTIME, &se, &timer);
+ assert(rc == 0);
+ rc = ::timer_settime(timer, 0, &nts, 0);
+ assert(rc == 0);
+
+ DispatchHandleRef* rh1;
+ DispatchHandleRef* wh1;
+
+ struct timespec w = {0, 1000000};
+ while (!stopWait) {
+ rh1 = new DispatchHandleRef(f0, boost::bind(reader, _1, sv[0]), 0, 0);
+ wh1 = new DispatchHandleRef(f1, 0, boost::bind(writer, _1, sv[1], testString), 0);
+ rh1->startWatch(poller);
+ wh1->startWatch(poller);
+
+ ::nanosleep(&w, 0);
+
+ delete wh1;
+ delete rh1;
+ }
rc = ::timer_delete(timer);
assert(rc == 0);
+
poller->shutdown();
dt.join();
dt1.join();
diff --git a/qpid/cpp/src/tests/FieldTable.cpp b/qpid/cpp/src/tests/FieldTable.cpp
index 6b364723cf..9f2fd45b73 100644
--- a/qpid/cpp/src/tests/FieldTable.cpp
+++ b/qpid/cpp/src/tests/FieldTable.cpp
@@ -22,7 +22,7 @@
#include "qpid/framing/Array.h"
#include "qpid/framing/FieldTable.h"
#include "qpid/framing/FieldValue.h"
-#include <alloca.h>
+#include "qpid/sys/alloca.h"
#include "unit_test.h"
diff --git a/qpid/cpp/src/tests/ForkedBroker.cpp b/qpid/cpp/src/tests/ForkedBroker.cpp
index 2b90068549..f90f76aeb2 100644
--- a/qpid/cpp/src/tests/ForkedBroker.cpp
+++ b/qpid/cpp/src/tests/ForkedBroker.cpp
@@ -22,6 +22,9 @@
#include "ForkedBroker.h"
#include <boost/bind.hpp>
#include <algorithm>
+#include <stdlib.h>
+#include <sys/types.h>
+#include <signal.h>
ForkedBroker::ForkedBroker(const Args& args) { init(args); }
@@ -41,9 +44,9 @@ void ForkedBroker::kill(int sig) {
if (::kill(savePid, sig) < 0)
throw ErrnoException("kill failed");
int status;
- if (::waitpid(savePid, &status, 0) < 0)
+ if (::waitpid(savePid, &status, 0) < 0 && sig != 9)
throw ErrnoException("wait for forked process failed");
- if (WEXITSTATUS(status) != 0)
+ if (WEXITSTATUS(status) != 0 && sig != 9)
throw qpid::Exception(QPID_MSG("Forked broker exited with: " << WEXITSTATUS(status)));
}
diff --git a/qpid/cpp/src/tests/FrameDecoder.cpp b/qpid/cpp/src/tests/FrameDecoder.cpp
new file mode 100644
index 0000000000..f5db66d5fe
--- /dev/null
+++ b/qpid/cpp/src/tests/FrameDecoder.cpp
@@ -0,0 +1,73 @@
+/*
+ *
+ * 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.
+ *
+ */
+
+#include "unit_test.h"
+#include "qpid/framing/AMQFrame.h"
+#include "qpid/framing/FrameDecoder.h"
+#include "qpid/framing/AMQContentBody.h"
+#include "qpid/framing/Buffer.h"
+#include <string>
+
+
+QPID_AUTO_TEST_SUITE(FrameDecoderTest)
+
+using namespace std;
+using namespace qpid::framing;
+
+
+string makeData(int size) {
+ string data;
+ data.resize(size);
+ for (int i =0; i < size; ++i)
+ data[i] = 'a' + (i%26);
+ return data;
+}
+string encodeFrame(string data) {
+ AMQFrame f((AMQContentBody(data)));
+ string encoded;
+ encoded.resize(f.encodedSize());
+ Buffer b(&encoded[0], encoded.size());
+ f.encode(b);
+ return encoded;
+}
+
+string getData(const AMQFrame& frame) {
+ const AMQContentBody* content = dynamic_cast<const AMQContentBody*>(frame.getBody());
+ BOOST_CHECK(content);
+ return content->getData();
+}
+
+QPID_AUTO_TEST_CASE(testByteFragments) {
+ string data = makeData(42);
+ string encoded = encodeFrame(data);
+ FrameDecoder decoder;
+ for (size_t i = 0; i < encoded.size()-1; ++i) {
+ Buffer buf(&encoded[i], 1);
+ BOOST_CHECK(!decoder.decode(buf));
+ }
+ Buffer buf(&encoded[encoded.size()-1], 1);
+ BOOST_CHECK(decoder.decode(buf));
+ BOOST_CHECK_EQUAL(data, getData(decoder.getFrame()));
+}
+
+
+
+QPID_AUTO_TEST_SUITE_END()
diff --git a/qpid/cpp/src/tests/Makefile.am b/qpid/cpp/src/tests/Makefile.am
index 9da85eaad4..9a81ef18b3 100644
--- a/qpid/cpp/src/tests/Makefile.am
+++ b/qpid/cpp/src/tests/Makefile.am
@@ -94,7 +94,9 @@ unit_test_SOURCES= unit_test.cpp unit_test.h \
QueueEvents.cpp \
ProxyTest.cpp \
RetryList.cpp \
- RateFlowcontrolTest.cpp
+ RateFlowcontrolTest.cpp \
+ FrameDecoder.cpp \
+ ReplicationTest.cpp
if HAVE_XML
unit_test_SOURCES+= XmlClientSessionTest.cpp
@@ -163,7 +165,7 @@ header_test_LDADD=$(lib_client)
check_PROGRAMS+=failover_soak
failover_soak_SOURCES=failover_soak.cpp ForkedBroker.h ForkedBroker.cpp
-failover_soak_LDADD=$(lib_client)
+failover_soak_LDADD=$(lib_client) $(lib_broker)
check_PROGRAMS+=declare_queues
declare_queues_SOURCES=declare_queues.cpp
@@ -195,11 +197,11 @@ sender_LDADD=$(lib_client)
check_PROGRAMS+=PollerTest
PollerTest_SOURCES=PollerTest.cpp
-PollerTest_LDADD=$(lib_common)
+PollerTest_LDADD=$(lib_common) $(SOCKLIBS)
check_PROGRAMS+=DispatcherTest
DispatcherTest_SOURCES=DispatcherTest.cpp
-DispatcherTest_LDADD=$(lib_common)
+DispatcherTest_LDADD=$(lib_common) $(SOCKLIBS)
TESTS_ENVIRONMENT = VALGRIND=$(VALGRIND) srcdir=$(srcdir) QPID_DATA_DIR= BOOST_TEST_SHOW_PROGRESS=yes $(srcdir)/run_test
@@ -255,9 +257,11 @@ CLEANFILES+=valgrind.out *.log *.vglog* dummy_test $(unit_wrappers)
# Longer running stability tests, not run by default check: target.
# Not run under valgrind, too slow
-LONG_TESTS+=start_broker fanout_perftest shared_perftest multiq_perftest topic_perftest run_failover_soak stop_broker reliable_replication_test
+LONG_TESTS+=start_broker fanout_perftest shared_perftest multiq_perftest topic_perftest run_failover_soak stop_broker \
+ reliable_replication_test federated_cluster_test_with_node_failure
-EXTRA_DIST+=fanout_perftest shared_perftest multiq_perftest topic_perftest run_failover_soak reliable_replication_test
+EXTRA_DIST+=fanout_perftest shared_perftest multiq_perftest topic_perftest run_failover_soak reliable_replication_test \
+ federated_cluster_test_with_node_failure
check-long:
$(MAKE) check TESTS="$(LONG_TESTS)" VALGRIND=
diff --git a/qpid/cpp/src/tests/MessageTest.cpp b/qpid/cpp/src/tests/MessageTest.cpp
index 8fd9a53c7c..cd63f64a37 100644
--- a/qpid/cpp/src/tests/MessageTest.cpp
+++ b/qpid/cpp/src/tests/MessageTest.cpp
@@ -24,13 +24,12 @@
#include "qpid/framing/MessageTransferBody.h"
#include "qpid/framing/FieldValue.h"
#include "qpid/framing/Uuid.h"
+#include "qpid/sys/alloca.h"
#include "unit_test.h"
#include <iostream>
-#include <alloca.h>
-using namespace boost;
using namespace qpid::broker;
using namespace qpid::framing;
@@ -44,7 +43,7 @@ QPID_AUTO_TEST_CASE(testEncodeDecode)
string data1("abcdefg");
string data2("hijklmn");
- intrusive_ptr<Message> msg(new Message());
+ boost::intrusive_ptr<Message> msg(new Message());
AMQFrame method((MessageTransferBody(ProtocolVersion(), exchange, 0, 0)));
AMQFrame header((AMQHeaderBody()));
diff --git a/qpid/cpp/src/tests/MessageUtils.h b/qpid/cpp/src/tests/MessageUtils.h
index 67a852aa10..6a12c72007 100644
--- a/qpid/cpp/src/tests/MessageUtils.h
+++ b/qpid/cpp/src/tests/MessageUtils.h
@@ -33,7 +33,7 @@ struct MessageUtils
static boost::intrusive_ptr<Message> createMessage(const string& exchange="", const string& routingKey="",
const Uuid& messageId=Uuid(true), uint64_t contentSize = 0)
{
- boost::intrusive_ptr<Message> msg(new Message());
+ boost::intrusive_ptr<broker::Message> msg(new broker::Message());
AMQFrame method(( MessageTransferBody(ProtocolVersion(), exchange, 0, 0)));
AMQFrame header((AMQHeaderBody()));
diff --git a/qpid/cpp/src/tests/PollerTest.cpp b/qpid/cpp/src/tests/PollerTest.cpp
index 4f11dc5901..5b6b09ef65 100644
--- a/qpid/cpp/src/tests/PollerTest.cpp
+++ b/qpid/cpp/src/tests/PollerTest.cpp
@@ -74,7 +74,7 @@ int main(int /*argc*/, char** /*argv*/)
try
{
int sv[2];
- int rc = ::socketpair(AF_LOCAL, SOCK_STREAM, 0, sv);
+ int rc = ::socketpair(AF_UNIX, SOCK_STREAM, 0, sv);
assert(rc >= 0);
// Set non-blocking
diff --git a/qpid/cpp/src/tests/ProxyTest.cpp b/qpid/cpp/src/tests/ProxyTest.cpp
index 9007f3dc97..4ea10f7be9 100644
--- a/qpid/cpp/src/tests/ProxyTest.cpp
+++ b/qpid/cpp/src/tests/ProxyTest.cpp
@@ -23,7 +23,6 @@
#include "qpid/framing/AMQMethodBody.h"
#include "qpid/framing/ExecutionSyncBody.h"
#include "qpid/framing/Proxy.h"
-#include <alloca.h>
#include "unit_test.h"
diff --git a/qpid/cpp/src/tests/QueueEvents.cpp b/qpid/cpp/src/tests/QueueEvents.cpp
index 3e377d04b3..cd9439355e 100644
--- a/qpid/cpp/src/tests/QueueEvents.cpp
+++ b/qpid/cpp/src/tests/QueueEvents.cpp
@@ -27,6 +27,7 @@
#include "qpid/broker/QueueEvents.h"
#include "qpid/client/QueueOptions.h"
#include "qpid/framing/SequenceNumber.h"
+#include "qpid/sys/Dispatcher.h"
#include <boost/bind.hpp>
#include <boost/format.hpp>
@@ -37,7 +38,7 @@ using namespace qpid::broker;
using namespace qpid::sys;
using qpid::framing::SequenceNumber;
-struct DummyListener
+struct EventChecker
{
typedef std::deque<QueueEvents::Event> Events;
@@ -70,9 +71,9 @@ QPID_AUTO_TEST_CASE(testBasicEventProcessing)
sys::Dispatcher dispatcher(poller);
Thread dispatchThread(dispatcher);
QueueEvents events(poller);
- DummyListener listener;
+ EventChecker listener;
listener.poller = poller;
- events.registerListener("dummy", boost::bind(&DummyListener::handle, &listener, _1));
+ events.registerListener("dummy", boost::bind(&EventChecker::handle, &listener, _1));
//signal occurence of some events:
Queue queue("queue1");
SequenceNumber id;
diff --git a/qpid/cpp/src/tests/QueuePolicyTest.cpp b/qpid/cpp/src/tests/QueuePolicyTest.cpp
index 6c650169c7..7c7f8b7a10 100644
--- a/qpid/cpp/src/tests/QueuePolicyTest.cpp
+++ b/qpid/cpp/src/tests/QueuePolicyTest.cpp
@@ -158,6 +158,15 @@ QPID_AUTO_TEST_CASE(testRingPolicy)
BOOST_CHECK_EQUAL((boost::format("%1%_%2%") % "Message" % (i+1)).str(), msg.getData());
}
BOOST_CHECK(!f.subs.get(msg, q));
+
+ for (int i = 10; i < 20; i++) {
+ f.session.messageTransfer(arg::content=client::Message((boost::format("%1%_%2%") % "Message" % (i+1)).str(), q));
+ }
+ for (int i = 15; i < 20; i++) {
+ BOOST_CHECK(f.subs.get(msg, q, qpid::sys::TIME_SEC));
+ BOOST_CHECK_EQUAL((boost::format("%1%_%2%") % "Message" % (i+1)).str(), msg.getData());
+ }
+ BOOST_CHECK(!f.subs.get(msg, q));
}
QPID_AUTO_TEST_CASE(testStrictRingPolicy)
diff --git a/qpid/cpp/src/tests/ReplicationTest.cpp b/qpid/cpp/src/tests/ReplicationTest.cpp
new file mode 100644
index 0000000000..7bd585639d
--- /dev/null
+++ b/qpid/cpp/src/tests/ReplicationTest.cpp
@@ -0,0 +1,129 @@
+ /*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+#include "unit_test.h"
+#include "test_tools.h"
+#include "BrokerFixture.h"
+
+#include "qpid/Plugin.h"
+#include "qpid/broker/Broker.h"
+#include "qpid/client/QueueOptions.h"
+#include "qpid/framing/reply_exceptions.h"
+#include "qpid/framing/SequenceNumber.h"
+#include "qpid/replication/constants.h"
+#include "qpid/sys/Shlib.h"
+
+#include <string>
+#include <sstream>
+#include <vector>
+
+#include <boost/assign.hpp>
+#include <boost/bind.hpp>
+
+using namespace qpid::client;
+using namespace qpid::framing;
+using namespace qpid::replication::constants;
+using boost::assign::list_of;
+
+QPID_AUTO_TEST_SUITE(ReplicationTestSuite)
+
+qpid::sys::Shlib plugin("../.libs/replicating_listener.so");
+
+qpid::broker::Broker::Options getBrokerOpts(const std::vector<std::string>& args)
+{
+ std::vector<const char*> argv(args.size());
+ transform(args.begin(), args.end(), argv.begin(), boost::bind(&string::c_str, _1));
+
+ qpid::broker::Broker::Options opts;
+ qpid::Plugin::addOptions(opts);
+ opts.parse(argv.size(), &argv[0], "", true);
+ return opts;
+}
+
+QPID_AUTO_TEST_CASE(testReplicationExchange)
+{
+ qpid::broker::Broker::Options brokerOpts(getBrokerOpts(list_of<string>("qpidd")
+ ("--replication-exchange-name=qpid.replication")));
+ ProxySessionFixture f(brokerOpts);
+
+
+ std::string dataQ("queue-1");
+ std::string eventQ("event-queue-1");
+ std::string dataQ2("queue-2");
+ std::string eventQ2("event-queue-2");
+ FieldTable eventQopts;
+ eventQopts.setString("qpid.insert_sequence_numbers", REPLICATION_EVENT_SEQNO);
+
+ f.session.queueDeclare(arg::queue=eventQ, arg::exclusive=true, arg::autoDelete=true, arg::arguments=eventQopts);
+ f.session.exchangeBind(arg::exchange="qpid.replication", arg::queue=eventQ, arg::bindingKey=dataQ);
+
+ f.session.queueDeclare(arg::queue=eventQ2, arg::exclusive=true, arg::autoDelete=true, arg::arguments=eventQopts);
+ f.session.exchangeBind(arg::exchange="qpid.replication", arg::queue=eventQ2, arg::bindingKey=dataQ2);
+
+ QueueOptions args;
+ args.enableQueueEvents(false);
+ f.session.queueDeclare(arg::queue=dataQ, arg::exclusive=true, arg::autoDelete=true, arg::arguments=args);
+ f.session.queueDeclare(arg::queue=dataQ2, arg::exclusive=true, arg::autoDelete=true, arg::arguments=args);
+ for (int i = 0; i < 10; i++) {
+ f.session.messageTransfer(arg::content=Message((boost::format("%1%_%2%") % "Message" % (i+1)).str(), dataQ));
+ f.session.messageTransfer(arg::content=Message((boost::format("%1%_%2%") % "Message" % (i+1)).str(), dataQ2));
+ }
+ Message msg;
+ LocalQueue incoming;
+ Subscription sub = f.subs.subscribe(incoming, dataQ);
+ for (int i = 0; i < 10; i++) {
+ BOOST_CHECK(incoming.get(msg, qpid::sys::TIME_SEC));
+ BOOST_CHECK_EQUAL((boost::format("%1%_%2%") % "Message" % (i+1)).str(), msg.getData());
+ }
+ BOOST_CHECK(!f.subs.get(msg, dataQ));
+
+ sub.cancel();
+ sub = f.subs.subscribe(incoming, eventQ);
+ //check that we received enqueue events for first queue:
+ for (int i = 0; i < 10; i++) {
+ BOOST_CHECK(incoming.get(msg, qpid::sys::TIME_SEC));
+ BOOST_CHECK_EQUAL(msg.getHeaders().getAsString(REPLICATION_TARGET_QUEUE), dataQ);
+ BOOST_CHECK_EQUAL(msg.getHeaders().getAsInt(REPLICATION_EVENT_TYPE), ENQUEUE);
+ BOOST_CHECK_EQUAL(msg.getHeaders().getAsInt64(REPLICATION_EVENT_SEQNO), (i+1));
+ BOOST_CHECK_EQUAL((boost::format("%1%_%2%") % "Message" % (i+1)).str(), msg.getData());
+ }
+ //check that we received dequeue events for first queue:
+ for (int i = 0; i < 10; i++) {
+ BOOST_CHECK(incoming.get(msg, qpid::sys::TIME_SEC));
+ BOOST_CHECK_EQUAL(msg.getHeaders().getAsString(REPLICATION_TARGET_QUEUE), dataQ);
+ BOOST_CHECK_EQUAL(msg.getHeaders().getAsInt(REPLICATION_EVENT_TYPE), DEQUEUE);
+ BOOST_CHECK_EQUAL(msg.getHeaders().getAsInt(DEQUEUED_MESSAGE_POSITION), (i+1));
+ BOOST_CHECK_EQUAL(msg.getHeaders().getAsInt64(REPLICATION_EVENT_SEQNO), (i+11));
+ }
+
+ sub.cancel();
+ sub = f.subs.subscribe(incoming, eventQ2);
+ //check that we received enqueue events for second queue:
+ for (int i = 0; i < 10; i++) {
+ BOOST_CHECK(incoming.get(msg, qpid::sys::TIME_SEC));
+ BOOST_CHECK_EQUAL(msg.getHeaders().getAsString(REPLICATION_TARGET_QUEUE), dataQ2);
+ BOOST_CHECK_EQUAL(msg.getHeaders().getAsInt(REPLICATION_EVENT_TYPE), ENQUEUE);
+ BOOST_CHECK_EQUAL(msg.getHeaders().getAsInt64(REPLICATION_EVENT_SEQNO), (i+1));
+ BOOST_CHECK_EQUAL((boost::format("%1%_%2%") % "Message" % (i+1)).str(), msg.getData());
+ }
+}
+
+
+QPID_AUTO_TEST_SUITE_END()
diff --git a/qpid/cpp/src/tests/SocketProxy.h b/qpid/cpp/src/tests/SocketProxy.h
index 9722359d82..d2a93c902b 100644
--- a/qpid/cpp/src/tests/SocketProxy.h
+++ b/qpid/cpp/src/tests/SocketProxy.h
@@ -94,7 +94,7 @@ class SocketProxy : private qpid::sys::Runnable
throwIf(!(event.type == qpid::sys::Poller::READABLE && event.handle == &listenerHandle), "SocketProxy: Accept failed");
poller.delFd(listenerHandle);
- server.reset(listener.accept(0, 0));
+ server.reset(listener.accept());
// Pump data between client & server sockets
qpid::sys::PollerHandle clientHandle(client);
diff --git a/qpid/cpp/src/tests/TimerTest.cpp b/qpid/cpp/src/tests/TimerTest.cpp
index 50712ff79c..f8ab9fb2f3 100644
--- a/qpid/cpp/src/tests/TimerTest.cpp
+++ b/qpid/cpp/src/tests/TimerTest.cpp
@@ -75,7 +75,11 @@ class TestTask : public TimerTask
BOOST_CHECK(fired);
BOOST_CHECK_EQUAL(expected_position, position);
Duration actual(start, end);
+#ifdef _WIN32
+ uint64_t difference = _abs64(expected - actual);
+#else
uint64_t difference = abs(expected - actual);
+#endif
std::string msg(boost::lexical_cast<std::string>(boost::format("tolerance = %1%, difference = %2%") % tolerance % difference));
BOOST_CHECK_MESSAGE(difference < tolerance, msg);
}
diff --git a/qpid/cpp/src/tests/Uuid.cpp b/qpid/cpp/src/tests/Uuid.cpp
index ee86d75a26..ea2e80b63b 100644
--- a/qpid/cpp/src/tests/Uuid.cpp
+++ b/qpid/cpp/src/tests/Uuid.cpp
@@ -18,11 +18,11 @@
#include "qpid/framing/Uuid.h"
#include "qpid/framing/Buffer.h"
+#include "qpid/sys/alloca.h"
#include "unit_test.h"
#include <set>
-#include <alloca.h>
QPID_AUTO_TEST_SUITE(UuidTestSuite)
diff --git a/qpid/cpp/src/tests/client_test.vcproj b/qpid/cpp/src/tests/client_test.vcproj
index 0f9a50cdf0..1623c2961e 100644
--- a/qpid/cpp/src/tests/client_test.vcproj
+++ b/qpid/cpp/src/tests/client_test.vcproj
@@ -3,7 +3,7 @@
ProjectType="Visual C++"
Version="9.00"
Name="client_test"
- ProjectGUID="{9A95F0E4-FECA-1BAD-2235-047BCDC7409E}"
+ ProjectGUID="{9A95F0E4-FECA-1BAD-2431-8A11DB0D67CE}"
RootNamespace="client_test"
Keyword="Win32Proj"
SignManifests="true"
@@ -21,8 +21,8 @@
<Configurations>
<Configuration
Name="Debug|Win32"
- OutputDirectory="Static_Debug"
- IntermediateDirectory="Static_Debug\client_test\I386"
+ OutputDirectory="."
+ IntermediateDirectory="Debug\client_test\I386"
ConfigurationType="1"
CharacterSet="0"
@@ -55,7 +55,7 @@
PreprocessorDefinitions="_DEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
MinimalRebuild="false"
BasicRuntimeChecks="3"
- RuntimeLibrary="1"
+ RuntimeLibrary="3"
RuntimeTypeInfo="true"
WarningLevel="3"
Detect64BitPortabilityProblems="false"
@@ -76,7 +76,7 @@
/>
<Tool
Name="VCLinkerTool"
- AdditionalDependencies="qpidcommonsd.lib qpidclientsd.lib qmfconsolesd.lib ws2_32.lib rpcrt4.lib"
+ AdditionalDependencies="qpidcommond.lib qpidclientd.lib"
OutputFile="$(OutDir)\client_test.exe"
LinkIncremental="2"
SuppressStartupBanner="true"
@@ -103,8 +103,8 @@
</Configuration>
<Configuration
Name="Release|Win32"
- OutputDirectory="Static_Release"
- IntermediateDirectory="Static_Release\client_test\I386"
+ OutputDirectory="Release"
+ IntermediateDirectory="Release\client_test\I386"
ConfigurationType="1"
CharacterSet="0"
@@ -135,7 +135,7 @@
Optimization="2"
AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..,..\gen"
PreprocessorDefinitions="NDEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
- RuntimeLibrary="0"
+ RuntimeLibrary="2"
RuntimeTypeInfo="true"
WarningLevel="3"
Detect64BitPortabilityProblems="false"
@@ -155,7 +155,7 @@
/>
<Tool
Name="VCLinkerTool"
- AdditionalDependencies="qpidcommons.lib qpidclients.lib qmfconsoles.lib ws2_32.lib rpcrt4.lib"
+ AdditionalDependencies="qpidcommon.lib qpidclient.lib"
OutputFile="$(OutDir)\client_test.exe"
LinkIncremental="1"
SuppressStartupBanner="true"
@@ -184,8 +184,8 @@
</Configuration>
<Configuration
Name="Debug|x64"
- OutputDirectory="Static_Debug"
- IntermediateDirectory="Static_Debug\client_test\AMD64"
+ OutputDirectory="."
+ IntermediateDirectory="Debug\client_test\AMD64"
ConfigurationType="1"
CharacterSet="0"
@@ -218,7 +218,7 @@
PreprocessorDefinitions="_DEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;_AMD64_;_WIN64;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
MinimalRebuild="false"
BasicRuntimeChecks="3"
- RuntimeLibrary="1"
+ RuntimeLibrary="3"
RuntimeTypeInfo="true"
WarningLevel="3"
Detect64BitPortabilityProblems="false"
@@ -240,7 +240,7 @@
<Tool
Name="VCLinkerTool"
AdditionalOptions="/machine:AMD64"
- AdditionalDependencies="qpidcommonsd.lib qpidclientsd.lib qmfconsolesd.lib ws2_32.lib rpcrt4.lib"
+ AdditionalDependencies="qpidcommond.lib qpidclientd.lib"
OutputFile="$(OutDir)\client_test.exe"
LinkIncremental="2"
SuppressStartupBanner="true"
@@ -267,8 +267,8 @@
</Configuration>
<Configuration
Name="Release|x64"
- OutputDirectory="Static_Release"
- IntermediateDirectory="Static_Release\client_test\AMD64"
+ OutputDirectory="Release"
+ IntermediateDirectory="Release\client_test\AMD64"
ConfigurationType="1"
CharacterSet="0"
@@ -299,7 +299,7 @@
Optimization="2"
AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..,..\gen"
PreprocessorDefinitions="NDEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;_AMD64_;_WIN64;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
- RuntimeLibrary="0"
+ RuntimeLibrary="2"
RuntimeTypeInfo="true"
WarningLevel="3"
Detect64BitPortabilityProblems="false"
@@ -320,7 +320,7 @@
<Tool
Name="VCLinkerTool"
AdditionalOptions="/machine:AMD64"
- AdditionalDependencies="qpidcommons.lib qpidclients.lib qmfconsoles.lib ws2_32.lib rpcrt4.lib"
+ AdditionalDependencies="qpidcommon.lib qpidclient.lib"
OutputFile="$(OutDir)\client_test.exe"
LinkIncremental="1"
SuppressStartupBanner="true"
diff --git a/qpid/cpp/src/tests/cluster.mk b/qpid/cpp/src/tests/cluster.mk
index c3100ac968..5d115de5a5 100644
--- a/qpid/cpp/src/tests/cluster.mk
+++ b/qpid/cpp/src/tests/cluster.mk
@@ -29,8 +29,9 @@ if HAVE_LIBCPG
# ais_check checks pre-requisites for cluster tests and runs them if ok.
-TESTS+=ais_check federated_cluster_test
-EXTRA_DIST+=ais_check start_cluster stop_cluster restart_cluster cluster_python_tests cluster_python_tests_failing.txt federated_cluster_test
+TESTS+=ais_check federated_cluster_test clustered_replication_test
+EXTRA_DIST+=ais_check start_cluster stop_cluster restart_cluster cluster_python_tests cluster_python_tests_failing.txt \
+ federated_cluster_test clustered_replication_test
check_PROGRAMS+=cluster_test
cluster_test_SOURCES=unit_test.cpp cluster_test.cpp ClusterFixture.cpp ClusterFixture.h ForkedBroker.h ForkedBroker.cpp
diff --git a/qpid/cpp/src/tests/cluster_test.cpp b/qpid/cpp/src/tests/cluster_test.cpp
index c880f30e6b..eee2df58cc 100644
--- a/qpid/cpp/src/tests/cluster_test.cpp
+++ b/qpid/cpp/src/tests/cluster_test.cpp
@@ -27,6 +27,7 @@
#include "qpid/client/ConnectionAccess.h"
#include "qpid/client/Session.h"
#include "qpid/client/FailoverListener.h"
+#include "qpid/client/FailoverManager.h"
#include "qpid/cluster/Cluster.h"
#include "qpid/cluster/Cpg.h"
#include "qpid/cluster/UpdateClient.h"
@@ -35,6 +36,8 @@
#include "qpid/framing/reply_exceptions.h"
#include "qpid/framing/enum.h"
#include "qpid/log/Logger.h"
+#include "qpid/sys/Monitor.h"
+#include "qpid/sys/Thread.h"
#include <boost/bind.hpp>
#include <boost/shared_ptr.hpp>
@@ -148,49 +151,65 @@ vector<string> browse(Client& c, const string& q, int n) {
c.subs.subscribe(lq, q, browseSettings);
vector<string> result;
for (int i = 0; i < n; ++i) {
- result.push_back(lq.get(TIMEOUT).getData());
+ Message m;
+ if (!lq.get(m, TIMEOUT))
+ break;
+ result.push_back(m.getData());
}
c.subs.getSubscription(q).cancel();
return result;
}
+ConnectionSettings aclSettings(int port, const std::string& id) {
+ ConnectionSettings settings;
+ settings.port = port;
+ settings.mechanism = "PLAIN";
+ settings.username = id;
+ settings.password = id;
+ return settings;
+}
+
+#if 0
+// FIXME aconway 2009-03-10: This test passes but exposes a memory leak in the SASL client code.
+// Enable it when the leak is fixed.
+
+QPID_AUTO_TEST_CASE(testAcl) {
+ ofstream policyFile("cluster_test.acl");
+ // FIXME aconway 2009-02-12: guest -> qpidd?
+ policyFile << "acl allow foo@QPID create queue name=foo" << endl
+ << "acl allow foo@QPID create queue name=foo2" << endl
+ << "acl deny foo@QPID create queue name=bar" << endl
+ << "acl allow all all" << endl;
+ policyFile.close();
+ char cwd[1024];
+ BOOST_CHECK(::getcwd(cwd, sizeof(cwd)));
+ ClusterFixture cluster(2,-1, list_of<string>
+ ("--no-data-dir")
+ ("--auth=no")
+ ("--acl-file="+string(cwd)+"/cluster_test.acl")
+ ("--cluster-mechanism=PLAIN")
+ ("--cluster-username=cluster")
+ ("--cluster-password=cluster")
+ ("--load-module=../.libs/acl.so"));
+
+ Client c0(aclSettings(cluster[0], "c0"), "c0");
+ Client c1(aclSettings(cluster[1], "c1"), "c1");
+ Client foo(aclSettings(cluster[1], "foo"), "foo");
+
+ foo.session.queueDeclare("foo");
+ BOOST_CHECK_EQUAL(c0.session.queueQuery("foo").getQueue(), "foo");
+
+ BOOST_CHECK_THROW(foo.session.queueDeclare("bar"), framing::NotAllowedException);
+ BOOST_CHECK(c0.session.queueQuery("bar").getQueue().empty());
+ BOOST_CHECK(c1.session.queueQuery("bar").getQueue().empty());
-// FIXME aconway 2009-02-12: need to figure out how to test this properly.
-// Current problems:
-// - all brokers share the same data-dir (set ACL without data dir?)
-// - updater's user name not making it through to updatee for ACL checks.
-//
-// QPID_AUTO_TEST_CASE(testAcl) {
-// ofstream policyFile("cluster_test.acl");
-// // FIXME aconway 2009-02-12: guest -> qpidd?
-// policyFile << "acl allow guest@QPID all all" << endl
-// << "acl allow foo@QPID create queue name=foo" << endl
-// << "acl allow bar@QPID create queue name=bar" << endl
-// << "acl deny all create queue" << endl
-// << "acl allow all all" << endl;
-// policyFile.close();
-// ClusterFixture cluster(2,-1, list_of<string>
-// ("--data-dir=.") ("--auth=no")
-// ("--acl-file=cluster_test.acl")
-// ("--cluster-mechanism=PLAIN")
-// ("--load-module=../.libs/acl.so"));
-// Client c0(cluster[0], "c0");
-// Client c1(cluster[1], "c1");
-
-// ConnectionSettings settings;
-// settings.port = cluster[0];
-// settings.username = "foo";
-// Client foo(settings, "foo");
-
-// foo.session.queueDeclare("foo");
-// BOOST_CHECK_EQUAL(c0.session.queueQuery("foo").getQueue(), "foo");
-// BOOST_CHECK_EQUAL(c1.session.queueQuery("foo").getQueue(), "foo");
-
-// BOOST_CHECK_THROW(foo.session.queueDeclare("bar"), int);
-// BOOST_CHECK_EQUAL(c0.session.queueQuery("bar").getQueue(), "");
-// BOOST_CHECK_EQUAL(c1.session.queueQuery("bar").getQueue(), "");
-// }
+ cluster.add();
+ Client c2(aclSettings(cluster[2], "c2"), "c2");
+ BOOST_CHECK_THROW(foo.session.queueDeclare("bar"), framing::NotAllowedException);
+ BOOST_CHECK(c2.session.queueQuery("bar").getQueue().empty());
+}
+#endif
QPID_AUTO_TEST_CASE(testMessageTimeToLive) {
// Note: this doesn't actually test for cluster race conditions around TTL,
@@ -199,13 +218,23 @@ QPID_AUTO_TEST_CASE(testMessageTimeToLive) {
ClusterFixture cluster(2);
Client c0(cluster[0], "c0");
Client c1(cluster[1], "c1");
+ c0.session.queueDeclare("p");
c0.session.queueDeclare("q");
c0.session.messageTransfer(arg::content=ttlMessage("a", "q", 200));
c0.session.messageTransfer(arg::content=Message("b", "q"));
- BOOST_CHECK_EQUAL(browse(c1, "q", 2), list_of<string>("a")("b"));
- sys::usleep(300*1000);
+ c0.session.messageTransfer(arg::content=ttlMessage("x", "p", 10000));
+ c0.session.messageTransfer(arg::content=Message("y", "p"));
+ cluster.add();
+ Client c2(cluster[1], "c2");
+
+ BOOST_CHECK_EQUAL(browse(c0, "p", 2), list_of<string>("x")("y"));
+ BOOST_CHECK_EQUAL(browse(c1, "p", 2), list_of<string>("x")("y"));
+ BOOST_CHECK_EQUAL(browse(c2, "p", 2), list_of<string>("x")("y"));
+
+ sys::usleep(200*1000);
BOOST_CHECK_EQUAL(browse(c0, "q", 1), list_of<string>("b"));
BOOST_CHECK_EQUAL(browse(c1, "q", 1), list_of<string>("b"));
+ BOOST_CHECK_EQUAL(browse(c2, "q", 1), list_of<string>("b"));
}
QPID_AUTO_TEST_CASE(testSequenceOptions) {
@@ -506,10 +535,11 @@ QPID_AUTO_TEST_CASE(testCatchupSharedState) {
c0.session.queueDeclare("q");
c0.session.messageTransfer(arg::content=Message("foo","q"));
c0.session.messageTransfer(arg::content=Message("bar","q"));
+
while (c0.session.queueQuery("q").getMessageCount() != 2)
sys::usleep(1000); // Wait for message to show up on broker 0.
- // Add a new broker, it should catch up.
+ // Add a new broker, it will catch up.
cluster.add();
// Do some work post-add
@@ -527,6 +557,7 @@ QPID_AUTO_TEST_CASE(testCatchupSharedState) {
BOOST_CHECK(c1.subs.get(m, "q", TIMEOUT));
BOOST_CHECK_EQUAL(m.getData(), "foo");
+ BOOST_CHECK_EQUAL(m.getDeliveryProperties().getExchange(), "");
BOOST_CHECK(c1.subs.get(m, "q", TIMEOUT));
BOOST_CHECK_EQUAL(m.getData(), "bar");
BOOST_CHECK_EQUAL(c1.session.queueQuery("q").getMessageCount(), 0u);
@@ -628,4 +659,86 @@ QPID_AUTO_TEST_CASE(testDequeueWaitingSubscription) {
BOOST_CHECK_EQUAL(0u, c2.session.queueQuery("q").getMessageCount());
}
+QPID_AUTO_TEST_CASE(testHeartbeatCancelledOnFailover)
+{
+ struct Sender : FailoverManager::Command
+ {
+ std::string queue;
+ std::string content;
+
+ Sender(const std::string& q, const std::string& c) : queue(q), content(c) {}
+
+ void execute(AsyncSession& session, bool)
+ {
+ session.messageTransfer(arg::content=Message(content, queue));
+ }
+ };
+
+ struct Receiver : FailoverManager::Command, MessageListener, qpid::sys::Runnable
+ {
+ FailoverManager& mgr;
+ std::string queue;
+ std::string expectedContent;
+ qpid::client::Subscription subscription;
+ qpid::sys::Monitor lock;
+ bool ready;
+
+ Receiver(FailoverManager& m, const std::string& q, const std::string& c) : mgr(m), queue(q), expectedContent(c), ready(false) {}
+
+ void received(Message& message)
+ {
+ BOOST_CHECK_EQUAL(expectedContent, message.getData());
+ subscription.cancel();
+ }
+
+ void execute(AsyncSession& session, bool)
+ {
+ session.queueDeclare(arg::queue=queue);
+ SubscriptionManager subs(session);
+ subscription = subs.subscribe(*this, queue);
+ session.sync();
+ setReady();
+ subs.run();
+ //cleanup:
+ session.queueDelete(arg::queue=queue);
+ }
+
+ void run()
+ {
+ mgr.execute(*this);
+ }
+
+ void waitForReady()
+ {
+ qpid::sys::Monitor::ScopedLock l(lock);
+ while (!ready) {
+ lock.wait();
+ }
+ }
+
+ void setReady()
+ {
+ qpid::sys::Monitor::ScopedLock l(lock);
+ ready = true;
+ lock.notify();
+ }
+ };
+
+ ClusterFixture cluster(2);
+ ConnectionSettings settings;
+ settings.port = cluster[1];
+ settings.heartbeat = 1;
+ FailoverManager fmgr(settings);
+ Sender sender("my-queue", "my-data");
+ Receiver receiver(fmgr, "my-queue", "my-data");
+ qpid::sys::Thread runner(receiver);
+ receiver.waitForReady();
+ cluster.kill(1);
+ //sleep for 2 secs to allow the heartbeat task to fire on the now dead connection:
+ ::usleep(2*1000*1000);
+ fmgr.execute(sender);
+ runner.join();
+ fmgr.close();
+}
+
QPID_AUTO_TEST_SUITE_END()
diff --git a/qpid/cpp/src/tests/clustered_replication_test b/qpid/cpp/src/tests/clustered_replication_test
new file mode 100755
index 0000000000..2a3e742632
--- /dev/null
+++ b/qpid/cpp/src/tests/clustered_replication_test
@@ -0,0 +1,127 @@
+#!/bin/sh
+
+#
+# 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.
+#
+
+# Test reliability of the replication feature in the face of link
+# failures:
+srcdir=`dirname $0`
+PYTHON_DIR=$srcdir/../../../python
+
+trap stop_brokers INT EXIT
+
+fail() {
+ echo $1
+ exit 1
+}
+with_ais_group() {
+ id -nG | grep '\<ais\>' >/dev/null || { echo "You are not a member of the ais group." 1>&2; exit 1; }
+ echo $* | newgrp ais
+}
+
+stop_brokers() {
+ if [[ $PRIMARY1 ]] ; then
+ ../qpidd -q --port $PRIMARY1
+ unset PRIMARY1
+ fi
+ if [[ $PRIMARY2 ]] ; then
+ ../qpidd -q --port $PRIMARY2
+ unset PRIMARY2
+ fi
+ if [[ $DR1 ]] ; then
+ ../qpidd -q --port $DR1
+ unset DR1
+ fi
+ if [[ $DR2 ]] ; then
+ ../qpidd -q --port $DR2
+ unset DR2
+ fi
+}
+
+if test -d ${PYTHON_DIR}; then
+ id -nG | grep '\<ais\>' >/dev/null || \
+ NOGROUP="You are not a member of the ais group."
+ ps -u root | grep 'aisexec\|corosync' >/dev/null || \
+ NOAISEXEC="The aisexec or corosync daemon is not running as root"
+
+ if test -n "$NOGROUP" -o -n "$NOAISEXEC"; then
+ cat <<EOF
+Not running federation to cluster test because:
+ $NOGROUP
+ $NOAISEXEC
+EOF
+ exit 0;
+ fi
+
+ #todo: these cluster names need to be unique to prevent clashes
+ PRIMARY_CLUSTER=PRIMARY_$(hostname)_$(pwd)
+ DR_CLUSTER=DR_$(hostname)_$(pwd)
+
+ GENERAL_OPTS="--auth no --no-module-dir --no-data-dir --daemon --port 0 --log-enable notice+ --log-to-stderr false"
+ PRIMARY_OPTS="--load-module ../.libs/replicating_listener.so --create-replication-queue true --replication-queue REPLICATION_QUEUE --load-module ../.libs/cluster.so --cluster-name $PRIMARY_CLUSTER"
+ DR_OPTS="--load-module ../.libs/replication_exchange.so --load-module ../.libs/cluster.so --cluster-name $DR_CLUSTER"
+
+ rm -f repl*.tmp #cleanup any files left from previous run
+
+ #start first node of primary cluster and set up test queue
+ echo Starting primary cluster
+ PRIMARY1=$(with_ais_group ../qpidd $GENERAL_OPTS $PRIMARY_OPTS --log-to-file repl.primary.1.tmp) || fail "Could not start node"
+ $PYTHON_DIR/commands/qpid-config -a "localhost:$PRIMARY1" add queue test-queue --generate-queue-events 2
+ $PYTHON_DIR/commands/qpid-config -a "localhost:$PRIMARY1" add queue control-queue --generate-queue-events 1
+
+ #send 10 messages, consume 5 of them
+ for i in `seq 1 10`; do echo Message$i; done | ./sender --port $PRIMARY1
+ ./receiver --port $PRIMARY1 --messages 5 > /dev/null
+
+ #add new node to primary cluster, testing correct transfer of state:
+ echo Adding node to primary cluster
+ PRIMARY2=$(with_ais_group ../qpidd $GENERAL_OPTS $PRIMARY_OPTS --log-to-file repl.primary.2.tmp)
+
+ #start DR cluster, set up test queue there and establish replication bridge
+ echo Starting DR cluster
+ DR1=$(with_ais_group ../qpidd $GENERAL_OPTS $DR_OPTS --log-to-file repl.dr.1.tmp)
+ DR2=$(with_ais_group ../qpidd $GENERAL_OPTS $DR_OPTS --log-to-file repl.dr.2.tmp)
+
+ $PYTHON_DIR/commands/qpid-config -a "localhost:$DR1" add queue test-queue
+ $PYTHON_DIR/commands/qpid-config -a "localhost:$DR1" add queue control-queue
+ $PYTHON_DIR/commands/qpid-config -a "localhost:$DR1" add exchange replication REPLICATION_EXCHANGE
+ $PYTHON_DIR/commands/qpid-route queue add localhost:$DR2 localhost:$PRIMARY2 REPLICATION_EXCHANGE REPLICATION_QUEUE
+
+ #send more messages to primary
+ for i in `seq 11 20`; do echo Message$i; done | ./sender --port $PRIMARY1 --send-eos 1
+
+ #wait for replication events to all be processed:
+ echo Waiting for replication to complete
+ echo Done | ./sender --port $PRIMARY1 --routing-key control-queue --send-eos 1
+ ./receiver --queue control-queue --port $DR1 > /dev/null
+
+ #verify contents of test queue on dr cluster:
+ echo Verifying...
+ ./receiver --port $DR2 > repl.out.tmp
+ for i in `seq 6 20`; do echo Message$i; done | diff repl.out.tmp - || FAIL=1
+
+ if [[ $FAIL ]]; then
+ echo Clustered replication test failed: expectations not met!
+ exit 1
+ else
+ echo Clustered replication test passed
+ rm -f repl*.tmp
+ fi
+
+fi
diff --git a/qpid/cpp/src/tests/consume.vcproj b/qpid/cpp/src/tests/consume.vcproj
index ecf7b2df08..2e1f8e3e56 100644
--- a/qpid/cpp/src/tests/consume.vcproj
+++ b/qpid/cpp/src/tests/consume.vcproj
@@ -3,7 +3,7 @@
ProjectType="Visual C++"
Version="9.00"
Name="consume"
- ProjectGUID="{7F5DE0A1-FECA-1BAD-2235-047BCDC7409E}"
+ ProjectGUID="{7F5DE0A1-FECA-1BAD-2431-8A11DB0D67CE}"
RootNamespace="consume"
Keyword="Win32Proj"
SignManifests="true"
@@ -21,8 +21,8 @@
<Configurations>
<Configuration
Name="Debug|Win32"
- OutputDirectory="Static_Debug"
- IntermediateDirectory="Static_Debug\consume\I386"
+ OutputDirectory="."
+ IntermediateDirectory="Debug\consume\I386"
ConfigurationType="1"
CharacterSet="0"
@@ -55,7 +55,7 @@
PreprocessorDefinitions="_DEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
MinimalRebuild="false"
BasicRuntimeChecks="3"
- RuntimeLibrary="1"
+ RuntimeLibrary="3"
RuntimeTypeInfo="true"
WarningLevel="3"
Detect64BitPortabilityProblems="false"
@@ -76,7 +76,7 @@
/>
<Tool
Name="VCLinkerTool"
- AdditionalDependencies="qpidcommonsd.lib qpidclientsd.lib qmfconsolesd.lib ws2_32.lib rpcrt4.lib"
+ AdditionalDependencies="qpidcommond.lib qpidclientd.lib"
OutputFile="$(OutDir)\consume.exe"
LinkIncremental="2"
SuppressStartupBanner="true"
@@ -103,8 +103,8 @@
</Configuration>
<Configuration
Name="Release|Win32"
- OutputDirectory="Static_Release"
- IntermediateDirectory="Static_Release\consume\I386"
+ OutputDirectory="Release"
+ IntermediateDirectory="Release\consume\I386"
ConfigurationType="1"
CharacterSet="0"
@@ -135,7 +135,7 @@
Optimization="2"
AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..,..\gen"
PreprocessorDefinitions="NDEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
- RuntimeLibrary="0"
+ RuntimeLibrary="2"
RuntimeTypeInfo="true"
WarningLevel="3"
Detect64BitPortabilityProblems="false"
@@ -155,7 +155,7 @@
/>
<Tool
Name="VCLinkerTool"
- AdditionalDependencies="qpidcommons.lib qpidclients.lib qmfconsoles.lib ws2_32.lib rpcrt4.lib"
+ AdditionalDependencies="qpidcommon.lib qpidclient.lib"
OutputFile="$(OutDir)\consume.exe"
LinkIncremental="1"
SuppressStartupBanner="true"
@@ -184,8 +184,8 @@
</Configuration>
<Configuration
Name="Debug|x64"
- OutputDirectory="Static_Debug"
- IntermediateDirectory="Static_Debug\consume\AMD64"
+ OutputDirectory="."
+ IntermediateDirectory="Debug\consume\AMD64"
ConfigurationType="1"
CharacterSet="0"
@@ -218,7 +218,7 @@
PreprocessorDefinitions="_DEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;_AMD64_;_WIN64;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
MinimalRebuild="false"
BasicRuntimeChecks="3"
- RuntimeLibrary="1"
+ RuntimeLibrary="3"
RuntimeTypeInfo="true"
WarningLevel="3"
Detect64BitPortabilityProblems="false"
@@ -240,7 +240,7 @@
<Tool
Name="VCLinkerTool"
AdditionalOptions="/machine:AMD64"
- AdditionalDependencies="qpidcommonsd.lib qpidclientsd.lib qmfconsolesd.lib ws2_32.lib rpcrt4.lib"
+ AdditionalDependencies="qpidcommond.lib qpidclientd.lib"
OutputFile="$(OutDir)\consume.exe"
LinkIncremental="2"
SuppressStartupBanner="true"
@@ -267,8 +267,8 @@
</Configuration>
<Configuration
Name="Release|x64"
- OutputDirectory="Static_Release"
- IntermediateDirectory="Static_Release\consume\AMD64"
+ OutputDirectory="Release"
+ IntermediateDirectory="Release\consume\AMD64"
ConfigurationType="1"
CharacterSet="0"
@@ -299,7 +299,7 @@
Optimization="2"
AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..,..\gen"
PreprocessorDefinitions="NDEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;_AMD64_;_WIN64;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
- RuntimeLibrary="0"
+ RuntimeLibrary="2"
RuntimeTypeInfo="true"
WarningLevel="3"
Detect64BitPortabilityProblems="false"
@@ -320,7 +320,7 @@
<Tool
Name="VCLinkerTool"
AdditionalOptions="/machine:AMD64"
- AdditionalDependencies="qpidcommons.lib qpidclients.lib qmfconsoles.lib ws2_32.lib rpcrt4.lib"
+ AdditionalDependencies="qpidcommon.lib qpidclient.lib"
OutputFile="$(OutDir)\consume.exe"
LinkIncremental="1"
SuppressStartupBanner="true"
diff --git a/qpid/cpp/src/tests/echotest.vcproj b/qpid/cpp/src/tests/echotest.vcproj
index 0048dde85f..2848894228 100644
--- a/qpid/cpp/src/tests/echotest.vcproj
+++ b/qpid/cpp/src/tests/echotest.vcproj
@@ -3,7 +3,7 @@
ProjectType="Visual C++"
Version="9.00"
Name="echotest"
- ProjectGUID="{0A5AF6BE-FECA-1BAD-2235-047BCDC7409E}"
+ ProjectGUID="{0A5AF6BE-FECA-1BAD-2431-8A11DB0D67CE}"
RootNamespace="echotest"
Keyword="Win32Proj"
SignManifests="true"
@@ -21,8 +21,8 @@
<Configurations>
<Configuration
Name="Debug|Win32"
- OutputDirectory="Static_Debug"
- IntermediateDirectory="Static_Debug\echotest\I386"
+ OutputDirectory="."
+ IntermediateDirectory="Debug\echotest\I386"
ConfigurationType="1"
CharacterSet="0"
@@ -55,7 +55,7 @@
PreprocessorDefinitions="_DEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
MinimalRebuild="false"
BasicRuntimeChecks="3"
- RuntimeLibrary="1"
+ RuntimeLibrary="3"
RuntimeTypeInfo="true"
WarningLevel="3"
Detect64BitPortabilityProblems="false"
@@ -76,7 +76,7 @@
/>
<Tool
Name="VCLinkerTool"
- AdditionalDependencies="qpidcommonsd.lib qpidclientsd.lib qmfconsolesd.lib ws2_32.lib rpcrt4.lib"
+ AdditionalDependencies="qpidcommond.lib qpidclientd.lib"
OutputFile="$(OutDir)\echotest.exe"
LinkIncremental="2"
SuppressStartupBanner="true"
@@ -103,8 +103,8 @@
</Configuration>
<Configuration
Name="Release|Win32"
- OutputDirectory="Static_Release"
- IntermediateDirectory="Static_Release\echotest\I386"
+ OutputDirectory="Release"
+ IntermediateDirectory="Release\echotest\I386"
ConfigurationType="1"
CharacterSet="0"
@@ -135,7 +135,7 @@
Optimization="2"
AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..,..\gen"
PreprocessorDefinitions="NDEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
- RuntimeLibrary="0"
+ RuntimeLibrary="2"
RuntimeTypeInfo="true"
WarningLevel="3"
Detect64BitPortabilityProblems="false"
@@ -155,7 +155,7 @@
/>
<Tool
Name="VCLinkerTool"
- AdditionalDependencies="qpidcommons.lib qpidclients.lib qmfconsoles.lib ws2_32.lib rpcrt4.lib"
+ AdditionalDependencies="qpidcommon.lib qpidclient.lib"
OutputFile="$(OutDir)\echotest.exe"
LinkIncremental="1"
SuppressStartupBanner="true"
@@ -184,8 +184,8 @@
</Configuration>
<Configuration
Name="Debug|x64"
- OutputDirectory="Static_Debug"
- IntermediateDirectory="Static_Debug\echotest\AMD64"
+ OutputDirectory="."
+ IntermediateDirectory="Debug\echotest\AMD64"
ConfigurationType="1"
CharacterSet="0"
@@ -218,7 +218,7 @@
PreprocessorDefinitions="_DEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;_AMD64_;_WIN64;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
MinimalRebuild="false"
BasicRuntimeChecks="3"
- RuntimeLibrary="1"
+ RuntimeLibrary="3"
RuntimeTypeInfo="true"
WarningLevel="3"
Detect64BitPortabilityProblems="false"
@@ -240,7 +240,7 @@
<Tool
Name="VCLinkerTool"
AdditionalOptions="/machine:AMD64"
- AdditionalDependencies="qpidcommonsd.lib qpidclientsd.lib qmfconsolesd.lib ws2_32.lib rpcrt4.lib"
+ AdditionalDependencies="qpidcommond.lib qpidclientd.lib"
OutputFile="$(OutDir)\echotest.exe"
LinkIncremental="2"
SuppressStartupBanner="true"
@@ -267,8 +267,8 @@
</Configuration>
<Configuration
Name="Release|x64"
- OutputDirectory="Static_Release"
- IntermediateDirectory="Static_Release\echotest\AMD64"
+ OutputDirectory="Release"
+ IntermediateDirectory="Release\echotest\AMD64"
ConfigurationType="1"
CharacterSet="0"
@@ -299,7 +299,7 @@
Optimization="2"
AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..,..\gen"
PreprocessorDefinitions="NDEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;_AMD64_;_WIN64;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
- RuntimeLibrary="0"
+ RuntimeLibrary="2"
RuntimeTypeInfo="true"
WarningLevel="3"
Detect64BitPortabilityProblems="false"
@@ -320,7 +320,7 @@
<Tool
Name="VCLinkerTool"
AdditionalOptions="/machine:AMD64"
- AdditionalDependencies="qpidcommons.lib qpidclients.lib qmfconsoles.lib ws2_32.lib rpcrt4.lib"
+ AdditionalDependencies="qpidcommon.lib qpidclient.lib"
OutputFile="$(OutDir)\echotest.exe"
LinkIncremental="1"
SuppressStartupBanner="true"
diff --git a/qpid/cpp/src/tests/failover_soak.cpp b/qpid/cpp/src/tests/failover_soak.cpp
index 6149e845e4..4f16e469b8 100644
--- a/qpid/cpp/src/tests/failover_soak.cpp
+++ b/qpid/cpp/src/tests/failover_soak.cpp
@@ -26,18 +26,32 @@
#include <sys/wait.h>
#include <sys/time.h>
#include <string.h>
+#include <sys/types.h>
+#include <signal.h>
#include <string>
#include <iostream>
#include <sstream>
#include <vector>
+#include <boost/assign.hpp>
+
+#include "qpid/framing/Uuid.h"
+
#include <ForkedBroker.h>
+#include <qpid/client/Connection.h>
+
+
using namespace std;
+using boost::assign::list_of;
+using namespace qpid::framing;
+using namespace qpid::client;
+
+
typedef vector<ForkedBroker *> brokerVector;
@@ -51,11 +65,34 @@ typedef enum
childStatus;
+typedef enum
+{
+ NO_TYPE,
+ DECLARING_CLIENT,
+ SENDING_CLIENT,
+ RECEIVING_CLIENT
+}
+childType;
+
+
+ostream& operator<< ( ostream& os, const childType& ct ) {
+ switch ( ct ) {
+ case DECLARING_CLIENT: os << "Declaring Client"; break;
+ case SENDING_CLIENT: os << "Sending Client"; break;
+ case RECEIVING_CLIENT: os << "Receiving Client"; break;
+ default: os << "No Client"; break;
+ }
+
+ return os;
+}
+
+
+
struct child
{
- child ( string & name, pid_t pid )
- : name(name), pid(pid), retval(-999), status(RUNNING)
+ child ( string & name, pid_t pid, childType type )
+ : name(name), pid(pid), retval(-999), status(RUNNING), type(type)
{
gettimeofday ( & startTime, 0 );
}
@@ -70,10 +107,18 @@ struct child
}
+ void
+ setType ( childType t )
+ {
+ type = t;
+ }
+
+
string name;
pid_t pid;
int retval;
childStatus status;
+ childType type;
struct timeval startTime,
stopTime;
};
@@ -83,10 +128,11 @@ struct child
struct children : public vector<child *>
{
+
void
- add ( string & name, pid_t pid )
+ add ( string & name, pid_t pid, childType type )
{
- push_back(new child ( name, pid ));
+ push_back ( new child ( name, pid, type ) );
}
@@ -108,7 +154,7 @@ struct children : public vector<child *>
child * kid = get ( pid );
if(! kid)
{
- if ( verbosity > 0 )
+ if ( verbosity > 1 )
{
cerr << "children::exited warning: Can't find child with pid "
<< pid
@@ -138,10 +184,15 @@ struct children : public vector<child *>
int
checkChildren ( )
{
- vector<child *>::iterator i;
+ vector<child *>::iterator i;
for ( i = begin(); i != end(); ++ i )
if ( (COMPLETED == (*i)->status) && (0 != (*i)->retval) )
- return (*i)->retval;
+ {
+ cerr << "checkChildren: error on child of type "
+ << (*i)->type
+ << endl;
+ return (*i)->retval;
+ }
return 0;
}
@@ -176,22 +227,43 @@ struct children : public vector<child *>
If it has been at least that long since a shild stopped
running, we judge the system to have hung.
*/
- bool
+ int
hanging ( int hangTime )
{
struct timeval now,
duration;
gettimeofday ( &now, 0 );
+ int how_many_hanging = 0;
+
vector<child *>::iterator i;
for ( i = begin(); i != end(); ++ i )
{
- timersub ( & now, &((*i)->startTime), & duration );
- if ( duration.tv_sec >= hangTime )
- return true;
+ //Not in POSIX
+ //timersub ( & now, &((*i)->startTime), & duration );
+ duration.tv_sec = now.tv_sec - (*i)->startTime.tv_sec;
+ duration.tv_usec = now.tv_usec - (*i)->startTime.tv_usec;
+ if (duration.tv_usec < 0) {
+ --duration.tv_sec;
+ duration.tv_usec += 1000000;
+ }
+
+ if ( (COMPLETED != (*i)->status) // child isn't done running
+ &&
+ ( duration.tv_sec >= hangTime ) // it's been too long
+ )
+ {
+ std::cerr << "Child of type "
+ << (*i)->type
+ << " hanging. "
+ << "PID is "
+ << (*i)->pid
+ << endl;
+ ++ how_many_hanging;
+ }
}
- return false;
+ return how_many_hanging;
}
@@ -206,9 +278,8 @@ children allMyChildren;
void
-childExit ( int signalNumber )
+childExit ( int )
{
- signalNumber ++; // Now maybe the compiler willleave me alone?
int childReturnCode;
pid_t pid = waitpid ( 0, & childReturnCode, WNOHANG);
@@ -235,10 +306,9 @@ mrand ( int minDesiredVal, int maxDesiredVal ) {
void
-makeClusterName ( string & s, int & num ) {
- num = mrand(1000);
+makeClusterName ( string & s ) {
stringstream ss;
- ss << "soakTestCluster_" << num;
+ ss << "soakTestCluster_" << Uuid(true).str();
s = ss.str();
}
@@ -263,66 +333,136 @@ printBrokers ( brokerVector & brokers )
+ForkedBroker * newbie = 0;
+int newbie_port = 0;
+
+
+
+bool
+wait_for_newbie ( )
+{
+ if ( ! newbie )
+ return true;
+
+ try
+ {
+ Connection connection;
+ connection.open ( "127.0.0.1", newbie_port );
+ connection.close();
+ newbie = 0; // He's no newbie anymore!
+ return true;
+ }
+ catch ( const std::exception& error )
+ {
+ std::cerr << "wait_for_newbie error: "
+ << error.what()
+ << endl;
+ return false;
+ }
+}
+
+
+
void
startNewBroker ( brokerVector & brokers,
char const * srcRoot,
char const * moduleDir,
- string const clusterName )
+ string const clusterName,
+ int verbosity )
{
static int brokerId = 0;
stringstream path, prefix, module;
module << moduleDir << "/cluster.so";
path << srcRoot << "/qpidd";
- prefix << "soak-" << brokerId++;
-
- const char * const argv[] =
- {
- "qpidd",
- "-p0",
- "--load-module=cluster.so",
- "--cluster-name",
- clusterName.c_str(),
- "--auth=no",
- "--no-data-dir",
- "--no-module-dir",
- "--mgmt-enable=no",
- "--log-prefix", prefix.str().c_str(),
- 0
- };
-
- size_t argc = sizeof(argv)/sizeof(argv[0]);
- brokers.push_back ( new ForkedBroker ( argc, argv ) );
+ prefix << "soak-" << brokerId;
+ std::vector<std::string> argv = list_of<string>
+ ("qpidd")
+ ("--no-module-dir")
+ ("--load-module=cluster.so")
+ ("--cluster-name")
+ (clusterName)
+ ("--auth=no")
+ ("--no-data-dir")
+ ("--mgmt-enable=no")
+ ("--log-prefix")
+ (prefix.str())
+ ("--log-to-file")
+ (prefix.str()+".log");
+
+ newbie = new ForkedBroker ( argv );
+ newbie_port = newbie->getPort();
+ ForkedBroker * broker = newbie;
+
+ if ( verbosity > 0 )
+ std::cerr << "new broker created: pid == "
+ << broker->getPID()
+ << " log-prefix == "
+ << "soak-" << brokerId
+ << endl;
+ brokers.push_back ( broker );
+
+ ++ brokerId;
}
-void
+bool
killFrontBroker ( brokerVector & brokers, int verbosity )
{
+ cerr << "killFrontBroker: waiting for newbie sync...\n";
+ if ( ! wait_for_newbie() )
+ return false;
+ cerr << "killFrontBroker: newbie synced.\n";
+
if ( verbosity > 0 )
cout << "killFrontBroker pid: " << brokers[0]->getPID() << " on port " << brokers[0]->getPort() << endl;
try { brokers[0]->kill(9); }
catch ( const exception& error ) {
if ( verbosity > 0 )
- cout << "error killing broker: " << error.what() << endl;
+ {
+ cout << "error killing broker: "
+ << error.what()
+ << endl;
+ }
+
+ return false;
}
delete brokers[0];
brokers.erase ( brokers.begin() );
+ return true;
}
+/*
+ * The optional delay is to avoid killing newbie brokers that have just
+ * been added and are still in the process of updating. This causes
+ * spurious, test-generated errors that scare everybody.
+ */
void
-killAllBrokers ( brokerVector & brokers )
+killAllBrokers ( brokerVector & brokers, int delay )
{
+ if ( delay > 0 )
+ {
+ std::cerr << "Killing all brokers after delay of " << delay << endl;
+ sleep ( delay );
+ }
+
for ( uint i = 0; i < brokers.size(); ++ i )
try { brokers[i]->kill(9); }
- catch ( ... ) { }
+ catch ( const exception& error )
+ {
+ std::cerr << "killAllBrokers Warning: exception during kill on broker "
+ << i
+ << " "
+ << error.what()
+ << endl;
+ }
}
@@ -339,7 +479,7 @@ runDeclareQueuesClient ( brokerVector brokers,
string name("declareQueues");
int port = brokers[0]->getPort ( );
- if ( verbosity > 0 )
+ if ( verbosity > 1 )
cout << "startDeclareQueuesClient: host: "
<< host
<< " port: "
@@ -357,11 +497,11 @@ runDeclareQueuesClient ( brokerVector brokers,
if ( ! pid ) {
execv ( path, const_cast<char * const *>(&argv[0]) );
- perror ( "error executing dq: " );
+ perror ( "error executing declareQueues: " );
return 0;
}
- allMyChildren.add ( name, pid );
+ allMyChildren.add ( name, pid, DECLARING_CLIENT );
return pid;
}
@@ -380,12 +520,16 @@ startReceivingClient ( brokerVector brokers,
string name("receiver");
int port = brokers[0]->getPort ( );
- if ( verbosity > 0 )
+ if ( verbosity > 1 )
cout << "startReceivingClient: port " << port << endl;
+
+ // verbosity has to be > 1 to let clients talk.
+ int client_verbosity = (verbosity > 1 ) ? 1 : 0;
+
char portStr[100];
char verbosityStr[100];
sprintf(portStr, "%d", port);
- sprintf(verbosityStr, "%d", verbosity);
+ sprintf(verbosityStr, "%d", client_verbosity);
vector<const char*> argv;
@@ -404,7 +548,7 @@ startReceivingClient ( brokerVector brokers,
return 0;
}
- allMyChildren.add ( name, pid );
+ allMyChildren.add ( name, pid, RECEIVING_CLIENT );
return pid;
}
@@ -424,13 +568,16 @@ startSendingClient ( brokerVector brokers,
string name("sender");
int port = brokers[0]->getPort ( );
- if ( verbosity )
+ if ( verbosity > 1)
cout << "startSenderClient: port " << port << endl;
char portStr[100];
char verbosityStr[100];
+ //
+ // verbosity has to be > 1 to let clients talk.
+ int client_verbosity = (verbosity > 1 ) ? 1 : 0;
sprintf ( portStr, "%d", port);
- sprintf ( verbosityStr, "%d", verbosity);
+ sprintf ( verbosityStr, "%d", client_verbosity);
vector<const char*> argv;
argv.push_back ( "replayingSender" );
@@ -449,19 +596,21 @@ startSendingClient ( brokerVector brokers,
return 0;
}
- allMyChildren.add ( name, pid );
+ allMyChildren.add ( name, pid, SENDING_CLIENT );
return pid;
}
-#define HUNKY_DORY 0
-#define BAD_ARGS 1
-#define CANT_FORK_DQ 2
-#define CANT_FORK_RECEIVER 3
-#define DQ_FAILED 4
-#define ERROR_ON_CHILD 5
-#define HANGING 6
+#define HUNKY_DORY 0
+#define BAD_ARGS 1
+#define CANT_FORK_DQ 2
+#define CANT_FORK_RECEIVER 3
+#define CANT_FORK_SENDER 4
+#define DQ_FAILED 5
+#define ERROR_ON_CHILD 6
+#define HANGING 7
+#define ERROR_KILLING_BROKER 8
int
@@ -489,16 +638,15 @@ main ( int argc, char const ** argv )
allMyChildren.verbosity = verbosity;
- int clusterNum;
string clusterName;
srand ( getpid() );
- makeClusterName ( clusterName, clusterNum );
+ makeClusterName ( clusterName );
brokerVector brokers;
- if ( verbosity > 0 )
+ if ( verbosity > 1 )
cout << "Starting initial cluster...\n";
int nBrokers = 3;
@@ -506,7 +654,8 @@ main ( int argc, char const ** argv )
startNewBroker ( brokers,
srcRoot,
moduleDir,
- clusterName );
+ clusterName,
+ verbosity );
}
@@ -518,14 +667,14 @@ main ( int argc, char const ** argv )
pid_t dqClientPid =
runDeclareQueuesClient ( brokers, host, declareQueuesPath, verbosity );
if ( -1 == dqClientPid ) {
- cerr << "failoverSoak error: Couldn't fork declareQueues.\n";
+ cerr << "END_OF_TEST ERROR_START_DECLARE_1\n";
return CANT_FORK_DQ;
}
// Don't continue until declareQueues is finished.
pid_t retval = waitpid ( dqClientPid, & childStatus, 0);
if ( retval != dqClientPid) {
- cerr << "failoverSoak error: waitpid on declareQueues returned value " << retval << endl;
+ cerr << "END_OF_TEST ERROR_START_DECLARE_2\n";
return DQ_FAILED;
}
allMyChildren.exited ( dqClientPid, childStatus );
@@ -540,7 +689,7 @@ main ( int argc, char const ** argv )
reportFrequency,
verbosity );
if ( -1 == receivingClientPid ) {
- cerr << "failoverSoak error: Couldn't fork receiver.\n";
+ cerr << "END_OF_TEST ERROR_START_RECEIVER\n";
return CANT_FORK_RECEIVER;
}
@@ -554,13 +703,13 @@ main ( int argc, char const ** argv )
reportFrequency,
verbosity );
if ( -1 == sendingClientPid ) {
- cerr << "failoverSoak error: Couldn't fork sender.\n";
- return CANT_FORK_RECEIVER;
+ cerr << "END_OF_TEST ERROR_START_SENDER\n";
+ return CANT_FORK_SENDER;
}
- int minSleep = 3,
- maxSleep = 6;
+ int minSleep = 2,
+ maxSleep = 4;
for ( int totalBrokers = 3;
@@ -578,11 +727,16 @@ main ( int argc, char const ** argv )
sleep ( sleepyTime );
// Kill the oldest broker. --------------------------
- killFrontBroker ( brokers, verbosity );
+ if ( ! killFrontBroker ( brokers, verbosity ) )
+ {
+ allMyChildren.killEverybody();
+ std::cerr << "END_OF_TEST ERROR_BROKER\n";
+ return ERROR_KILLING_BROKER;
+ }
// Sleep for a while. -------------------------
sleepyTime = mrand ( minSleep, maxSleep );
- if ( verbosity > 0 )
+ if ( verbosity > 1 )
cerr << "Sleeping for " << sleepyTime << " seconds.\n";
sleep ( sleepyTime );
@@ -593,22 +747,33 @@ main ( int argc, char const ** argv )
startNewBroker ( brokers,
srcRoot,
moduleDir,
- clusterName );
+ clusterName,
+ verbosity );
- if ( verbosity > 0 )
+ if ( verbosity > 1 )
printBrokers ( brokers );
// If all children have exited, quit.
int unfinished = allMyChildren.unfinished();
if ( ! unfinished ) {
- killAllBrokers ( brokers );
+ killAllBrokers ( brokers, 5 );
- if ( verbosity > 0 )
+ if ( verbosity > 1 )
cout << "failoverSoak: all children have exited.\n";
int retval = allMyChildren.checkChildren();
- if ( verbosity > 0 )
+ if ( verbosity > 1 )
std::cerr << "failoverSoak: checkChildren: " << retval << endl;
- return retval ? ERROR_ON_CHILD : HUNKY_DORY;
+
+ if ( retval )
+ {
+ std::cerr << "END_OF_TEST ERROR_CLIENT\n";
+ return ERROR_ON_CHILD;
+ }
+ else
+ {
+ std::cerr << "END_OF_TEST SUCCESSFUL\n";
+ return HUNKY_DORY;
+ }
}
// Even if some are still running, if there's an error, quit.
@@ -617,35 +782,38 @@ main ( int argc, char const ** argv )
if ( verbosity > 0 )
cout << "failoverSoak: error on child.\n";
allMyChildren.killEverybody();
- killAllBrokers ( brokers );
+ killAllBrokers ( brokers, 5 );
+ std::cerr << "END_OF_TEST ERROR_CLIENT\n";
return ERROR_ON_CHILD;
}
// If one is hanging, quit.
if ( allMyChildren.hanging ( 120 ) )
{
- if ( verbosity > 0 )
- cout << "failoverSoak: child hanging.\n";
- allMyChildren.killEverybody();
- killAllBrokers ( brokers );
+ /*
+ * Don't kill any processes. Leave alive for questioning.
+ * */
+ std::cerr << "END_OF_TEST ERROR_HANGING\n";
return HANGING;
}
- if ( verbosity > 0 ) {
+ if ( verbosity > 1 ) {
std::cerr << "------- next kill-broker loop --------\n";
allMyChildren.print();
}
}
retval = allMyChildren.checkChildren();
- if ( verbosity > 0 )
+ if ( verbosity > 1 )
std::cerr << "failoverSoak: checkChildren: " << retval << endl;
- if ( verbosity > 0 )
+ if ( verbosity > 1 )
cout << "failoverSoak: maxBrokers reached.\n";
allMyChildren.killEverybody();
- killAllBrokers ( brokers );
+ killAllBrokers ( brokers, 5 );
+
+ std::cerr << "END_OF_TEST SUCCESSFUL\n";
return retval ? ERROR_ON_CHILD : HUNKY_DORY;
}
diff --git a/qpid/cpp/src/tests/federated_cluster_test b/qpid/cpp/src/tests/federated_cluster_test
index d4549738b2..575a5d9c9b 100755
--- a/qpid/cpp/src/tests/federated_cluster_test
+++ b/qpid/cpp/src/tests/federated_cluster_test
@@ -21,8 +21,8 @@
# Test reliability of the replication feature in the face of link
# failures:
-MY_DIR=`dirname \`which $0\``
-PYTHON_DIR=${MY_DIR}/../../../python
+srcdir=`dirname $0`
+PYTHON_DIR=$srcdir/../../../python
trap stop_brokers EXIT
@@ -37,9 +37,14 @@ stop_brokers() {
unset BROKER_A
fi
if [[ $NODE_1 ]] ; then
- ./stop_cluster
+ ../qpidd -q --port $NODE_1
unset NODE_1
fi
+ if [[ $NODE_2 ]] ; then
+ ../qpidd -q --port $NODE_2
+ unset NODE_2
+ fi
+ rm cluster.ports
}
start_brokers() {
@@ -48,19 +53,20 @@ start_brokers() {
BROKER_A=`cat fed.port.tmp`
#...and start cluster
- ./start_cluster 2 || fail "Could not start cluster"
+ $srcdir/start_cluster 2 || fail "Could not start cluster"
NODE_1=$(head -1 cluster.ports)
NODE_2=$(tail -1 cluster.ports)
}
setup() {
+ export PYTHONPATH=$PYTHON_DIR
#create exchange on both cluster and single broker
$PYTHON_DIR/commands/qpid-config -a "localhost:$BROKER_A" add exchange direct test-exchange
$PYTHON_DIR/commands/qpid-config -a "localhost:$NODE_1" add exchange direct test-exchange
#create dynamic routes for test exchange
- $PYTHON_DIR/commands/qpid-route dynamic add "localhost:$NODE_1" "localhost:$BROKER_A" test-exchange
- $PYTHON_DIR/commands/qpid-route dynamic add "localhost:$BROKER_A" "localhost:$NODE_1" test-exchange
+ $PYTHON_DIR/commands/qpid-route dynamic add "localhost:$NODE_2" "localhost:$BROKER_A" test-exchange
+ $PYTHON_DIR/commands/qpid-route dynamic add "localhost:$BROKER_A" "localhost:$NODE_2" test-exchange
#create test queue on cluster and bind it to the test exchange
$PYTHON_DIR/commands/qpid-config -a "localhost:$NODE_1" add queue test-queue
@@ -71,7 +77,7 @@ setup() {
$PYTHON_DIR/commands/qpid-config -a "localhost:$BROKER_A" bind test-exchange test-queue from-cluster
}
-run_test_pull_to_cluster() {
+run_test_pull_to_cluster_two_consumers() {
#start consumers on each of the two nodes of the cluster
./receiver --port $NODE_1 --queue test-queue --credit-window 1 > fed1.out.tmp &
./receiver --port $NODE_2 --queue test-queue --credit-window 1 > fed2.out.tmp &
@@ -88,6 +94,20 @@ run_test_pull_to_cluster() {
rm -f fed*.tmp #cleanup
}
+run_test_pull_to_cluster() {
+ #send stream of messages to test exchange on single broker
+ for i in `seq 1 1000`; do echo Message $i >> fed.in.tmp; done
+ ./sender --port $BROKER_A --exchange test-exchange --routing-key to-cluster --send-eos 1 < fed.in.tmp
+
+ #consume from remaining node of the cluster
+ ./receiver --port $NODE_2 --queue test-queue > fed.out.tmp
+
+ #verify all messages are received
+ diff fed.in.tmp fed.out.tmp || fail "federated link to cluster failed: expectations not met!"
+
+ rm -f fed*.tmp #cleanup
+}
+
run_test_pull_from_cluster() {
#start consumer on single broker
./receiver --port $BROKER_A --queue test-queue --credit-window 1 > fed.out.tmp &
@@ -124,8 +144,19 @@ EOF
echo "brokers started"
setup
echo "setup completed"
- run_test_pull_to_cluster
+ run_test_pull_to_cluster_two_consumers
echo "federated link to cluster verified"
run_test_pull_from_cluster
echo "federated link from cluster verified"
+ if [[ $TEST_NODE_FAILURE ]] ; then
+ #kill first cluster node and retest
+ kill -9 $(../qpidd --check --port $NODE_1) && unset NODE_1
+ echo "killed first cluster node; waiting for links to re-establish themselves..."
+ sleep 5
+ echo "retesting..."
+ run_test_pull_to_cluster
+ echo "federated link to cluster verified"
+ run_test_pull_from_cluster
+ echo "federated link from cluster verified"
+ fi
fi
diff --git a/qpid/cpp/src/tests/federated_cluster_test_with_node_failure b/qpid/cpp/src/tests/federated_cluster_test_with_node_failure
new file mode 100755
index 0000000000..f144a676de
--- /dev/null
+++ b/qpid/cpp/src/tests/federated_cluster_test_with_node_failure
@@ -0,0 +1,23 @@
+#!/bin/sh
+
+#
+# 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.
+#
+
+srcdir=`dirname $0`
+TEST_NODE_FAILURE=1 $srcdir/federated_cluster_test
diff --git a/qpid/cpp/src/tests/header_test.vcproj b/qpid/cpp/src/tests/header_test.vcproj
index 9a1da958cc..da761a6edb 100644
--- a/qpid/cpp/src/tests/header_test.vcproj
+++ b/qpid/cpp/src/tests/header_test.vcproj
@@ -3,7 +3,7 @@
ProjectType="Visual C++"
Version="9.00"
Name="header_test"
- ProjectGUID="{1B23F05D-FECA-1BAD-2235-047BCDC7409E}"
+ ProjectGUID="{1B23F05D-FECA-1BAD-2431-8A11DB0D67CE}"
RootNamespace="header_test"
Keyword="Win32Proj"
SignManifests="true"
@@ -21,8 +21,8 @@
<Configurations>
<Configuration
Name="Debug|Win32"
- OutputDirectory="Static_Debug"
- IntermediateDirectory="Static_Debug\header_test\I386"
+ OutputDirectory="."
+ IntermediateDirectory="Debug\header_test\I386"
ConfigurationType="1"
CharacterSet="0"
@@ -55,7 +55,7 @@
PreprocessorDefinitions="_DEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
MinimalRebuild="false"
BasicRuntimeChecks="3"
- RuntimeLibrary="1"
+ RuntimeLibrary="3"
RuntimeTypeInfo="true"
WarningLevel="3"
Detect64BitPortabilityProblems="false"
@@ -76,7 +76,7 @@
/>
<Tool
Name="VCLinkerTool"
- AdditionalDependencies="qpidcommonsd.lib qpidclientsd.lib qmfconsolesd.lib ws2_32.lib rpcrt4.lib"
+ AdditionalDependencies="qpidcommond.lib qpidclientd.lib"
OutputFile="$(OutDir)\header_test.exe"
LinkIncremental="2"
SuppressStartupBanner="true"
@@ -103,8 +103,8 @@
</Configuration>
<Configuration
Name="Release|Win32"
- OutputDirectory="Static_Release"
- IntermediateDirectory="Static_Release\header_test\I386"
+ OutputDirectory="Release"
+ IntermediateDirectory="Release\header_test\I386"
ConfigurationType="1"
CharacterSet="0"
@@ -135,7 +135,7 @@
Optimization="2"
AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..,..\gen"
PreprocessorDefinitions="NDEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
- RuntimeLibrary="0"
+ RuntimeLibrary="2"
RuntimeTypeInfo="true"
WarningLevel="3"
Detect64BitPortabilityProblems="false"
@@ -155,7 +155,7 @@
/>
<Tool
Name="VCLinkerTool"
- AdditionalDependencies="qpidcommons.lib qpidclients.lib qmfconsoles.lib ws2_32.lib rpcrt4.lib"
+ AdditionalDependencies="qpidcommon.lib qpidclient.lib"
OutputFile="$(OutDir)\header_test.exe"
LinkIncremental="1"
SuppressStartupBanner="true"
@@ -184,8 +184,8 @@
</Configuration>
<Configuration
Name="Debug|x64"
- OutputDirectory="Static_Debug"
- IntermediateDirectory="Static_Debug\header_test\AMD64"
+ OutputDirectory="."
+ IntermediateDirectory="Debug\header_test\AMD64"
ConfigurationType="1"
CharacterSet="0"
@@ -218,7 +218,7 @@
PreprocessorDefinitions="_DEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;_AMD64_;_WIN64;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
MinimalRebuild="false"
BasicRuntimeChecks="3"
- RuntimeLibrary="1"
+ RuntimeLibrary="3"
RuntimeTypeInfo="true"
WarningLevel="3"
Detect64BitPortabilityProblems="false"
@@ -240,7 +240,7 @@
<Tool
Name="VCLinkerTool"
AdditionalOptions="/machine:AMD64"
- AdditionalDependencies="qpidcommonsd.lib qpidclientsd.lib qmfconsolesd.lib ws2_32.lib rpcrt4.lib"
+ AdditionalDependencies="qpidcommond.lib qpidclientd.lib"
OutputFile="$(OutDir)\header_test.exe"
LinkIncremental="2"
SuppressStartupBanner="true"
@@ -267,8 +267,8 @@
</Configuration>
<Configuration
Name="Release|x64"
- OutputDirectory="Static_Release"
- IntermediateDirectory="Static_Release\header_test\AMD64"
+ OutputDirectory="Release"
+ IntermediateDirectory="Release\header_test\AMD64"
ConfigurationType="1"
CharacterSet="0"
@@ -299,7 +299,7 @@
Optimization="2"
AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..,..\gen"
PreprocessorDefinitions="NDEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;_AMD64_;_WIN64;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
- RuntimeLibrary="0"
+ RuntimeLibrary="2"
RuntimeTypeInfo="true"
WarningLevel="3"
Detect64BitPortabilityProblems="false"
@@ -320,7 +320,7 @@
<Tool
Name="VCLinkerTool"
AdditionalOptions="/machine:AMD64"
- AdditionalDependencies="qpidcommons.lib qpidclients.lib qmfconsoles.lib ws2_32.lib rpcrt4.lib"
+ AdditionalDependencies="qpidcommon.lib qpidclient.lib"
OutputFile="$(OutDir)\header_test.exe"
LinkIncremental="1"
SuppressStartupBanner="true"
diff --git a/qpid/cpp/src/tests/latencytest.vcproj b/qpid/cpp/src/tests/latencytest.vcproj
index eb9741a1e1..758302029a 100644
--- a/qpid/cpp/src/tests/latencytest.vcproj
+++ b/qpid/cpp/src/tests/latencytest.vcproj
@@ -3,7 +3,7 @@
ProjectType="Visual C++"
Version="9.00"
Name="latencytest"
- ProjectGUID="{4A809018-FECA-1BAD-2235-047BCDC7409E}"
+ ProjectGUID="{4A809018-FECA-1BAD-2431-8A11DB0D67CE}"
RootNamespace="latencytest"
Keyword="Win32Proj"
SignManifests="true"
@@ -21,8 +21,8 @@
<Configurations>
<Configuration
Name="Debug|Win32"
- OutputDirectory="Static_Debug"
- IntermediateDirectory="Static_Debug\latencytest\I386"
+ OutputDirectory="."
+ IntermediateDirectory="Debug\latencytest\I386"
ConfigurationType="1"
CharacterSet="0"
@@ -55,7 +55,7 @@
PreprocessorDefinitions="_DEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
MinimalRebuild="false"
BasicRuntimeChecks="3"
- RuntimeLibrary="1"
+ RuntimeLibrary="3"
RuntimeTypeInfo="true"
WarningLevel="3"
Detect64BitPortabilityProblems="false"
@@ -76,7 +76,7 @@
/>
<Tool
Name="VCLinkerTool"
- AdditionalDependencies="qpidcommonsd.lib qpidclientsd.lib qmfconsolesd.lib ws2_32.lib rpcrt4.lib"
+ AdditionalDependencies="qpidcommond.lib qpidclientd.lib"
OutputFile="$(OutDir)\latencytest.exe"
LinkIncremental="2"
SuppressStartupBanner="true"
@@ -103,8 +103,8 @@
</Configuration>
<Configuration
Name="Release|Win32"
- OutputDirectory="Static_Release"
- IntermediateDirectory="Static_Release\latencytest\I386"
+ OutputDirectory="Release"
+ IntermediateDirectory="Release\latencytest\I386"
ConfigurationType="1"
CharacterSet="0"
@@ -135,7 +135,7 @@
Optimization="2"
AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..,..\gen"
PreprocessorDefinitions="NDEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
- RuntimeLibrary="0"
+ RuntimeLibrary="2"
RuntimeTypeInfo="true"
WarningLevel="3"
Detect64BitPortabilityProblems="false"
@@ -155,7 +155,7 @@
/>
<Tool
Name="VCLinkerTool"
- AdditionalDependencies="qpidcommons.lib qpidclients.lib qmfconsoles.lib ws2_32.lib rpcrt4.lib"
+ AdditionalDependencies="qpidcommon.lib qpidclient.lib"
OutputFile="$(OutDir)\latencytest.exe"
LinkIncremental="1"
SuppressStartupBanner="true"
@@ -184,8 +184,8 @@
</Configuration>
<Configuration
Name="Debug|x64"
- OutputDirectory="Static_Debug"
- IntermediateDirectory="Static_Debug\latencytest\AMD64"
+ OutputDirectory="."
+ IntermediateDirectory="Debug\latencytest\AMD64"
ConfigurationType="1"
CharacterSet="0"
@@ -218,7 +218,7 @@
PreprocessorDefinitions="_DEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;_AMD64_;_WIN64;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
MinimalRebuild="false"
BasicRuntimeChecks="3"
- RuntimeLibrary="1"
+ RuntimeLibrary="3"
RuntimeTypeInfo="true"
WarningLevel="3"
Detect64BitPortabilityProblems="false"
@@ -240,7 +240,7 @@
<Tool
Name="VCLinkerTool"
AdditionalOptions="/machine:AMD64"
- AdditionalDependencies="qpidcommonsd.lib qpidclientsd.lib qmfconsolesd.lib ws2_32.lib rpcrt4.lib"
+ AdditionalDependencies="qpidcommond.lib qpidclientd.lib"
OutputFile="$(OutDir)\latencytest.exe"
LinkIncremental="2"
SuppressStartupBanner="true"
@@ -267,8 +267,8 @@
</Configuration>
<Configuration
Name="Release|x64"
- OutputDirectory="Static_Release"
- IntermediateDirectory="Static_Release\latencytest\AMD64"
+ OutputDirectory="Release"
+ IntermediateDirectory="Release\latencytest\AMD64"
ConfigurationType="1"
CharacterSet="0"
@@ -299,7 +299,7 @@
Optimization="2"
AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..,..\gen"
PreprocessorDefinitions="NDEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;_AMD64_;_WIN64;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
- RuntimeLibrary="0"
+ RuntimeLibrary="2"
RuntimeTypeInfo="true"
WarningLevel="3"
Detect64BitPortabilityProblems="false"
@@ -320,7 +320,7 @@
<Tool
Name="VCLinkerTool"
AdditionalOptions="/machine:AMD64"
- AdditionalDependencies="qpidcommons.lib qpidclients.lib qmfconsoles.lib ws2_32.lib rpcrt4.lib"
+ AdditionalDependencies="qpidcommon.lib qpidclient.lib"
OutputFile="$(OutDir)\latencytest.exe"
LinkIncremental="1"
SuppressStartupBanner="true"
diff --git a/qpid/cpp/src/tests/logging.cpp b/qpid/cpp/src/tests/logging.cpp
index 051722e7c8..00e1d7de85 100644
--- a/qpid/cpp/src/tests/logging.cpp
+++ b/qpid/cpp/src/tests/logging.cpp
@@ -23,6 +23,7 @@
#include "qpid/memory.h"
#include "qpid/Options.h"
#if defined (_WIN32)
+# include "qpid/log/windows/SinkOptions.h"
#else
# include "qpid/log/posix/SinkOptions.h"
#endif
@@ -172,7 +173,7 @@ QPID_AUTO_TEST_CASE(testLoggerFormat) {
l.format(Logger::FUNCTION);
QPID_LOG(critical, "foo");
- BOOST_CHECK_REGEX("void .*testLoggerFormat.*\\(\\): foo\n", out->last());
+ BOOST_CHECK_EQUAL(string(BOOST_CURRENT_FUNCTION) + ": foo\n", out->last());
l.format(Logger::LEVEL);
QPID_LOG(critical, "foo");
@@ -270,7 +271,11 @@ QPID_AUTO_TEST_CASE(testOptionsParse) {
"--log-function", "YES"
};
qpid::log::Options opts("");
+#ifdef _WIN32
+ qpid::log::windows::SinkOptions sinks("test");
+#else
qpid::log::posix::SinkOptions sinks("test");
+#endif
opts.parse(ARGC(argv), const_cast<char**>(argv));
sinks = *opts.sinkOptions;
vector<string> expect=list_of("error+:foo")("debug:bar")("info");
@@ -286,7 +291,11 @@ QPID_AUTO_TEST_CASE(testOptionsParse) {
QPID_AUTO_TEST_CASE(testOptionsDefault) {
Options opts("");
+#ifdef _WIN32
+ qpid::log::windows::SinkOptions sinks("test");
+#else
qpid::log::posix::SinkOptions sinks("test");
+#endif
sinks = *opts.sinkOptions;
BOOST_CHECK(sinks.logToStderr);
BOOST_CHECK(!sinks.logToStdout);
@@ -345,8 +354,13 @@ QPID_AUTO_TEST_CASE(testQuoteNonPrintable) {
ScopedSuppressLogging ls(l);
Options opts("test");
opts.time=false;
+#ifdef _WIN32
+ qpid::log::windows::SinkOptions *sinks =
+ dynamic_cast<qpid::log::windows::SinkOptions *>(opts.sinkOptions.get());
+#else
qpid::log::posix::SinkOptions *sinks =
dynamic_cast<qpid::log::posix::SinkOptions *>(opts.sinkOptions.get());
+#endif
sinks->logToStderr = false;
sinks->logFile = "logging.tmp";
l.configure(opts);
diff --git a/qpid/cpp/src/tests/perftest.cpp b/qpid/cpp/src/tests/perftest.cpp
index 6456bc8304..18491d72a0 100644
--- a/qpid/cpp/src/tests/perftest.cpp
+++ b/qpid/cpp/src/tests/perftest.cpp
@@ -38,7 +38,6 @@
#include <sstream>
#include <numeric>
#include <algorithm>
-#include <unistd.h>
#include <math.h>
@@ -238,8 +237,10 @@ struct Client : public Runnable {
~Client() {
try {
- session.close();
- connection->close();
+ if (connection->isOpen()) {
+ session.close();
+ connection->close();
+ }
} catch (const std::exception& e) {
std::cerr << "Error in shutdown: " << e.what() << std::endl;
}
@@ -523,7 +524,8 @@ struct PublishThread : public Client {
sync(session).txCommit();
}
}
- if (opts.intervalPub) ::usleep(opts.intervalPub*1000);
+ if (opts.intervalPub)
+ qpid::sys::usleep(opts.intervalPub*1000);
}
if (opts.confirm) session.sync();
AbsTime end=now();
@@ -613,7 +615,8 @@ struct SubscribeThread : public Client {
if (opts.commitAsync) session.txCommit();
else sync(session).txCommit();
}
- if (opts.intervalSub) ::usleep(opts.intervalSub*1000);
+ if (opts.intervalSub)
+ qpid::sys::usleep(opts.intervalSub*1000);
// TODO aconway 2007-11-23: check message order for.
// multiple publishers. Need an array of counters,
// one per publisher and a publisher ID in the
diff --git a/qpid/cpp/src/tests/perftest.vcproj b/qpid/cpp/src/tests/perftest.vcproj
index c9132bac03..3a2397ac9b 100644
--- a/qpid/cpp/src/tests/perftest.vcproj
+++ b/qpid/cpp/src/tests/perftest.vcproj
@@ -3,7 +3,7 @@
ProjectType="Visual C++"
Version="9.00"
Name="perftest"
- ProjectGUID="{1F2066BE-FECA-1BAD-2235-047BCDC7409E}"
+ ProjectGUID="{1F2066BE-FECA-1BAD-2431-8A11DB0D67CE}"
RootNamespace="perftest"
Keyword="Win32Proj"
SignManifests="true"
@@ -21,8 +21,8 @@
<Configurations>
<Configuration
Name="Debug|Win32"
- OutputDirectory="Static_Debug"
- IntermediateDirectory="Static_Debug\perftest\I386"
+ OutputDirectory="."
+ IntermediateDirectory="Debug\perftest\I386"
ConfigurationType="1"
CharacterSet="0"
@@ -55,7 +55,7 @@
PreprocessorDefinitions="_DEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
MinimalRebuild="false"
BasicRuntimeChecks="3"
- RuntimeLibrary="1"
+ RuntimeLibrary="3"
RuntimeTypeInfo="true"
WarningLevel="3"
Detect64BitPortabilityProblems="false"
@@ -76,7 +76,7 @@
/>
<Tool
Name="VCLinkerTool"
- AdditionalDependencies="qpidcommonsd.lib qpidclientsd.lib qmfconsolesd.lib ws2_32.lib rpcrt4.lib"
+ AdditionalDependencies="qpidcommond.lib qpidclientd.lib"
OutputFile="$(OutDir)\perftest.exe"
LinkIncremental="2"
SuppressStartupBanner="true"
@@ -103,8 +103,8 @@
</Configuration>
<Configuration
Name="Release|Win32"
- OutputDirectory="Static_Release"
- IntermediateDirectory="Static_Release\perftest\I386"
+ OutputDirectory="Release"
+ IntermediateDirectory="Release\perftest\I386"
ConfigurationType="1"
CharacterSet="0"
@@ -135,7 +135,7 @@
Optimization="2"
AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..,..\gen"
PreprocessorDefinitions="NDEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
- RuntimeLibrary="0"
+ RuntimeLibrary="2"
RuntimeTypeInfo="true"
WarningLevel="3"
Detect64BitPortabilityProblems="false"
@@ -155,7 +155,7 @@
/>
<Tool
Name="VCLinkerTool"
- AdditionalDependencies="qpidcommons.lib qpidclients.lib qmfconsoles.lib ws2_32.lib rpcrt4.lib"
+ AdditionalDependencies="qpidcommon.lib qpidclient.lib"
OutputFile="$(OutDir)\perftest.exe"
LinkIncremental="1"
SuppressStartupBanner="true"
@@ -184,8 +184,8 @@
</Configuration>
<Configuration
Name="Debug|x64"
- OutputDirectory="Static_Debug"
- IntermediateDirectory="Static_Debug\perftest\AMD64"
+ OutputDirectory="."
+ IntermediateDirectory="Debug\perftest\AMD64"
ConfigurationType="1"
CharacterSet="0"
@@ -218,7 +218,7 @@
PreprocessorDefinitions="_DEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;_AMD64_;_WIN64;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
MinimalRebuild="false"
BasicRuntimeChecks="3"
- RuntimeLibrary="1"
+ RuntimeLibrary="3"
RuntimeTypeInfo="true"
WarningLevel="3"
Detect64BitPortabilityProblems="false"
@@ -240,7 +240,7 @@
<Tool
Name="VCLinkerTool"
AdditionalOptions="/machine:AMD64"
- AdditionalDependencies="qpidcommonsd.lib qpidclientsd.lib qmfconsolesd.lib ws2_32.lib rpcrt4.lib"
+ AdditionalDependencies="qpidcommond.lib qpidclientd.lib"
OutputFile="$(OutDir)\perftest.exe"
LinkIncremental="2"
SuppressStartupBanner="true"
@@ -267,8 +267,8 @@
</Configuration>
<Configuration
Name="Release|x64"
- OutputDirectory="Static_Release"
- IntermediateDirectory="Static_Release\perftest\AMD64"
+ OutputDirectory="Release"
+ IntermediateDirectory="Release\perftest\AMD64"
ConfigurationType="1"
CharacterSet="0"
@@ -299,7 +299,7 @@
Optimization="2"
AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..,..\gen"
PreprocessorDefinitions="NDEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;_AMD64_;_WIN64;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
- RuntimeLibrary="0"
+ RuntimeLibrary="2"
RuntimeTypeInfo="true"
WarningLevel="3"
Detect64BitPortabilityProblems="false"
@@ -320,7 +320,7 @@
<Tool
Name="VCLinkerTool"
AdditionalOptions="/machine:AMD64"
- AdditionalDependencies="qpidcommons.lib qpidclients.lib qmfconsoles.lib ws2_32.lib rpcrt4.lib"
+ AdditionalDependencies="qpidcommon.lib qpidclient.lib"
OutputFile="$(OutDir)\perftest.exe"
LinkIncremental="1"
SuppressStartupBanner="true"
diff --git a/qpid/cpp/src/tests/publish.vcproj b/qpid/cpp/src/tests/publish.vcproj
index a205337ecd..7422606a32 100644
--- a/qpid/cpp/src/tests/publish.vcproj
+++ b/qpid/cpp/src/tests/publish.vcproj
@@ -3,7 +3,7 @@
ProjectType="Visual C++"
Version="9.00"
Name="publish"
- ProjectGUID="{AE773E7F-FECA-1BAD-2235-047BCDC7409E}"
+ ProjectGUID="{AE773E7F-FECA-1BAD-2431-8A11DB0D67CE}"
RootNamespace="publish"
Keyword="Win32Proj"
SignManifests="true"
@@ -21,8 +21,8 @@
<Configurations>
<Configuration
Name="Debug|Win32"
- OutputDirectory="Static_Debug"
- IntermediateDirectory="Static_Debug\publish\I386"
+ OutputDirectory="."
+ IntermediateDirectory="Debug\publish\I386"
ConfigurationType="1"
CharacterSet="0"
@@ -55,7 +55,7 @@
PreprocessorDefinitions="_DEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
MinimalRebuild="false"
BasicRuntimeChecks="3"
- RuntimeLibrary="1"
+ RuntimeLibrary="3"
RuntimeTypeInfo="true"
WarningLevel="3"
Detect64BitPortabilityProblems="false"
@@ -76,7 +76,7 @@
/>
<Tool
Name="VCLinkerTool"
- AdditionalDependencies="qpidcommonsd.lib qpidclientsd.lib qmfconsolesd.lib ws2_32.lib rpcrt4.lib"
+ AdditionalDependencies="qpidcommond.lib qpidclientd.lib"
OutputFile="$(OutDir)\publish.exe"
LinkIncremental="2"
SuppressStartupBanner="true"
@@ -103,8 +103,8 @@
</Configuration>
<Configuration
Name="Release|Win32"
- OutputDirectory="Static_Release"
- IntermediateDirectory="Static_Release\publish\I386"
+ OutputDirectory="Release"
+ IntermediateDirectory="Release\publish\I386"
ConfigurationType="1"
CharacterSet="0"
@@ -135,7 +135,7 @@
Optimization="2"
AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..,..\gen"
PreprocessorDefinitions="NDEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
- RuntimeLibrary="0"
+ RuntimeLibrary="2"
RuntimeTypeInfo="true"
WarningLevel="3"
Detect64BitPortabilityProblems="false"
@@ -155,7 +155,7 @@
/>
<Tool
Name="VCLinkerTool"
- AdditionalDependencies="qpidcommons.lib qpidclients.lib qmfconsoles.lib ws2_32.lib rpcrt4.lib"
+ AdditionalDependencies="qpidcommon.lib qpidclient.lib"
OutputFile="$(OutDir)\publish.exe"
LinkIncremental="1"
SuppressStartupBanner="true"
@@ -184,8 +184,8 @@
</Configuration>
<Configuration
Name="Debug|x64"
- OutputDirectory="Static_Debug"
- IntermediateDirectory="Static_Debug\publish\AMD64"
+ OutputDirectory="."
+ IntermediateDirectory="Debug\publish\AMD64"
ConfigurationType="1"
CharacterSet="0"
@@ -218,7 +218,7 @@
PreprocessorDefinitions="_DEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;_AMD64_;_WIN64;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
MinimalRebuild="false"
BasicRuntimeChecks="3"
- RuntimeLibrary="1"
+ RuntimeLibrary="3"
RuntimeTypeInfo="true"
WarningLevel="3"
Detect64BitPortabilityProblems="false"
@@ -240,7 +240,7 @@
<Tool
Name="VCLinkerTool"
AdditionalOptions="/machine:AMD64"
- AdditionalDependencies="qpidcommonsd.lib qpidclientsd.lib qmfconsolesd.lib ws2_32.lib rpcrt4.lib"
+ AdditionalDependencies="qpidcommond.lib qpidclientd.lib"
OutputFile="$(OutDir)\publish.exe"
LinkIncremental="2"
SuppressStartupBanner="true"
@@ -267,8 +267,8 @@
</Configuration>
<Configuration
Name="Release|x64"
- OutputDirectory="Static_Release"
- IntermediateDirectory="Static_Release\publish\AMD64"
+ OutputDirectory="Release"
+ IntermediateDirectory="Release\publish\AMD64"
ConfigurationType="1"
CharacterSet="0"
@@ -299,7 +299,7 @@
Optimization="2"
AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..,..\gen"
PreprocessorDefinitions="NDEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;_AMD64_;_WIN64;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
- RuntimeLibrary="0"
+ RuntimeLibrary="2"
RuntimeTypeInfo="true"
WarningLevel="3"
Detect64BitPortabilityProblems="false"
@@ -320,7 +320,7 @@
<Tool
Name="VCLinkerTool"
AdditionalOptions="/machine:AMD64"
- AdditionalDependencies="qpidcommons.lib qpidclients.lib qmfconsoles.lib ws2_32.lib rpcrt4.lib"
+ AdditionalDependencies="qpidcommon.lib qpidclient.lib"
OutputFile="$(OutDir)\publish.exe"
LinkIncremental="1"
SuppressStartupBanner="true"
diff --git a/qpid/cpp/src/tests/receiver.cpp b/qpid/cpp/src/tests/receiver.cpp
index 1ecaece51e..49f7ff0338 100644
--- a/qpid/cpp/src/tests/receiver.cpp
+++ b/qpid/cpp/src/tests/receiver.cpp
@@ -23,7 +23,7 @@
#include <qpid/client/Session.h>
#include <qpid/client/Message.h>
#include <qpid/client/SubscriptionManager.h>
-#include <qpid/client/SubscriptionManager.h>
+#include <qpid/client/SubscriptionSettings.h>
#include "TestOptions.h"
#include <iostream>
@@ -43,15 +43,17 @@ struct Args : public qpid::TestOptions
bool ignoreDuplicates;
uint creditWindow;
uint ackFrequency;
+ bool browse;
- Args() : queue("test-queue"), messages(0), ignoreDuplicates(false), creditWindow(0), ackFrequency(1)
+ Args() : queue("test-queue"), messages(0), ignoreDuplicates(false), creditWindow(0), ackFrequency(1), browse(false)
{
addOptions()
("queue", qpid::optValue(queue, "QUEUE NAME"), "Queue from which to request messages")
("messages", qpid::optValue(messages, "N"), "Number of messages to receive; 0 means receive indefinitely")
("ignore-duplicates", qpid::optValue(ignoreDuplicates), "Detect and ignore duplicates (by checking 'sn' header)")
("credit-window", qpid::optValue(creditWindow, "N"), "Credit window (0 implies infinite window)")
- ("ack-frequency", qpid::optValue(ackFrequency, "N"), "Ack frequency (0 implies none of the messages will get accepted)");
+ ("ack-frequency", qpid::optValue(ackFrequency, "N"), "Ack frequency (0 implies none of the messages will get accepted)")
+ ("browse", qpid::optValue(browse), "Browse rather than consuming");
}
};
@@ -60,7 +62,7 @@ const string EOS("eos");
class Receiver : public MessageListener, public FailoverManager::Command
{
public:
- Receiver(const string& queue, uint messages, bool ignoreDuplicates, uint creditWindow, uint ackFrequency);
+ Receiver(const string& queue, uint messages, bool ignoreDuplicates, uint creditWindow, uint ackFrequency, bool browse);
void received(Message& message);
void execute(AsyncSession& session, bool isRetry);
private:
@@ -75,9 +77,10 @@ class Receiver : public MessageListener, public FailoverManager::Command
bool isDuplicate(Message& message);
};
-Receiver::Receiver(const string& q, uint messages, bool ignoreDuplicates, uint creditWindow, uint ackFrequency) :
+Receiver::Receiver(const string& q, uint messages, bool ignoreDuplicates, uint creditWindow, uint ackFrequency, bool browse) :
queue(q), count(messages), skipDups(ignoreDuplicates), processed(0), lastSn(0)
{
+ if (browse) settings.acquireMode = ACQUIRE_MODE_NOT_ACQUIRED;
if (creditWindow) settings.flowControl = FlowControl::messageWindow(creditWindow);
settings.autoAck = ackFrequency;
}
@@ -107,6 +110,9 @@ void Receiver::execute(AsyncSession& session, bool /*isRetry*/)
SubscriptionManager subs(session);
subscription = subs.subscribe(*this, queue, settings);
subs.run();
+ if (settings.autoAck) {
+ subscription.accept(subscription.getUnaccepted());
+ }
}
int main(int argc, char ** argv)
@@ -115,7 +121,7 @@ int main(int argc, char ** argv)
try {
opts.parse(argc, argv);
FailoverManager connection(opts.con);
- Receiver receiver(opts.queue, opts.messages, opts.ignoreDuplicates, opts.creditWindow, opts.ackFrequency);
+ Receiver receiver(opts.queue, opts.messages, opts.ignoreDuplicates, opts.creditWindow, opts.ackFrequency, opts.browse);
connection.execute(receiver);
connection.close();
return 0;
diff --git a/qpid/cpp/src/tests/receiver.vcproj b/qpid/cpp/src/tests/receiver.vcproj
index 824b75d7d9..ce6fad366e 100644
--- a/qpid/cpp/src/tests/receiver.vcproj
+++ b/qpid/cpp/src/tests/receiver.vcproj
@@ -3,7 +3,7 @@
ProjectType="Visual C++"
Version="9.00"
Name="receiver"
- ProjectGUID="{7D314A98-FECA-1BAD-2235-047BCDC7409E}"
+ ProjectGUID="{7D314A98-FECA-1BAD-2431-8A11DB0D67CE}"
RootNamespace="receiver"
Keyword="Win32Proj"
SignManifests="true"
@@ -21,8 +21,8 @@
<Configurations>
<Configuration
Name="Debug|Win32"
- OutputDirectory="Static_Debug"
- IntermediateDirectory="Static_Debug\receiver\I386"
+ OutputDirectory="."
+ IntermediateDirectory="Debug\receiver\I386"
ConfigurationType="1"
CharacterSet="0"
@@ -55,7 +55,7 @@
PreprocessorDefinitions="_DEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
MinimalRebuild="false"
BasicRuntimeChecks="3"
- RuntimeLibrary="1"
+ RuntimeLibrary="3"
RuntimeTypeInfo="true"
WarningLevel="3"
Detect64BitPortabilityProblems="false"
@@ -76,7 +76,7 @@
/>
<Tool
Name="VCLinkerTool"
- AdditionalDependencies="qpidcommonsd.lib qpidclientsd.lib qmfconsolesd.lib ws2_32.lib rpcrt4.lib"
+ AdditionalDependencies="qpidcommond.lib qpidclientd.lib"
OutputFile="$(OutDir)\receiver.exe"
LinkIncremental="2"
SuppressStartupBanner="true"
@@ -103,8 +103,8 @@
</Configuration>
<Configuration
Name="Release|Win32"
- OutputDirectory="Static_Release"
- IntermediateDirectory="Static_Release\receiver\I386"
+ OutputDirectory="Release"
+ IntermediateDirectory="Release\receiver\I386"
ConfigurationType="1"
CharacterSet="0"
@@ -135,7 +135,7 @@
Optimization="2"
AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..,..\gen"
PreprocessorDefinitions="NDEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
- RuntimeLibrary="0"
+ RuntimeLibrary="2"
RuntimeTypeInfo="true"
WarningLevel="3"
Detect64BitPortabilityProblems="false"
@@ -155,7 +155,7 @@
/>
<Tool
Name="VCLinkerTool"
- AdditionalDependencies="qpidcommons.lib qpidclients.lib qmfconsoles.lib ws2_32.lib rpcrt4.lib"
+ AdditionalDependencies="qpidcommon.lib qpidclient.lib"
OutputFile="$(OutDir)\receiver.exe"
LinkIncremental="1"
SuppressStartupBanner="true"
@@ -184,8 +184,8 @@
</Configuration>
<Configuration
Name="Debug|x64"
- OutputDirectory="Static_Debug"
- IntermediateDirectory="Static_Debug\receiver\AMD64"
+ OutputDirectory="."
+ IntermediateDirectory="Debug\receiver\AMD64"
ConfigurationType="1"
CharacterSet="0"
@@ -218,7 +218,7 @@
PreprocessorDefinitions="_DEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;_AMD64_;_WIN64;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
MinimalRebuild="false"
BasicRuntimeChecks="3"
- RuntimeLibrary="1"
+ RuntimeLibrary="3"
RuntimeTypeInfo="true"
WarningLevel="3"
Detect64BitPortabilityProblems="false"
@@ -240,7 +240,7 @@
<Tool
Name="VCLinkerTool"
AdditionalOptions="/machine:AMD64"
- AdditionalDependencies="qpidcommonsd.lib qpidclientsd.lib qmfconsolesd.lib ws2_32.lib rpcrt4.lib"
+ AdditionalDependencies="qpidcommond.lib qpidclientd.lib"
OutputFile="$(OutDir)\receiver.exe"
LinkIncremental="2"
SuppressStartupBanner="true"
@@ -267,8 +267,8 @@
</Configuration>
<Configuration
Name="Release|x64"
- OutputDirectory="Static_Release"
- IntermediateDirectory="Static_Release\receiver\AMD64"
+ OutputDirectory="Release"
+ IntermediateDirectory="Release\receiver\AMD64"
ConfigurationType="1"
CharacterSet="0"
@@ -299,7 +299,7 @@
Optimization="2"
AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..,..\gen"
PreprocessorDefinitions="NDEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;_AMD64_;_WIN64;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
- RuntimeLibrary="0"
+ RuntimeLibrary="2"
RuntimeTypeInfo="true"
WarningLevel="3"
Detect64BitPortabilityProblems="false"
@@ -320,7 +320,7 @@
<Tool
Name="VCLinkerTool"
AdditionalOptions="/machine:AMD64"
- AdditionalDependencies="qpidcommons.lib qpidclients.lib qmfconsoles.lib ws2_32.lib rpcrt4.lib"
+ AdditionalDependencies="qpidcommon.lib qpidclient.lib"
OutputFile="$(OutDir)\receiver.exe"
LinkIncremental="1"
SuppressStartupBanner="true"
diff --git a/qpid/cpp/src/tests/replaying_sender.cpp b/qpid/cpp/src/tests/replaying_sender.cpp
index 7e148e277f..ea2a13bd54 100644
--- a/qpid/cpp/src/tests/replaying_sender.cpp
+++ b/qpid/cpp/src/tests/replaying_sender.cpp
@@ -60,6 +60,8 @@ Sender::Sender(const std::string& queue, uint count_, uint reportFreq ) : sender
void Sender::execute(AsyncSession& session, bool isRetry)
{
+ if (verbosity > 0)
+ std::cout << "replaying_sender " << (isRetry ? "first " : "re-") << "connect." << endl;
if (isRetry) sender.replay(session);
else sender.init(session);
while (sent < count) {
@@ -70,7 +72,7 @@ void Sender::execute(AsyncSession& session, bool isRetry)
sender.send(message);
if (count > reportFrequency && !(sent % reportFrequency)) {
if ( verbosity > 0 )
- std::cout << "sent " << sent << " of " << count << std::endl;
+ std::cout << "Sender sent " << sent << " of " << count << std::endl;
}
}
message.setData("That's all, folks!");
diff --git a/qpid/cpp/src/tests/replication_test b/qpid/cpp/src/tests/replication_test
index 9b6e5cfb29..6e0c1c8d3b 100755
--- a/qpid/cpp/src/tests/replication_test
+++ b/qpid/cpp/src/tests/replication_test
@@ -22,21 +22,20 @@
# Run a test of the replication feature
MY_DIR=`dirname \`which $0\``
PYTHON_DIR=${MY_DIR}/../../../python
-
trap stop_brokers INT TERM QUIT
stop_brokers() {
- if [[ $BROKER_A ]] ; then
+ if [ x$BROKER_A != x ]; then
../qpidd -q --port $BROKER_A
unset BROKER_A
fi
- if [[ $BROKER_B ]] ; then
+ if [ x$BROKER_B != x ]; then
../qpidd -q --port $BROKER_B
unset BROKER_B
fi
}
-if test -d ${PYTHON_DIR} && test -e ../.libs/replicating_listener.so && test -e ../.libs/replication_exchange.so ; then
+if test -d ${PYTHON_DIR} && test -f ../.libs/replicating_listener.so && test -f ../.libs/replication_exchange.so; then
rm -f queue-*.repl replication-*.log #cleanup from any earlier runs
../qpidd --daemon --port 0 --no-data-dir --no-module-dir --auth no --load-module ../.libs/replicating_listener.so --replication-queue replication --create-replication-queue true --log-enable info+ --log-to-file replication-source.log --log-to-stderr 0 > qpidd.port
@@ -44,7 +43,8 @@ if test -d ${PYTHON_DIR} && test -e ../.libs/replicating_listener.so && test -e
../qpidd --daemon --port 0 --no-data-dir --no-module-dir --auth no --load-module ../.libs/replication_exchange.so --log-enable info+ --log-to-file replication-dest.log --log-to-stderr 0 > qpidd.port
BROKER_B=`cat qpidd.port`
- export PYTHONPATH=$PYTHON_DIR
+ PYTHONPATH=$PYTHON_DIR
+ export PYTHONPATH
echo "Running replication test between localhost:$BROKER_A and localhost:$BROKER_B"
$PYTHON_DIR/commands/qpid-config -a "localhost:$BROKER_B" add exchange replication replication
@@ -55,23 +55,39 @@ if test -d ${PYTHON_DIR} && test -e ../.libs/replicating_listener.so && test -e
$PYTHON_DIR/commands/qpid-config -a "localhost:$BROKER_A" add queue queue-a --generate-queue-events 2
$PYTHON_DIR/commands/qpid-config -a "localhost:$BROKER_A" add queue queue-b --generate-queue-events 2
$PYTHON_DIR/commands/qpid-config -a "localhost:$BROKER_A" add queue queue-c --generate-queue-events 1
+ $PYTHON_DIR/commands/qpid-config -a "localhost:$BROKER_A" add queue queue-d --generate-queue-events 2
$PYTHON_DIR/commands/qpid-config -a "localhost:$BROKER_B" add queue queue-a
$PYTHON_DIR/commands/qpid-config -a "localhost:$BROKER_B" add queue queue-b
$PYTHON_DIR/commands/qpid-config -a "localhost:$BROKER_B" add queue queue-c
-
- #publish and consume from test queus on broker A:
- for i in `seq 1 10`; do echo Message $i for A >> queue-a-input.repl; done
- for i in `seq 1 20`; do echo Message $i for B >> queue-b-input.repl; done
- for i in `seq 1 15`; do echo Message $i for C >> queue-c-input.repl; done
+ #queue-d deliberately not declared on DR; this error case should be handled
+
+ #publish and consume from test queues on broker A:
+ i=1
+ while [ $i -le 10 ]; do
+ echo Message $i for A >> queue-a-input.repl
+ i=`expr $i + 1`
+ done
+ i=1
+ while [ $i -le 20 ]; do
+ echo Message $i for B >> queue-b-input.repl
+ i=`expr $i + 1`
+ done
+ i=1
+ while [ $i -le 15 ]; do
+ echo Message $i for C >> queue-c-input.repl
+ i=`expr $i + 1`
+ done
./sender --port $BROKER_A --routing-key queue-a --send-eos 1 < queue-a-input.repl
./sender --port $BROKER_A --routing-key queue-b --send-eos 1 < queue-b-input.repl
./sender --port $BROKER_A --routing-key queue-c --send-eos 1 < queue-c-input.repl
+ echo dummy | ./sender --port $BROKER_A --routing-key queue-d --send-eos 1
./receiver --port $BROKER_A --queue queue-a --messages 5 > /dev/null
./receiver --port $BROKER_A --queue queue-b --messages 10 > /dev/null
./receiver --port $BROKER_A --queue queue-c --messages 10 > /dev/null
+ ./receiver --port $BROKER_A --queue queue-d > /dev/null
#shutdown broker A then check that broker Bs versions of the queues are as expected
../qpidd -q --port $BROKER_A
@@ -90,7 +106,9 @@ if test -d ${PYTHON_DIR} && test -e ../.libs/replicating_listener.so && test -e
diff queue-b-backup.repl queue-b-expected.repl || FAIL=1
diff queue-c-backup.repl queue-c-input.repl || FAIL=1
- if [[ $FAIL ]]; then
+ grep 'queue-d does not exist' replication-dest.log > /dev/null || echo "WARNING: Expected error to be logged!"
+
+ if [ x$FAIL != x ]; then
echo replication test failed: expectations not met!
exit 1
else
diff --git a/qpid/cpp/src/tests/resuming_receiver.cpp b/qpid/cpp/src/tests/resuming_receiver.cpp
index f49a115e1e..ef559a009d 100644
--- a/qpid/cpp/src/tests/resuming_receiver.cpp
+++ b/qpid/cpp/src/tests/resuming_receiver.cpp
@@ -53,6 +53,7 @@ class Listener : public MessageListener,
bool gaps;
uint reportFrequency;
int verbosity;
+ bool done;
};
@@ -62,7 +63,8 @@ Listener::Listener(int freq, int verbosity)
lastSn(0),
gaps(false),
reportFrequency(freq),
- verbosity(verbosity)
+ verbosity(verbosity),
+ done(false)
{}
@@ -70,6 +72,7 @@ void Listener::received(Message & message)
{
if (message.getData() == "That's all, folks!")
{
+ done = true;
if(verbosity > 0 )
{
std::cout << "Shutting down listener for "
@@ -111,14 +114,14 @@ void Listener::check()
if (gaps) throw Exception("Detected gaps in sequence; messages appear to have been lost.");
}
-void Listener::execute(AsyncSession& session, bool isRetry)
-{
- if (isRetry) {
- // std::cout << "Resuming from " << count << std::endl;
+void Listener::execute(AsyncSession& session, bool isRetry) {
+ if (verbosity > 0)
+ std::cout << "resuming_receiver " << (isRetry ? "first " : "re-") << "connect." << endl;
+ if (!done) {
+ SubscriptionManager subs(session);
+ subscription = subs.subscribe(*this, "message_queue");
+ subs.run();
}
- SubscriptionManager subs(session);
- subscription = subs.subscribe(*this, "message_queue");
- subs.run();
}
void Listener::editUrlList(std::vector<Url>& urls)
diff --git a/qpid/cpp/src/tests/run_failover_soak b/qpid/cpp/src/tests/run_failover_soak
index 9dddf59cf1..36dfed79a6 100755
--- a/qpid/cpp/src/tests/run_failover_soak
+++ b/qpid/cpp/src/tests/run_failover_soak
@@ -22,8 +22,8 @@
# Check AIS requirements and run tests if found.
id -ng | grep '\<ais\>' >/dev/null || \
NOGROUP="The ais group is not your primary group."
-ps -u root | grep aisexec >/dev/null || \
- NOAISEXEC="The aisexec daemon is not running as root"
+ps -u root | grep 'aisexec\|corosync' >/dev/null || \
+ NOAISEXEC="The aisexec/corosync daemon is not running as root"
if test -n "$NOGROUP" -o -n "$NOAISEXEC"; then
cat <<EOF
@@ -47,10 +47,10 @@ host=127.0.0.1
src_root=..
module_dir=$src_root/.libs
-n_messages=300000
-report_frequency=10000
-verbosity=1
+MESSAGES=${MESSAGES:-300000}
+REPORT_FREQUENCY=${REPORT_FREQUENCY:-`expr $MESSAGES / 20`}
+VERBOSITY=${VERBOSITY:-1}
-exec `dirname $0`/failover_soak $src_root $module_dir $host ./declare_queues ./replaying_sender ./resuming_receiver $n_messages $report_frequency $verbosity
+exec ./failover_soak $src_root $module_dir $host ./declare_queues ./replaying_sender ./resuming_receiver $MESSAGES $REPORT_FREQUENCY $VERBOSITY
diff --git a/qpid/cpp/src/tests/run_header_test b/qpid/cpp/src/tests/run_header_test
index 39d4a24f84..414fecd28f 100755
--- a/qpid/cpp/src/tests/run_header_test
+++ b/qpid/cpp/src/tests/run_header_test
@@ -29,7 +29,8 @@ test -f qpidd.port && QPID_PORT=`cat qpidd.port`
if test -d ${PYTHON_DIR} ; then
./header_test -p $QPID_PORT
- export PYTHONPATH=$PYTHON_DIR:$PYTHONPATH
+ PYTHONPATH=$PYTHON_DIR:$PYTHONPATH
+ export PYTHONPATH
$srcdir/header_test.py "localhost" $QPID_PORT
else
echo "Skipping header test as python libs not found"
diff --git a/qpid/cpp/src/tests/sender.cpp b/qpid/cpp/src/tests/sender.cpp
index 48062315fe..9d9e5be99d 100644
--- a/qpid/cpp/src/tests/sender.cpp
+++ b/qpid/cpp/src/tests/sender.cpp
@@ -24,6 +24,7 @@
#include <qpid/client/AsyncSession.h>
#include <qpid/client/Message.h>
#include <qpid/client/MessageReplayTracker.h>
+#include <qpid/client/QueueOptions.h>
#include <qpid/Exception.h>
#include "TestOptions.h"
@@ -40,13 +41,17 @@ struct Args : public qpid::TestOptions
string destination;
string key;
uint sendEos;
+ bool durable;
+ string lvqMatchValue;
- Args() : key("test-queue"), sendEos(0)
+ Args() : key("test-queue"), sendEos(0), durable(false)
{
- addOptions()
+ addOptions()
("exchange", qpid::optValue(destination, "EXCHANGE"), "Exchange to send messages to")
("routing-key", qpid::optValue(key, "KEY"), "Routing key to add to messages")
- ("send-eos", qpid::optValue(sendEos, "N"), "Send N EOS messages to mark end of input");
+ ("send-eos", qpid::optValue(sendEos, "N"), "Send N EOS messages to mark end of input")
+ ("durable", qpid::optValue(durable, "true|false"), "Mark messages as durable.")
+ ("lvq-match-value", qpid::optValue(lvqMatchValue, "KEY"), "The value to set for the LVQ match key property");
}
};
@@ -55,7 +60,7 @@ const string EOS("eos");
class Sender : public FailoverManager::Command
{
public:
- Sender(const std::string& destination, const std::string& key, uint sendEos);
+ Sender(const std::string& destination, const std::string& key, uint sendEos, bool durable, const std::string& lvqMatchValue);
void execute(AsyncSession& session, bool isRetry);
private:
const std::string destination;
@@ -65,8 +70,17 @@ class Sender : public FailoverManager::Command
uint sent;
};
-Sender::Sender(const std::string& dest, const std::string& key, uint eos) :
- destination(dest), sender(10), message("", key), sendEos(eos), sent(0) {}
+Sender::Sender(const std::string& dest, const std::string& key, uint eos, bool durable, const std::string& lvqMatchValue) :
+ destination(dest), sender(10), message("", key), sendEos(eos), sent(0)
+{
+ if (durable){
+ message.getDeliveryProperties().setDeliveryMode(framing::PERSISTENT);
+ }
+
+ if (!lvqMatchValue.empty()) {
+ message.getHeaders().setString(QueueOptions::strLVQMatchProperty, lvqMatchValue);
+ }
+}
void Sender::execute(AsyncSession& session, bool isRetry)
{
@@ -90,7 +104,7 @@ int main(int argc, char ** argv)
try {
opts.parse(argc, argv);
FailoverManager connection(opts.con);
- Sender sender(opts.destination, opts.key, opts.sendEos);
+ Sender sender(opts.destination, opts.key, opts.sendEos, opts.durable, opts.lvqMatchValue);
connection.execute(sender);
connection.close();
return 0;
diff --git a/qpid/cpp/src/tests/sender.vcproj b/qpid/cpp/src/tests/sender.vcproj
index 7ae9081332..616b665406 100644
--- a/qpid/cpp/src/tests/sender.vcproj
+++ b/qpid/cpp/src/tests/sender.vcproj
@@ -3,7 +3,7 @@
ProjectType="Visual C++"
Version="9.00"
Name="sender"
- ProjectGUID="{09714CB8-FECA-1BAD-2235-047BCDC7409E}"
+ ProjectGUID="{09714CB8-FECA-1BAD-2431-8A11DB0D67CE}"
RootNamespace="sender"
Keyword="Win32Proj"
SignManifests="true"
@@ -21,8 +21,8 @@
<Configurations>
<Configuration
Name="Debug|Win32"
- OutputDirectory="Static_Debug"
- IntermediateDirectory="Static_Debug\sender\I386"
+ OutputDirectory="."
+ IntermediateDirectory="Debug\sender\I386"
ConfigurationType="1"
CharacterSet="0"
@@ -55,7 +55,7 @@
PreprocessorDefinitions="_DEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
MinimalRebuild="false"
BasicRuntimeChecks="3"
- RuntimeLibrary="1"
+ RuntimeLibrary="3"
RuntimeTypeInfo="true"
WarningLevel="3"
Detect64BitPortabilityProblems="false"
@@ -76,7 +76,7 @@
/>
<Tool
Name="VCLinkerTool"
- AdditionalDependencies="qpidcommonsd.lib qpidclientsd.lib qmfconsolesd.lib ws2_32.lib rpcrt4.lib"
+ AdditionalDependencies="qpidcommond.lib qpidclientd.lib"
OutputFile="$(OutDir)\sender.exe"
LinkIncremental="2"
SuppressStartupBanner="true"
@@ -103,8 +103,8 @@
</Configuration>
<Configuration
Name="Release|Win32"
- OutputDirectory="Static_Release"
- IntermediateDirectory="Static_Release\sender\I386"
+ OutputDirectory="Release"
+ IntermediateDirectory="Release\sender\I386"
ConfigurationType="1"
CharacterSet="0"
@@ -135,7 +135,7 @@
Optimization="2"
AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..,..\gen"
PreprocessorDefinitions="NDEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
- RuntimeLibrary="0"
+ RuntimeLibrary="2"
RuntimeTypeInfo="true"
WarningLevel="3"
Detect64BitPortabilityProblems="false"
@@ -155,7 +155,7 @@
/>
<Tool
Name="VCLinkerTool"
- AdditionalDependencies="qpidcommons.lib qpidclients.lib qmfconsoles.lib ws2_32.lib rpcrt4.lib"
+ AdditionalDependencies="qpidcommon.lib qpidclient.lib"
OutputFile="$(OutDir)\sender.exe"
LinkIncremental="1"
SuppressStartupBanner="true"
@@ -184,8 +184,8 @@
</Configuration>
<Configuration
Name="Debug|x64"
- OutputDirectory="Static_Debug"
- IntermediateDirectory="Static_Debug\sender\AMD64"
+ OutputDirectory="."
+ IntermediateDirectory="Debug\sender\AMD64"
ConfigurationType="1"
CharacterSet="0"
@@ -218,7 +218,7 @@
PreprocessorDefinitions="_DEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;_AMD64_;_WIN64;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
MinimalRebuild="false"
BasicRuntimeChecks="3"
- RuntimeLibrary="1"
+ RuntimeLibrary="3"
RuntimeTypeInfo="true"
WarningLevel="3"
Detect64BitPortabilityProblems="false"
@@ -240,7 +240,7 @@
<Tool
Name="VCLinkerTool"
AdditionalOptions="/machine:AMD64"
- AdditionalDependencies="qpidcommonsd.lib qpidclientsd.lib qmfconsolesd.lib ws2_32.lib rpcrt4.lib"
+ AdditionalDependencies="qpidcommond.lib qpidclientd.lib"
OutputFile="$(OutDir)\sender.exe"
LinkIncremental="2"
SuppressStartupBanner="true"
@@ -267,8 +267,8 @@
</Configuration>
<Configuration
Name="Release|x64"
- OutputDirectory="Static_Release"
- IntermediateDirectory="Static_Release\sender\AMD64"
+ OutputDirectory="Release"
+ IntermediateDirectory="Release\sender\AMD64"
ConfigurationType="1"
CharacterSet="0"
@@ -299,7 +299,7 @@
Optimization="2"
AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..,..\gen"
PreprocessorDefinitions="NDEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;_AMD64_;_WIN64;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
- RuntimeLibrary="0"
+ RuntimeLibrary="2"
RuntimeTypeInfo="true"
WarningLevel="3"
Detect64BitPortabilityProblems="false"
@@ -320,7 +320,7 @@
<Tool
Name="VCLinkerTool"
AdditionalOptions="/machine:AMD64"
- AdditionalDependencies="qpidcommons.lib qpidclients.lib qmfconsoles.lib ws2_32.lib rpcrt4.lib"
+ AdditionalDependencies="qpidcommon.lib qpidclient.lib"
OutputFile="$(OutDir)\sender.exe"
LinkIncremental="1"
SuppressStartupBanner="true"
diff --git a/qpid/cpp/src/tests/shlibtest.vcproj b/qpid/cpp/src/tests/shlibtest.vcproj
index b30ce30b3a..4a139a2cb5 100644
--- a/qpid/cpp/src/tests/shlibtest.vcproj
+++ b/qpid/cpp/src/tests/shlibtest.vcproj
@@ -3,7 +3,7 @@
ProjectType="Visual C++"
Version="9.00"
Name="shlibtest"
- ProjectGUID="{37AB26B9-FECA-1BAD-2235-047BCDC7409E}"
+ ProjectGUID="{37AB26B9-FECA-1BAD-2431-8A11DB0D67CE}"
RootNamespace="shlibtest"
Keyword="Win32Proj"
SignManifests="true"
@@ -22,8 +22,8 @@
<Configuration
Name="Debug|Win32"
OutputDirectory="."
- IntermediateDirectory="Static_Debug\shlibtest\I386"
- ConfigurationType="4"
+ IntermediateDirectory="Debug\shlibtest\I386"
+ ConfigurationType="2"
CharacterSet="0"
>
@@ -52,10 +52,10 @@
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\."
- PreprocessorDefinitions="_DEBUG;WIN32;_WINDOWS;_CRT_NONSTDC_NO_WARNINGS"
+ PreprocessorDefinitions="SHLIBTEST_BUILD_DLL;_DEBUG;WIN32;_WINDOWS;_CRT_NONSTDC_NO_WARNINGS"
MinimalRebuild="false"
BasicRuntimeChecks="3"
- RuntimeLibrary="1"
+ RuntimeLibrary="3"
RuntimeTypeInfo="true"
WarningLevel="3"
Detect64BitPortabilityProblems="false"
@@ -74,8 +74,16 @@
Name="VCPreLinkEventTool"
/>
<Tool
- Name="VCLibrarianTool"
- OutputFile=".\shlibtestsd.lib"
+ Name="VCLinkerTool"
+ AdditionalDependencies=""
+ OutputFile="$(OutDir)\shlibtestd.dll"
+ LinkIncremental="2"
+ SuppressStartupBanner="true"
+ AdditionalLibraryDirectories=".;$(BOOST_ROOT)\lib"
+ GenerateDebugInformation="true"
+ SubSystem="2"
+ ImportLibrary=".\shlibtestd.lib"
+ TargetMachine="1"
/>
<Tool
Name="VCALinkTool"
@@ -96,8 +104,8 @@
<Configuration
Name="Release|Win32"
OutputDirectory="."
- IntermediateDirectory="Static_Release\shlibtest\I386"
- ConfigurationType="4"
+ IntermediateDirectory="Release\shlibtest\I386"
+ ConfigurationType="2"
CharacterSet="0"
>
@@ -126,8 +134,8 @@
Name="VCCLCompilerTool"
Optimization="2"
AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\."
- PreprocessorDefinitions="NDEBUG;WIN32;_WINDOWS;_CRT_NONSTDC_NO_WARNINGS"
- RuntimeLibrary="0"
+ PreprocessorDefinitions="SHLIBTEST_BUILD_DLL;NDEBUG;WIN32;_WINDOWS;_CRT_NONSTDC_NO_WARNINGS"
+ RuntimeLibrary="2"
RuntimeTypeInfo="true"
WarningLevel="3"
Detect64BitPortabilityProblems="false"
@@ -145,8 +153,18 @@
Name="VCPreLinkEventTool"
/>
<Tool
- Name="VCLibrarianTool"
- OutputFile=".\shlibtests.lib"
+ Name="VCLinkerTool"
+ AdditionalDependencies=""
+ OutputFile="$(OutDir)\shlibtest.dll"
+ LinkIncremental="1"
+ SuppressStartupBanner="true"
+ AdditionalLibraryDirectories=".;$(BOOST_ROOT)\lib"
+ GenerateDebugInformation="true"
+ SubSystem="2"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ ImportLibrary=".\shlibtest.lib"
+ TargetMachine="1"
/>
<Tool
Name="VCALinkTool"
@@ -167,8 +185,8 @@
<Configuration
Name="Debug|x64"
OutputDirectory="."
- IntermediateDirectory="Static_Debug\shlibtest\AMD64"
- ConfigurationType="4"
+ IntermediateDirectory="Debug\shlibtest\AMD64"
+ ConfigurationType="2"
CharacterSet="0"
>
@@ -197,10 +215,10 @@
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\."
- PreprocessorDefinitions="_DEBUG;WIN32;_WINDOWS;_CRT_NONSTDC_NO_WARNINGS;_AMD64_;_WIN64"
+ PreprocessorDefinitions="SHLIBTEST_BUILD_DLL;_DEBUG;WIN32;_WINDOWS;_CRT_NONSTDC_NO_WARNINGS;_AMD64_;_WIN64"
MinimalRebuild="false"
BasicRuntimeChecks="3"
- RuntimeLibrary="1"
+ RuntimeLibrary="3"
RuntimeTypeInfo="true"
WarningLevel="3"
Detect64BitPortabilityProblems="false"
@@ -219,8 +237,17 @@
Name="VCPreLinkEventTool"
/>
<Tool
- Name="VCLibrarianTool"
- OutputFile=".\shlibtestsd.lib"
+ Name="VCLinkerTool"
+ AdditionalOptions="/machine:AMD64"
+ AdditionalDependencies=""
+ OutputFile="$(OutDir)\shlibtestd.dll"
+ LinkIncremental="2"
+ SuppressStartupBanner="true"
+ AdditionalLibraryDirectories=".;$(BOOST_ROOT)\lib"
+ GenerateDebugInformation="true"
+ SubSystem="2"
+ ImportLibrary=".\shlibtestd.lib"
+ TargetMachine="17"
/>
<Tool
Name="VCALinkTool"
@@ -241,8 +268,8 @@
<Configuration
Name="Release|x64"
OutputDirectory="."
- IntermediateDirectory="Static_Release\shlibtest\AMD64"
- ConfigurationType="4"
+ IntermediateDirectory="Release\shlibtest\AMD64"
+ ConfigurationType="2"
CharacterSet="0"
>
@@ -271,8 +298,8 @@
Name="VCCLCompilerTool"
Optimization="2"
AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\."
- PreprocessorDefinitions="NDEBUG;WIN32;_WINDOWS;_CRT_NONSTDC_NO_WARNINGS;_AMD64_;_WIN64"
- RuntimeLibrary="0"
+ PreprocessorDefinitions="SHLIBTEST_BUILD_DLL;NDEBUG;WIN32;_WINDOWS;_CRT_NONSTDC_NO_WARNINGS;_AMD64_;_WIN64"
+ RuntimeLibrary="2"
RuntimeTypeInfo="true"
WarningLevel="3"
Detect64BitPortabilityProblems="false"
@@ -290,8 +317,19 @@
Name="VCPreLinkEventTool"
/>
<Tool
- Name="VCLibrarianTool"
- OutputFile=".\shlibtests.lib"
+ Name="VCLinkerTool"
+ AdditionalOptions="/machine:AMD64"
+ AdditionalDependencies=""
+ OutputFile="$(OutDir)\shlibtest.dll"
+ LinkIncremental="1"
+ SuppressStartupBanner="true"
+ AdditionalLibraryDirectories=".;$(BOOST_ROOT)\lib"
+ GenerateDebugInformation="true"
+ SubSystem="2"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ ImportLibrary=".\shlibtest.lib"
+ TargetMachine="17"
/>
<Tool
Name="VCALinkTool"
@@ -336,6 +374,9 @@
RelativePath="BrokerFixture.h">
</File>
<File
+ RelativePath="ClusterFixture.h">
+ </File>
+ <File
RelativePath="ConnectionOptions.h">
</File>
<File
diff --git a/qpid/cpp/src/tests/ssl_test b/qpid/cpp/src/tests/ssl_test
index c7b59b62ef..13965f3a03 100755
--- a/qpid/cpp/src/tests/ssl_test
+++ b/qpid/cpp/src/tests/ssl_test
@@ -39,8 +39,7 @@ create_certs() {
}
start_broker() {
- ../qpidd --daemon --transport ssl --port 0 --ssl-port 0 --no-data-dir --no-module-dir --auth no --config $CONFIG --load-module ../.libs/ssl.so --ssl-cert-db $CERT_DIR --ssl-cert-password-file $CERT_PW_FILE > qpidd.port
- PORT=`cat qpidd.port`
+ PORT=`../qpidd --daemon --transport ssl --port 0 --ssl-port 0 --no-data-dir --no-module-dir --auth no --config $CONFIG --load-module ../.libs/ssl.so --ssl-cert-db $CERT_DIR --ssl-cert-password-file $CERT_PW_FILE`
}
stop_broker() {
diff --git a/qpid/cpp/src/tests/start_cluster b/qpid/cpp/src/tests/start_cluster
index 4f0516500c..053b23da33 100755
--- a/qpid/cpp/src/tests/start_cluster
+++ b/qpid/cpp/src/tests/start_cluster
@@ -28,11 +28,10 @@ with_ais_group() {
echo $* | newgrp ais
}
-test -f cluster.ports && { echo "cluster.ports file already exists" ; exit 1; }
rm -f cluster*.log
SIZE=${1:-1}; shift
CLUSTER=`pwd` # Cluster name=pwd, avoid clashes.
-OPTS="-d --no-module-dir --load-module ../.libs/cluster.so --cluster-name=$CLUSTER --no-data-dir --auth=no $*"
+OPTS="-d --no-module-dir --load-module ../.libs/cluster.so --cluster-name=$CLUSTER --no-data-dir --auth=no $@"
for (( i=0; i<SIZE; ++i )); do
PORT=`with_ais_group ../qpidd -p0 --log-to-file=cluster$i.log $OPTS` || exit 1
diff --git a/qpid/cpp/src/tests/tests.sln b/qpid/cpp/src/tests/tests.sln
index cee1a45292..273e90d1c8 100644
--- a/qpid/cpp/src/tests/tests.sln
+++ b/qpid/cpp/src/tests/tests.sln
@@ -7,38 +7,38 @@ Microsoft Visual Studio Solution File, Format Version 10.00
# this file will be lost the next time it is generated.
#
# MPC Command:
-# C:\ace\MPC\mwc.pl -type vc9 -features boost=1 -static tests.mwc
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "client_test", "client_test.vcproj", "{9A95F0E4-FECA-1BAD-2235-047BCDC7409E}"
+# C:\ace\MPC\mwc.pl -type vc9 -features boost=1 tests.mwc
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "client_test", "client_test.vcproj", "{9A95F0E4-FECA-1BAD-2431-8A11DB0D67CE}"
EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "consume", "consume.vcproj", "{7F5DE0A1-FECA-1BAD-2235-047BCDC7409E}"
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "consume", "consume.vcproj", "{7F5DE0A1-FECA-1BAD-2431-8A11DB0D67CE}"
EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "echotest", "echotest.vcproj", "{0A5AF6BE-FECA-1BAD-2235-047BCDC7409E}"
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "echotest", "echotest.vcproj", "{0A5AF6BE-FECA-1BAD-2431-8A11DB0D67CE}"
EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "header_test", "header_test.vcproj", "{1B23F05D-FECA-1BAD-2235-047BCDC7409E}"
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "header_test", "header_test.vcproj", "{1B23F05D-FECA-1BAD-2431-8A11DB0D67CE}"
EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "latencytest", "latencytest.vcproj", "{4A809018-FECA-1BAD-2235-047BCDC7409E}"
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "latencytest", "latencytest.vcproj", "{4A809018-FECA-1BAD-2431-8A11DB0D67CE}"
EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "perftest", "perftest.vcproj", "{1F2066BE-FECA-1BAD-2235-047BCDC7409E}"
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "perftest", "perftest.vcproj", "{1F2066BE-FECA-1BAD-2431-8A11DB0D67CE}"
EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "publish", "publish.vcproj", "{AE773E7F-FECA-1BAD-2235-047BCDC7409E}"
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "publish", "publish.vcproj", "{AE773E7F-FECA-1BAD-2431-8A11DB0D67CE}"
EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "receiver", "receiver.vcproj", "{7D314A98-FECA-1BAD-2235-047BCDC7409E}"
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "receiver", "receiver.vcproj", "{7D314A98-FECA-1BAD-2431-8A11DB0D67CE}"
EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "sender", "sender.vcproj", "{09714CB8-FECA-1BAD-2235-047BCDC7409E}"
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "sender", "sender.vcproj", "{09714CB8-FECA-1BAD-2431-8A11DB0D67CE}"
EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "shlibtest", "shlibtest.vcproj", "{37AB26B9-FECA-1BAD-2235-047BCDC7409E}"
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "shlibtest", "shlibtest.vcproj", "{37AB26B9-FECA-1BAD-2431-8A11DB0D67CE}"
EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "topic_listener", "topic_listener.vcproj", "{9392D1EE-FECA-1BAD-2235-047BCDC7409E}"
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "topic_listener", "topic_listener.vcproj", "{9392D1EE-FECA-1BAD-2431-8A11DB0D67CE}"
EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "topic_publisher", "topic_publisher.vcproj", "{7D66FE10-FECA-1BAD-2235-047BCDC7409E}"
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "topic_publisher", "topic_publisher.vcproj", "{7D66FE10-FECA-1BAD-2431-8A11DB0D67CE}"
EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "txjob", "txjob.vcproj", "{09034A53-FECA-1BAD-2235-047BCDC7409E}"
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "txjob", "txjob.vcproj", "{09034A53-FECA-1BAD-2431-8A11DB0D67CE}"
EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "txshift", "txshift.vcproj", "{6E3B2A6B-FECA-1BAD-2235-047BCDC7409E}"
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "txshift", "txshift.vcproj", "{6E3B2A6B-FECA-1BAD-2431-8A11DB0D67CE}"
EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "txtest", "txtest.vcproj", "{697786BE-FECA-1BAD-2235-047BCDC7409E}"
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "txtest", "txtest.vcproj", "{697786BE-FECA-1BAD-2431-8A11DB0D67CE}"
EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "unit_test", "unit_test.vcproj", "{51E5F6B9-FECA-1BAD-2235-047BCDC7409E}"
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "unit_test", "unit_test.vcproj", "{51E5F6B9-FECA-1BAD-2431-8A11DB0D67CE}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
@@ -48,134 +48,134 @@ Global
Release|x64 = Release|x64
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
- {9A95F0E4-FECA-1BAD-2235-047BCDC7409E}.Debug|Win32.ActiveCfg = Debug|Win32
- {9A95F0E4-FECA-1BAD-2235-047BCDC7409E}.Debug|Win32.Build.0 = Debug|Win32
- {9A95F0E4-FECA-1BAD-2235-047BCDC7409E}.Debug|x64.ActiveCfg = Debug|x64
- {9A95F0E4-FECA-1BAD-2235-047BCDC7409E}.Debug|x64.Build.0 = Debug|x64
- {9A95F0E4-FECA-1BAD-2235-047BCDC7409E}.Release|Win32.ActiveCfg = Release|Win32
- {9A95F0E4-FECA-1BAD-2235-047BCDC7409E}.Release|Win32.Build.0 = Release|Win32
- {9A95F0E4-FECA-1BAD-2235-047BCDC7409E}.Release|x64.ActiveCfg = Release|x64
- {9A95F0E4-FECA-1BAD-2235-047BCDC7409E}.Release|x64.Build.0 = Release|x64
- {7F5DE0A1-FECA-1BAD-2235-047BCDC7409E}.Debug|Win32.ActiveCfg = Debug|Win32
- {7F5DE0A1-FECA-1BAD-2235-047BCDC7409E}.Debug|Win32.Build.0 = Debug|Win32
- {7F5DE0A1-FECA-1BAD-2235-047BCDC7409E}.Debug|x64.ActiveCfg = Debug|x64
- {7F5DE0A1-FECA-1BAD-2235-047BCDC7409E}.Debug|x64.Build.0 = Debug|x64
- {7F5DE0A1-FECA-1BAD-2235-047BCDC7409E}.Release|Win32.ActiveCfg = Release|Win32
- {7F5DE0A1-FECA-1BAD-2235-047BCDC7409E}.Release|Win32.Build.0 = Release|Win32
- {7F5DE0A1-FECA-1BAD-2235-047BCDC7409E}.Release|x64.ActiveCfg = Release|x64
- {7F5DE0A1-FECA-1BAD-2235-047BCDC7409E}.Release|x64.Build.0 = Release|x64
- {0A5AF6BE-FECA-1BAD-2235-047BCDC7409E}.Debug|Win32.ActiveCfg = Debug|Win32
- {0A5AF6BE-FECA-1BAD-2235-047BCDC7409E}.Debug|Win32.Build.0 = Debug|Win32
- {0A5AF6BE-FECA-1BAD-2235-047BCDC7409E}.Debug|x64.ActiveCfg = Debug|x64
- {0A5AF6BE-FECA-1BAD-2235-047BCDC7409E}.Debug|x64.Build.0 = Debug|x64
- {0A5AF6BE-FECA-1BAD-2235-047BCDC7409E}.Release|Win32.ActiveCfg = Release|Win32
- {0A5AF6BE-FECA-1BAD-2235-047BCDC7409E}.Release|Win32.Build.0 = Release|Win32
- {0A5AF6BE-FECA-1BAD-2235-047BCDC7409E}.Release|x64.ActiveCfg = Release|x64
- {0A5AF6BE-FECA-1BAD-2235-047BCDC7409E}.Release|x64.Build.0 = Release|x64
- {1B23F05D-FECA-1BAD-2235-047BCDC7409E}.Debug|Win32.ActiveCfg = Debug|Win32
- {1B23F05D-FECA-1BAD-2235-047BCDC7409E}.Debug|Win32.Build.0 = Debug|Win32
- {1B23F05D-FECA-1BAD-2235-047BCDC7409E}.Debug|x64.ActiveCfg = Debug|x64
- {1B23F05D-FECA-1BAD-2235-047BCDC7409E}.Debug|x64.Build.0 = Debug|x64
- {1B23F05D-FECA-1BAD-2235-047BCDC7409E}.Release|Win32.ActiveCfg = Release|Win32
- {1B23F05D-FECA-1BAD-2235-047BCDC7409E}.Release|Win32.Build.0 = Release|Win32
- {1B23F05D-FECA-1BAD-2235-047BCDC7409E}.Release|x64.ActiveCfg = Release|x64
- {1B23F05D-FECA-1BAD-2235-047BCDC7409E}.Release|x64.Build.0 = Release|x64
- {4A809018-FECA-1BAD-2235-047BCDC7409E}.Debug|Win32.ActiveCfg = Debug|Win32
- {4A809018-FECA-1BAD-2235-047BCDC7409E}.Debug|Win32.Build.0 = Debug|Win32
- {4A809018-FECA-1BAD-2235-047BCDC7409E}.Debug|x64.ActiveCfg = Debug|x64
- {4A809018-FECA-1BAD-2235-047BCDC7409E}.Debug|x64.Build.0 = Debug|x64
- {4A809018-FECA-1BAD-2235-047BCDC7409E}.Release|Win32.ActiveCfg = Release|Win32
- {4A809018-FECA-1BAD-2235-047BCDC7409E}.Release|Win32.Build.0 = Release|Win32
- {4A809018-FECA-1BAD-2235-047BCDC7409E}.Release|x64.ActiveCfg = Release|x64
- {4A809018-FECA-1BAD-2235-047BCDC7409E}.Release|x64.Build.0 = Release|x64
- {1F2066BE-FECA-1BAD-2235-047BCDC7409E}.Debug|Win32.ActiveCfg = Debug|Win32
- {1F2066BE-FECA-1BAD-2235-047BCDC7409E}.Debug|Win32.Build.0 = Debug|Win32
- {1F2066BE-FECA-1BAD-2235-047BCDC7409E}.Debug|x64.ActiveCfg = Debug|x64
- {1F2066BE-FECA-1BAD-2235-047BCDC7409E}.Debug|x64.Build.0 = Debug|x64
- {1F2066BE-FECA-1BAD-2235-047BCDC7409E}.Release|Win32.ActiveCfg = Release|Win32
- {1F2066BE-FECA-1BAD-2235-047BCDC7409E}.Release|Win32.Build.0 = Release|Win32
- {1F2066BE-FECA-1BAD-2235-047BCDC7409E}.Release|x64.ActiveCfg = Release|x64
- {1F2066BE-FECA-1BAD-2235-047BCDC7409E}.Release|x64.Build.0 = Release|x64
- {AE773E7F-FECA-1BAD-2235-047BCDC7409E}.Debug|Win32.ActiveCfg = Debug|Win32
- {AE773E7F-FECA-1BAD-2235-047BCDC7409E}.Debug|Win32.Build.0 = Debug|Win32
- {AE773E7F-FECA-1BAD-2235-047BCDC7409E}.Debug|x64.ActiveCfg = Debug|x64
- {AE773E7F-FECA-1BAD-2235-047BCDC7409E}.Debug|x64.Build.0 = Debug|x64
- {AE773E7F-FECA-1BAD-2235-047BCDC7409E}.Release|Win32.ActiveCfg = Release|Win32
- {AE773E7F-FECA-1BAD-2235-047BCDC7409E}.Release|Win32.Build.0 = Release|Win32
- {AE773E7F-FECA-1BAD-2235-047BCDC7409E}.Release|x64.ActiveCfg = Release|x64
- {AE773E7F-FECA-1BAD-2235-047BCDC7409E}.Release|x64.Build.0 = Release|x64
- {7D314A98-FECA-1BAD-2235-047BCDC7409E}.Debug|Win32.ActiveCfg = Debug|Win32
- {7D314A98-FECA-1BAD-2235-047BCDC7409E}.Debug|Win32.Build.0 = Debug|Win32
- {7D314A98-FECA-1BAD-2235-047BCDC7409E}.Debug|x64.ActiveCfg = Debug|x64
- {7D314A98-FECA-1BAD-2235-047BCDC7409E}.Debug|x64.Build.0 = Debug|x64
- {7D314A98-FECA-1BAD-2235-047BCDC7409E}.Release|Win32.ActiveCfg = Release|Win32
- {7D314A98-FECA-1BAD-2235-047BCDC7409E}.Release|Win32.Build.0 = Release|Win32
- {7D314A98-FECA-1BAD-2235-047BCDC7409E}.Release|x64.ActiveCfg = Release|x64
- {7D314A98-FECA-1BAD-2235-047BCDC7409E}.Release|x64.Build.0 = Release|x64
- {09714CB8-FECA-1BAD-2235-047BCDC7409E}.Debug|Win32.ActiveCfg = Debug|Win32
- {09714CB8-FECA-1BAD-2235-047BCDC7409E}.Debug|Win32.Build.0 = Debug|Win32
- {09714CB8-FECA-1BAD-2235-047BCDC7409E}.Debug|x64.ActiveCfg = Debug|x64
- {09714CB8-FECA-1BAD-2235-047BCDC7409E}.Debug|x64.Build.0 = Debug|x64
- {09714CB8-FECA-1BAD-2235-047BCDC7409E}.Release|Win32.ActiveCfg = Release|Win32
- {09714CB8-FECA-1BAD-2235-047BCDC7409E}.Release|Win32.Build.0 = Release|Win32
- {09714CB8-FECA-1BAD-2235-047BCDC7409E}.Release|x64.ActiveCfg = Release|x64
- {09714CB8-FECA-1BAD-2235-047BCDC7409E}.Release|x64.Build.0 = Release|x64
- {37AB26B9-FECA-1BAD-2235-047BCDC7409E}.Debug|Win32.ActiveCfg = Debug|Win32
- {37AB26B9-FECA-1BAD-2235-047BCDC7409E}.Debug|Win32.Build.0 = Debug|Win32
- {37AB26B9-FECA-1BAD-2235-047BCDC7409E}.Debug|x64.ActiveCfg = Debug|x64
- {37AB26B9-FECA-1BAD-2235-047BCDC7409E}.Debug|x64.Build.0 = Debug|x64
- {37AB26B9-FECA-1BAD-2235-047BCDC7409E}.Release|Win32.ActiveCfg = Release|Win32
- {37AB26B9-FECA-1BAD-2235-047BCDC7409E}.Release|Win32.Build.0 = Release|Win32
- {37AB26B9-FECA-1BAD-2235-047BCDC7409E}.Release|x64.ActiveCfg = Release|x64
- {37AB26B9-FECA-1BAD-2235-047BCDC7409E}.Release|x64.Build.0 = Release|x64
- {9392D1EE-FECA-1BAD-2235-047BCDC7409E}.Debug|Win32.ActiveCfg = Debug|Win32
- {9392D1EE-FECA-1BAD-2235-047BCDC7409E}.Debug|Win32.Build.0 = Debug|Win32
- {9392D1EE-FECA-1BAD-2235-047BCDC7409E}.Debug|x64.ActiveCfg = Debug|x64
- {9392D1EE-FECA-1BAD-2235-047BCDC7409E}.Debug|x64.Build.0 = Debug|x64
- {9392D1EE-FECA-1BAD-2235-047BCDC7409E}.Release|Win32.ActiveCfg = Release|Win32
- {9392D1EE-FECA-1BAD-2235-047BCDC7409E}.Release|Win32.Build.0 = Release|Win32
- {9392D1EE-FECA-1BAD-2235-047BCDC7409E}.Release|x64.ActiveCfg = Release|x64
- {9392D1EE-FECA-1BAD-2235-047BCDC7409E}.Release|x64.Build.0 = Release|x64
- {7D66FE10-FECA-1BAD-2235-047BCDC7409E}.Debug|Win32.ActiveCfg = Debug|Win32
- {7D66FE10-FECA-1BAD-2235-047BCDC7409E}.Debug|Win32.Build.0 = Debug|Win32
- {7D66FE10-FECA-1BAD-2235-047BCDC7409E}.Debug|x64.ActiveCfg = Debug|x64
- {7D66FE10-FECA-1BAD-2235-047BCDC7409E}.Debug|x64.Build.0 = Debug|x64
- {7D66FE10-FECA-1BAD-2235-047BCDC7409E}.Release|Win32.ActiveCfg = Release|Win32
- {7D66FE10-FECA-1BAD-2235-047BCDC7409E}.Release|Win32.Build.0 = Release|Win32
- {7D66FE10-FECA-1BAD-2235-047BCDC7409E}.Release|x64.ActiveCfg = Release|x64
- {7D66FE10-FECA-1BAD-2235-047BCDC7409E}.Release|x64.Build.0 = Release|x64
- {09034A53-FECA-1BAD-2235-047BCDC7409E}.Debug|Win32.ActiveCfg = Debug|Win32
- {09034A53-FECA-1BAD-2235-047BCDC7409E}.Debug|Win32.Build.0 = Debug|Win32
- {09034A53-FECA-1BAD-2235-047BCDC7409E}.Debug|x64.ActiveCfg = Debug|x64
- {09034A53-FECA-1BAD-2235-047BCDC7409E}.Debug|x64.Build.0 = Debug|x64
- {09034A53-FECA-1BAD-2235-047BCDC7409E}.Release|Win32.ActiveCfg = Release|Win32
- {09034A53-FECA-1BAD-2235-047BCDC7409E}.Release|Win32.Build.0 = Release|Win32
- {09034A53-FECA-1BAD-2235-047BCDC7409E}.Release|x64.ActiveCfg = Release|x64
- {09034A53-FECA-1BAD-2235-047BCDC7409E}.Release|x64.Build.0 = Release|x64
- {6E3B2A6B-FECA-1BAD-2235-047BCDC7409E}.Debug|Win32.ActiveCfg = Debug|Win32
- {6E3B2A6B-FECA-1BAD-2235-047BCDC7409E}.Debug|Win32.Build.0 = Debug|Win32
- {6E3B2A6B-FECA-1BAD-2235-047BCDC7409E}.Debug|x64.ActiveCfg = Debug|x64
- {6E3B2A6B-FECA-1BAD-2235-047BCDC7409E}.Debug|x64.Build.0 = Debug|x64
- {6E3B2A6B-FECA-1BAD-2235-047BCDC7409E}.Release|Win32.ActiveCfg = Release|Win32
- {6E3B2A6B-FECA-1BAD-2235-047BCDC7409E}.Release|Win32.Build.0 = Release|Win32
- {6E3B2A6B-FECA-1BAD-2235-047BCDC7409E}.Release|x64.ActiveCfg = Release|x64
- {6E3B2A6B-FECA-1BAD-2235-047BCDC7409E}.Release|x64.Build.0 = Release|x64
- {697786BE-FECA-1BAD-2235-047BCDC7409E}.Debug|Win32.ActiveCfg = Debug|Win32
- {697786BE-FECA-1BAD-2235-047BCDC7409E}.Debug|Win32.Build.0 = Debug|Win32
- {697786BE-FECA-1BAD-2235-047BCDC7409E}.Debug|x64.ActiveCfg = Debug|x64
- {697786BE-FECA-1BAD-2235-047BCDC7409E}.Debug|x64.Build.0 = Debug|x64
- {697786BE-FECA-1BAD-2235-047BCDC7409E}.Release|Win32.ActiveCfg = Release|Win32
- {697786BE-FECA-1BAD-2235-047BCDC7409E}.Release|Win32.Build.0 = Release|Win32
- {697786BE-FECA-1BAD-2235-047BCDC7409E}.Release|x64.ActiveCfg = Release|x64
- {697786BE-FECA-1BAD-2235-047BCDC7409E}.Release|x64.Build.0 = Release|x64
- {51E5F6B9-FECA-1BAD-2235-047BCDC7409E}.Debug|Win32.ActiveCfg = Debug|Win32
- {51E5F6B9-FECA-1BAD-2235-047BCDC7409E}.Debug|Win32.Build.0 = Debug|Win32
- {51E5F6B9-FECA-1BAD-2235-047BCDC7409E}.Debug|x64.ActiveCfg = Debug|x64
- {51E5F6B9-FECA-1BAD-2235-047BCDC7409E}.Debug|x64.Build.0 = Debug|x64
- {51E5F6B9-FECA-1BAD-2235-047BCDC7409E}.Release|Win32.ActiveCfg = Release|Win32
- {51E5F6B9-FECA-1BAD-2235-047BCDC7409E}.Release|Win32.Build.0 = Release|Win32
- {51E5F6B9-FECA-1BAD-2235-047BCDC7409E}.Release|x64.ActiveCfg = Release|x64
- {51E5F6B9-FECA-1BAD-2235-047BCDC7409E}.Release|x64.Build.0 = Release|x64
+ {9A95F0E4-FECA-1BAD-2431-8A11DB0D67CE}.Debug|Win32.ActiveCfg = Debug|Win32
+ {9A95F0E4-FECA-1BAD-2431-8A11DB0D67CE}.Debug|Win32.Build.0 = Debug|Win32
+ {9A95F0E4-FECA-1BAD-2431-8A11DB0D67CE}.Debug|x64.ActiveCfg = Debug|x64
+ {9A95F0E4-FECA-1BAD-2431-8A11DB0D67CE}.Debug|x64.Build.0 = Debug|x64
+ {9A95F0E4-FECA-1BAD-2431-8A11DB0D67CE}.Release|Win32.ActiveCfg = Release|Win32
+ {9A95F0E4-FECA-1BAD-2431-8A11DB0D67CE}.Release|Win32.Build.0 = Release|Win32
+ {9A95F0E4-FECA-1BAD-2431-8A11DB0D67CE}.Release|x64.ActiveCfg = Release|x64
+ {9A95F0E4-FECA-1BAD-2431-8A11DB0D67CE}.Release|x64.Build.0 = Release|x64
+ {7F5DE0A1-FECA-1BAD-2431-8A11DB0D67CE}.Debug|Win32.ActiveCfg = Debug|Win32
+ {7F5DE0A1-FECA-1BAD-2431-8A11DB0D67CE}.Debug|Win32.Build.0 = Debug|Win32
+ {7F5DE0A1-FECA-1BAD-2431-8A11DB0D67CE}.Debug|x64.ActiveCfg = Debug|x64
+ {7F5DE0A1-FECA-1BAD-2431-8A11DB0D67CE}.Debug|x64.Build.0 = Debug|x64
+ {7F5DE0A1-FECA-1BAD-2431-8A11DB0D67CE}.Release|Win32.ActiveCfg = Release|Win32
+ {7F5DE0A1-FECA-1BAD-2431-8A11DB0D67CE}.Release|Win32.Build.0 = Release|Win32
+ {7F5DE0A1-FECA-1BAD-2431-8A11DB0D67CE}.Release|x64.ActiveCfg = Release|x64
+ {7F5DE0A1-FECA-1BAD-2431-8A11DB0D67CE}.Release|x64.Build.0 = Release|x64
+ {0A5AF6BE-FECA-1BAD-2431-8A11DB0D67CE}.Debug|Win32.ActiveCfg = Debug|Win32
+ {0A5AF6BE-FECA-1BAD-2431-8A11DB0D67CE}.Debug|Win32.Build.0 = Debug|Win32
+ {0A5AF6BE-FECA-1BAD-2431-8A11DB0D67CE}.Debug|x64.ActiveCfg = Debug|x64
+ {0A5AF6BE-FECA-1BAD-2431-8A11DB0D67CE}.Debug|x64.Build.0 = Debug|x64
+ {0A5AF6BE-FECA-1BAD-2431-8A11DB0D67CE}.Release|Win32.ActiveCfg = Release|Win32
+ {0A5AF6BE-FECA-1BAD-2431-8A11DB0D67CE}.Release|Win32.Build.0 = Release|Win32
+ {0A5AF6BE-FECA-1BAD-2431-8A11DB0D67CE}.Release|x64.ActiveCfg = Release|x64
+ {0A5AF6BE-FECA-1BAD-2431-8A11DB0D67CE}.Release|x64.Build.0 = Release|x64
+ {1B23F05D-FECA-1BAD-2431-8A11DB0D67CE}.Debug|Win32.ActiveCfg = Debug|Win32
+ {1B23F05D-FECA-1BAD-2431-8A11DB0D67CE}.Debug|Win32.Build.0 = Debug|Win32
+ {1B23F05D-FECA-1BAD-2431-8A11DB0D67CE}.Debug|x64.ActiveCfg = Debug|x64
+ {1B23F05D-FECA-1BAD-2431-8A11DB0D67CE}.Debug|x64.Build.0 = Debug|x64
+ {1B23F05D-FECA-1BAD-2431-8A11DB0D67CE}.Release|Win32.ActiveCfg = Release|Win32
+ {1B23F05D-FECA-1BAD-2431-8A11DB0D67CE}.Release|Win32.Build.0 = Release|Win32
+ {1B23F05D-FECA-1BAD-2431-8A11DB0D67CE}.Release|x64.ActiveCfg = Release|x64
+ {1B23F05D-FECA-1BAD-2431-8A11DB0D67CE}.Release|x64.Build.0 = Release|x64
+ {4A809018-FECA-1BAD-2431-8A11DB0D67CE}.Debug|Win32.ActiveCfg = Debug|Win32
+ {4A809018-FECA-1BAD-2431-8A11DB0D67CE}.Debug|Win32.Build.0 = Debug|Win32
+ {4A809018-FECA-1BAD-2431-8A11DB0D67CE}.Debug|x64.ActiveCfg = Debug|x64
+ {4A809018-FECA-1BAD-2431-8A11DB0D67CE}.Debug|x64.Build.0 = Debug|x64
+ {4A809018-FECA-1BAD-2431-8A11DB0D67CE}.Release|Win32.ActiveCfg = Release|Win32
+ {4A809018-FECA-1BAD-2431-8A11DB0D67CE}.Release|Win32.Build.0 = Release|Win32
+ {4A809018-FECA-1BAD-2431-8A11DB0D67CE}.Release|x64.ActiveCfg = Release|x64
+ {4A809018-FECA-1BAD-2431-8A11DB0D67CE}.Release|x64.Build.0 = Release|x64
+ {1F2066BE-FECA-1BAD-2431-8A11DB0D67CE}.Debug|Win32.ActiveCfg = Debug|Win32
+ {1F2066BE-FECA-1BAD-2431-8A11DB0D67CE}.Debug|Win32.Build.0 = Debug|Win32
+ {1F2066BE-FECA-1BAD-2431-8A11DB0D67CE}.Debug|x64.ActiveCfg = Debug|x64
+ {1F2066BE-FECA-1BAD-2431-8A11DB0D67CE}.Debug|x64.Build.0 = Debug|x64
+ {1F2066BE-FECA-1BAD-2431-8A11DB0D67CE}.Release|Win32.ActiveCfg = Release|Win32
+ {1F2066BE-FECA-1BAD-2431-8A11DB0D67CE}.Release|Win32.Build.0 = Release|Win32
+ {1F2066BE-FECA-1BAD-2431-8A11DB0D67CE}.Release|x64.ActiveCfg = Release|x64
+ {1F2066BE-FECA-1BAD-2431-8A11DB0D67CE}.Release|x64.Build.0 = Release|x64
+ {AE773E7F-FECA-1BAD-2431-8A11DB0D67CE}.Debug|Win32.ActiveCfg = Debug|Win32
+ {AE773E7F-FECA-1BAD-2431-8A11DB0D67CE}.Debug|Win32.Build.0 = Debug|Win32
+ {AE773E7F-FECA-1BAD-2431-8A11DB0D67CE}.Debug|x64.ActiveCfg = Debug|x64
+ {AE773E7F-FECA-1BAD-2431-8A11DB0D67CE}.Debug|x64.Build.0 = Debug|x64
+ {AE773E7F-FECA-1BAD-2431-8A11DB0D67CE}.Release|Win32.ActiveCfg = Release|Win32
+ {AE773E7F-FECA-1BAD-2431-8A11DB0D67CE}.Release|Win32.Build.0 = Release|Win32
+ {AE773E7F-FECA-1BAD-2431-8A11DB0D67CE}.Release|x64.ActiveCfg = Release|x64
+ {AE773E7F-FECA-1BAD-2431-8A11DB0D67CE}.Release|x64.Build.0 = Release|x64
+ {7D314A98-FECA-1BAD-2431-8A11DB0D67CE}.Debug|Win32.ActiveCfg = Debug|Win32
+ {7D314A98-FECA-1BAD-2431-8A11DB0D67CE}.Debug|Win32.Build.0 = Debug|Win32
+ {7D314A98-FECA-1BAD-2431-8A11DB0D67CE}.Debug|x64.ActiveCfg = Debug|x64
+ {7D314A98-FECA-1BAD-2431-8A11DB0D67CE}.Debug|x64.Build.0 = Debug|x64
+ {7D314A98-FECA-1BAD-2431-8A11DB0D67CE}.Release|Win32.ActiveCfg = Release|Win32
+ {7D314A98-FECA-1BAD-2431-8A11DB0D67CE}.Release|Win32.Build.0 = Release|Win32
+ {7D314A98-FECA-1BAD-2431-8A11DB0D67CE}.Release|x64.ActiveCfg = Release|x64
+ {7D314A98-FECA-1BAD-2431-8A11DB0D67CE}.Release|x64.Build.0 = Release|x64
+ {09714CB8-FECA-1BAD-2431-8A11DB0D67CE}.Debug|Win32.ActiveCfg = Debug|Win32
+ {09714CB8-FECA-1BAD-2431-8A11DB0D67CE}.Debug|Win32.Build.0 = Debug|Win32
+ {09714CB8-FECA-1BAD-2431-8A11DB0D67CE}.Debug|x64.ActiveCfg = Debug|x64
+ {09714CB8-FECA-1BAD-2431-8A11DB0D67CE}.Debug|x64.Build.0 = Debug|x64
+ {09714CB8-FECA-1BAD-2431-8A11DB0D67CE}.Release|Win32.ActiveCfg = Release|Win32
+ {09714CB8-FECA-1BAD-2431-8A11DB0D67CE}.Release|Win32.Build.0 = Release|Win32
+ {09714CB8-FECA-1BAD-2431-8A11DB0D67CE}.Release|x64.ActiveCfg = Release|x64
+ {09714CB8-FECA-1BAD-2431-8A11DB0D67CE}.Release|x64.Build.0 = Release|x64
+ {37AB26B9-FECA-1BAD-2431-8A11DB0D67CE}.Debug|Win32.ActiveCfg = Debug|Win32
+ {37AB26B9-FECA-1BAD-2431-8A11DB0D67CE}.Debug|Win32.Build.0 = Debug|Win32
+ {37AB26B9-FECA-1BAD-2431-8A11DB0D67CE}.Debug|x64.ActiveCfg = Debug|x64
+ {37AB26B9-FECA-1BAD-2431-8A11DB0D67CE}.Debug|x64.Build.0 = Debug|x64
+ {37AB26B9-FECA-1BAD-2431-8A11DB0D67CE}.Release|Win32.ActiveCfg = Release|Win32
+ {37AB26B9-FECA-1BAD-2431-8A11DB0D67CE}.Release|Win32.Build.0 = Release|Win32
+ {37AB26B9-FECA-1BAD-2431-8A11DB0D67CE}.Release|x64.ActiveCfg = Release|x64
+ {37AB26B9-FECA-1BAD-2431-8A11DB0D67CE}.Release|x64.Build.0 = Release|x64
+ {9392D1EE-FECA-1BAD-2431-8A11DB0D67CE}.Debug|Win32.ActiveCfg = Debug|Win32
+ {9392D1EE-FECA-1BAD-2431-8A11DB0D67CE}.Debug|Win32.Build.0 = Debug|Win32
+ {9392D1EE-FECA-1BAD-2431-8A11DB0D67CE}.Debug|x64.ActiveCfg = Debug|x64
+ {9392D1EE-FECA-1BAD-2431-8A11DB0D67CE}.Debug|x64.Build.0 = Debug|x64
+ {9392D1EE-FECA-1BAD-2431-8A11DB0D67CE}.Release|Win32.ActiveCfg = Release|Win32
+ {9392D1EE-FECA-1BAD-2431-8A11DB0D67CE}.Release|Win32.Build.0 = Release|Win32
+ {9392D1EE-FECA-1BAD-2431-8A11DB0D67CE}.Release|x64.ActiveCfg = Release|x64
+ {9392D1EE-FECA-1BAD-2431-8A11DB0D67CE}.Release|x64.Build.0 = Release|x64
+ {7D66FE10-FECA-1BAD-2431-8A11DB0D67CE}.Debug|Win32.ActiveCfg = Debug|Win32
+ {7D66FE10-FECA-1BAD-2431-8A11DB0D67CE}.Debug|Win32.Build.0 = Debug|Win32
+ {7D66FE10-FECA-1BAD-2431-8A11DB0D67CE}.Debug|x64.ActiveCfg = Debug|x64
+ {7D66FE10-FECA-1BAD-2431-8A11DB0D67CE}.Debug|x64.Build.0 = Debug|x64
+ {7D66FE10-FECA-1BAD-2431-8A11DB0D67CE}.Release|Win32.ActiveCfg = Release|Win32
+ {7D66FE10-FECA-1BAD-2431-8A11DB0D67CE}.Release|Win32.Build.0 = Release|Win32
+ {7D66FE10-FECA-1BAD-2431-8A11DB0D67CE}.Release|x64.ActiveCfg = Release|x64
+ {7D66FE10-FECA-1BAD-2431-8A11DB0D67CE}.Release|x64.Build.0 = Release|x64
+ {09034A53-FECA-1BAD-2431-8A11DB0D67CE}.Debug|Win32.ActiveCfg = Debug|Win32
+ {09034A53-FECA-1BAD-2431-8A11DB0D67CE}.Debug|Win32.Build.0 = Debug|Win32
+ {09034A53-FECA-1BAD-2431-8A11DB0D67CE}.Debug|x64.ActiveCfg = Debug|x64
+ {09034A53-FECA-1BAD-2431-8A11DB0D67CE}.Debug|x64.Build.0 = Debug|x64
+ {09034A53-FECA-1BAD-2431-8A11DB0D67CE}.Release|Win32.ActiveCfg = Release|Win32
+ {09034A53-FECA-1BAD-2431-8A11DB0D67CE}.Release|Win32.Build.0 = Release|Win32
+ {09034A53-FECA-1BAD-2431-8A11DB0D67CE}.Release|x64.ActiveCfg = Release|x64
+ {09034A53-FECA-1BAD-2431-8A11DB0D67CE}.Release|x64.Build.0 = Release|x64
+ {6E3B2A6B-FECA-1BAD-2431-8A11DB0D67CE}.Debug|Win32.ActiveCfg = Debug|Win32
+ {6E3B2A6B-FECA-1BAD-2431-8A11DB0D67CE}.Debug|Win32.Build.0 = Debug|Win32
+ {6E3B2A6B-FECA-1BAD-2431-8A11DB0D67CE}.Debug|x64.ActiveCfg = Debug|x64
+ {6E3B2A6B-FECA-1BAD-2431-8A11DB0D67CE}.Debug|x64.Build.0 = Debug|x64
+ {6E3B2A6B-FECA-1BAD-2431-8A11DB0D67CE}.Release|Win32.ActiveCfg = Release|Win32
+ {6E3B2A6B-FECA-1BAD-2431-8A11DB0D67CE}.Release|Win32.Build.0 = Release|Win32
+ {6E3B2A6B-FECA-1BAD-2431-8A11DB0D67CE}.Release|x64.ActiveCfg = Release|x64
+ {6E3B2A6B-FECA-1BAD-2431-8A11DB0D67CE}.Release|x64.Build.0 = Release|x64
+ {697786BE-FECA-1BAD-2431-8A11DB0D67CE}.Debug|Win32.ActiveCfg = Debug|Win32
+ {697786BE-FECA-1BAD-2431-8A11DB0D67CE}.Debug|Win32.Build.0 = Debug|Win32
+ {697786BE-FECA-1BAD-2431-8A11DB0D67CE}.Debug|x64.ActiveCfg = Debug|x64
+ {697786BE-FECA-1BAD-2431-8A11DB0D67CE}.Debug|x64.Build.0 = Debug|x64
+ {697786BE-FECA-1BAD-2431-8A11DB0D67CE}.Release|Win32.ActiveCfg = Release|Win32
+ {697786BE-FECA-1BAD-2431-8A11DB0D67CE}.Release|Win32.Build.0 = Release|Win32
+ {697786BE-FECA-1BAD-2431-8A11DB0D67CE}.Release|x64.ActiveCfg = Release|x64
+ {697786BE-FECA-1BAD-2431-8A11DB0D67CE}.Release|x64.Build.0 = Release|x64
+ {51E5F6B9-FECA-1BAD-2431-8A11DB0D67CE}.Debug|Win32.ActiveCfg = Debug|Win32
+ {51E5F6B9-FECA-1BAD-2431-8A11DB0D67CE}.Debug|Win32.Build.0 = Debug|Win32
+ {51E5F6B9-FECA-1BAD-2431-8A11DB0D67CE}.Debug|x64.ActiveCfg = Debug|x64
+ {51E5F6B9-FECA-1BAD-2431-8A11DB0D67CE}.Debug|x64.Build.0 = Debug|x64
+ {51E5F6B9-FECA-1BAD-2431-8A11DB0D67CE}.Release|Win32.ActiveCfg = Release|Win32
+ {51E5F6B9-FECA-1BAD-2431-8A11DB0D67CE}.Release|Win32.Build.0 = Release|Win32
+ {51E5F6B9-FECA-1BAD-2431-8A11DB0D67CE}.Release|x64.ActiveCfg = Release|x64
+ {51E5F6B9-FECA-1BAD-2431-8A11DB0D67CE}.Release|x64.Build.0 = Release|x64
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
diff --git a/qpid/cpp/src/tests/topic_listener.cpp b/qpid/cpp/src/tests/topic_listener.cpp
index 7bdc2c32de..1f0b3f5377 100644
--- a/qpid/cpp/src/tests/topic_listener.cpp
+++ b/qpid/cpp/src/tests/topic_listener.cpp
@@ -37,6 +37,7 @@
#include "qpid/client/MessageListener.h"
#include "qpid/client/Session.h"
#include "qpid/client/SubscriptionManager.h"
+#include "qpid/sys/SystemInfo.h"
#include "qpid/sys/Time.h"
#include "qpid/framing/FieldValue.h"
#include <iostream>
@@ -132,7 +133,7 @@ int main(int argc, char** argv){
if( args.statusqueue.length() > 0 ) {
stringstream msg_str;
- msg_str << "topic_listener: " << (int)getpid();
+ msg_str << "topic_listener: " << qpid::sys::SystemInfo::getProcessId();
session.messageTransfer(arg::content=Message(msg_str.str(), args.statusqueue));
cout << "Ready status put on queue '" << args.statusqueue << "'" << endl;
}
diff --git a/qpid/cpp/src/tests/topic_listener.vcproj b/qpid/cpp/src/tests/topic_listener.vcproj
index eedfe14687..0be31b8348 100644
--- a/qpid/cpp/src/tests/topic_listener.vcproj
+++ b/qpid/cpp/src/tests/topic_listener.vcproj
@@ -3,7 +3,7 @@
ProjectType="Visual C++"
Version="9.00"
Name="topic_listener"
- ProjectGUID="{9392D1EE-FECA-1BAD-2235-047BCDC7409E}"
+ ProjectGUID="{9392D1EE-FECA-1BAD-2431-8A11DB0D67CE}"
RootNamespace="topic_listener"
Keyword="Win32Proj"
SignManifests="true"
@@ -21,8 +21,8 @@
<Configurations>
<Configuration
Name="Debug|Win32"
- OutputDirectory="Static_Debug"
- IntermediateDirectory="Static_Debug\topic_listener\I386"
+ OutputDirectory="."
+ IntermediateDirectory="Debug\topic_listener\I386"
ConfigurationType="1"
CharacterSet="0"
@@ -55,7 +55,7 @@
PreprocessorDefinitions="_DEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
MinimalRebuild="false"
BasicRuntimeChecks="3"
- RuntimeLibrary="1"
+ RuntimeLibrary="3"
RuntimeTypeInfo="true"
WarningLevel="3"
Detect64BitPortabilityProblems="false"
@@ -76,7 +76,7 @@
/>
<Tool
Name="VCLinkerTool"
- AdditionalDependencies="qpidcommonsd.lib qpidclientsd.lib qmfconsolesd.lib ws2_32.lib rpcrt4.lib"
+ AdditionalDependencies="qpidcommond.lib qpidclientd.lib"
OutputFile="$(OutDir)\topic_listener.exe"
LinkIncremental="2"
SuppressStartupBanner="true"
@@ -103,8 +103,8 @@
</Configuration>
<Configuration
Name="Release|Win32"
- OutputDirectory="Static_Release"
- IntermediateDirectory="Static_Release\topic_listener\I386"
+ OutputDirectory="Release"
+ IntermediateDirectory="Release\topic_listener\I386"
ConfigurationType="1"
CharacterSet="0"
@@ -135,7 +135,7 @@
Optimization="2"
AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..,..\gen"
PreprocessorDefinitions="NDEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
- RuntimeLibrary="0"
+ RuntimeLibrary="2"
RuntimeTypeInfo="true"
WarningLevel="3"
Detect64BitPortabilityProblems="false"
@@ -155,7 +155,7 @@
/>
<Tool
Name="VCLinkerTool"
- AdditionalDependencies="qpidcommons.lib qpidclients.lib qmfconsoles.lib ws2_32.lib rpcrt4.lib"
+ AdditionalDependencies="qpidcommon.lib qpidclient.lib"
OutputFile="$(OutDir)\topic_listener.exe"
LinkIncremental="1"
SuppressStartupBanner="true"
@@ -184,8 +184,8 @@
</Configuration>
<Configuration
Name="Debug|x64"
- OutputDirectory="Static_Debug"
- IntermediateDirectory="Static_Debug\topic_listener\AMD64"
+ OutputDirectory="."
+ IntermediateDirectory="Debug\topic_listener\AMD64"
ConfigurationType="1"
CharacterSet="0"
@@ -218,7 +218,7 @@
PreprocessorDefinitions="_DEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;_AMD64_;_WIN64;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
MinimalRebuild="false"
BasicRuntimeChecks="3"
- RuntimeLibrary="1"
+ RuntimeLibrary="3"
RuntimeTypeInfo="true"
WarningLevel="3"
Detect64BitPortabilityProblems="false"
@@ -240,7 +240,7 @@
<Tool
Name="VCLinkerTool"
AdditionalOptions="/machine:AMD64"
- AdditionalDependencies="qpidcommonsd.lib qpidclientsd.lib qmfconsolesd.lib ws2_32.lib rpcrt4.lib"
+ AdditionalDependencies="qpidcommond.lib qpidclientd.lib"
OutputFile="$(OutDir)\topic_listener.exe"
LinkIncremental="2"
SuppressStartupBanner="true"
@@ -267,8 +267,8 @@
</Configuration>
<Configuration
Name="Release|x64"
- OutputDirectory="Static_Release"
- IntermediateDirectory="Static_Release\topic_listener\AMD64"
+ OutputDirectory="Release"
+ IntermediateDirectory="Release\topic_listener\AMD64"
ConfigurationType="1"
CharacterSet="0"
@@ -299,7 +299,7 @@
Optimization="2"
AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..,..\gen"
PreprocessorDefinitions="NDEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;_AMD64_;_WIN64;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
- RuntimeLibrary="0"
+ RuntimeLibrary="2"
RuntimeTypeInfo="true"
WarningLevel="3"
Detect64BitPortabilityProblems="false"
@@ -320,7 +320,7 @@
<Tool
Name="VCLinkerTool"
AdditionalOptions="/machine:AMD64"
- AdditionalDependencies="qpidcommons.lib qpidclients.lib qmfconsoles.lib ws2_32.lib rpcrt4.lib"
+ AdditionalDependencies="qpidcommon.lib qpidclient.lib"
OutputFile="$(OutDir)\topic_listener.exe"
LinkIncremental="1"
SuppressStartupBanner="true"
diff --git a/qpid/cpp/src/tests/topic_publisher.vcproj b/qpid/cpp/src/tests/topic_publisher.vcproj
index a059adb398..016c6d4a38 100644
--- a/qpid/cpp/src/tests/topic_publisher.vcproj
+++ b/qpid/cpp/src/tests/topic_publisher.vcproj
@@ -3,7 +3,7 @@
ProjectType="Visual C++"
Version="9.00"
Name="topic_publisher"
- ProjectGUID="{7D66FE10-FECA-1BAD-2235-047BCDC7409E}"
+ ProjectGUID="{7D66FE10-FECA-1BAD-2431-8A11DB0D67CE}"
RootNamespace="topic_publisher"
Keyword="Win32Proj"
SignManifests="true"
@@ -21,8 +21,8 @@
<Configurations>
<Configuration
Name="Debug|Win32"
- OutputDirectory="Static_Debug"
- IntermediateDirectory="Static_Debug\topic_publisher\I386"
+ OutputDirectory="."
+ IntermediateDirectory="Debug\topic_publisher\I386"
ConfigurationType="1"
CharacterSet="0"
@@ -55,7 +55,7 @@
PreprocessorDefinitions="_DEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
MinimalRebuild="false"
BasicRuntimeChecks="3"
- RuntimeLibrary="1"
+ RuntimeLibrary="3"
RuntimeTypeInfo="true"
WarningLevel="3"
Detect64BitPortabilityProblems="false"
@@ -76,7 +76,7 @@
/>
<Tool
Name="VCLinkerTool"
- AdditionalDependencies="qpidcommonsd.lib qpidclientsd.lib qmfconsolesd.lib ws2_32.lib rpcrt4.lib"
+ AdditionalDependencies="qpidcommond.lib qpidclientd.lib"
OutputFile="$(OutDir)\topic_publisher.exe"
LinkIncremental="2"
SuppressStartupBanner="true"
@@ -103,8 +103,8 @@
</Configuration>
<Configuration
Name="Release|Win32"
- OutputDirectory="Static_Release"
- IntermediateDirectory="Static_Release\topic_publisher\I386"
+ OutputDirectory="Release"
+ IntermediateDirectory="Release\topic_publisher\I386"
ConfigurationType="1"
CharacterSet="0"
@@ -135,7 +135,7 @@
Optimization="2"
AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..,..\gen"
PreprocessorDefinitions="NDEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
- RuntimeLibrary="0"
+ RuntimeLibrary="2"
RuntimeTypeInfo="true"
WarningLevel="3"
Detect64BitPortabilityProblems="false"
@@ -155,7 +155,7 @@
/>
<Tool
Name="VCLinkerTool"
- AdditionalDependencies="qpidcommons.lib qpidclients.lib qmfconsoles.lib ws2_32.lib rpcrt4.lib"
+ AdditionalDependencies="qpidcommon.lib qpidclient.lib"
OutputFile="$(OutDir)\topic_publisher.exe"
LinkIncremental="1"
SuppressStartupBanner="true"
@@ -184,8 +184,8 @@
</Configuration>
<Configuration
Name="Debug|x64"
- OutputDirectory="Static_Debug"
- IntermediateDirectory="Static_Debug\topic_publisher\AMD64"
+ OutputDirectory="."
+ IntermediateDirectory="Debug\topic_publisher\AMD64"
ConfigurationType="1"
CharacterSet="0"
@@ -218,7 +218,7 @@
PreprocessorDefinitions="_DEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;_AMD64_;_WIN64;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
MinimalRebuild="false"
BasicRuntimeChecks="3"
- RuntimeLibrary="1"
+ RuntimeLibrary="3"
RuntimeTypeInfo="true"
WarningLevel="3"
Detect64BitPortabilityProblems="false"
@@ -240,7 +240,7 @@
<Tool
Name="VCLinkerTool"
AdditionalOptions="/machine:AMD64"
- AdditionalDependencies="qpidcommonsd.lib qpidclientsd.lib qmfconsolesd.lib ws2_32.lib rpcrt4.lib"
+ AdditionalDependencies="qpidcommond.lib qpidclientd.lib"
OutputFile="$(OutDir)\topic_publisher.exe"
LinkIncremental="2"
SuppressStartupBanner="true"
@@ -267,8 +267,8 @@
</Configuration>
<Configuration
Name="Release|x64"
- OutputDirectory="Static_Release"
- IntermediateDirectory="Static_Release\topic_publisher\AMD64"
+ OutputDirectory="Release"
+ IntermediateDirectory="Release\topic_publisher\AMD64"
ConfigurationType="1"
CharacterSet="0"
@@ -299,7 +299,7 @@
Optimization="2"
AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..,..\gen"
PreprocessorDefinitions="NDEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;_AMD64_;_WIN64;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
- RuntimeLibrary="0"
+ RuntimeLibrary="2"
RuntimeTypeInfo="true"
WarningLevel="3"
Detect64BitPortabilityProblems="false"
@@ -320,7 +320,7 @@
<Tool
Name="VCLinkerTool"
AdditionalOptions="/machine:AMD64"
- AdditionalDependencies="qpidcommons.lib qpidclients.lib qmfconsoles.lib ws2_32.lib rpcrt4.lib"
+ AdditionalDependencies="qpidcommon.lib qpidclient.lib"
OutputFile="$(OutDir)\topic_publisher.exe"
LinkIncremental="1"
SuppressStartupBanner="true"
diff --git a/qpid/cpp/src/tests/txjob.vcproj b/qpid/cpp/src/tests/txjob.vcproj
index 69bdff2e8d..19fe3fba12 100644
--- a/qpid/cpp/src/tests/txjob.vcproj
+++ b/qpid/cpp/src/tests/txjob.vcproj
@@ -3,7 +3,7 @@
ProjectType="Visual C++"
Version="9.00"
Name="txjob"
- ProjectGUID="{09034A53-FECA-1BAD-2235-047BCDC7409E}"
+ ProjectGUID="{09034A53-FECA-1BAD-2431-8A11DB0D67CE}"
RootNamespace="txjob"
Keyword="Win32Proj"
SignManifests="true"
@@ -21,8 +21,8 @@
<Configurations>
<Configuration
Name="Debug|Win32"
- OutputDirectory="Static_Debug"
- IntermediateDirectory="Static_Debug\txjob\I386"
+ OutputDirectory="."
+ IntermediateDirectory="Debug\txjob\I386"
ConfigurationType="1"
CharacterSet="0"
@@ -55,7 +55,7 @@
PreprocessorDefinitions="_DEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
MinimalRebuild="false"
BasicRuntimeChecks="3"
- RuntimeLibrary="1"
+ RuntimeLibrary="3"
RuntimeTypeInfo="true"
WarningLevel="3"
Detect64BitPortabilityProblems="false"
@@ -76,7 +76,7 @@
/>
<Tool
Name="VCLinkerTool"
- AdditionalDependencies="qpidcommonsd.lib qpidclientsd.lib qmfconsolesd.lib ws2_32.lib rpcrt4.lib"
+ AdditionalDependencies="qpidcommond.lib qpidclientd.lib"
OutputFile="$(OutDir)\txjob.exe"
LinkIncremental="2"
SuppressStartupBanner="true"
@@ -103,8 +103,8 @@
</Configuration>
<Configuration
Name="Release|Win32"
- OutputDirectory="Static_Release"
- IntermediateDirectory="Static_Release\txjob\I386"
+ OutputDirectory="Release"
+ IntermediateDirectory="Release\txjob\I386"
ConfigurationType="1"
CharacterSet="0"
@@ -135,7 +135,7 @@
Optimization="2"
AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..,..\gen"
PreprocessorDefinitions="NDEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
- RuntimeLibrary="0"
+ RuntimeLibrary="2"
RuntimeTypeInfo="true"
WarningLevel="3"
Detect64BitPortabilityProblems="false"
@@ -155,7 +155,7 @@
/>
<Tool
Name="VCLinkerTool"
- AdditionalDependencies="qpidcommons.lib qpidclients.lib qmfconsoles.lib ws2_32.lib rpcrt4.lib"
+ AdditionalDependencies="qpidcommon.lib qpidclient.lib"
OutputFile="$(OutDir)\txjob.exe"
LinkIncremental="1"
SuppressStartupBanner="true"
@@ -184,8 +184,8 @@
</Configuration>
<Configuration
Name="Debug|x64"
- OutputDirectory="Static_Debug"
- IntermediateDirectory="Static_Debug\txjob\AMD64"
+ OutputDirectory="."
+ IntermediateDirectory="Debug\txjob\AMD64"
ConfigurationType="1"
CharacterSet="0"
@@ -218,7 +218,7 @@
PreprocessorDefinitions="_DEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;_AMD64_;_WIN64;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
MinimalRebuild="false"
BasicRuntimeChecks="3"
- RuntimeLibrary="1"
+ RuntimeLibrary="3"
RuntimeTypeInfo="true"
WarningLevel="3"
Detect64BitPortabilityProblems="false"
@@ -240,7 +240,7 @@
<Tool
Name="VCLinkerTool"
AdditionalOptions="/machine:AMD64"
- AdditionalDependencies="qpidcommonsd.lib qpidclientsd.lib qmfconsolesd.lib ws2_32.lib rpcrt4.lib"
+ AdditionalDependencies="qpidcommond.lib qpidclientd.lib"
OutputFile="$(OutDir)\txjob.exe"
LinkIncremental="2"
SuppressStartupBanner="true"
@@ -267,8 +267,8 @@
</Configuration>
<Configuration
Name="Release|x64"
- OutputDirectory="Static_Release"
- IntermediateDirectory="Static_Release\txjob\AMD64"
+ OutputDirectory="Release"
+ IntermediateDirectory="Release\txjob\AMD64"
ConfigurationType="1"
CharacterSet="0"
@@ -299,7 +299,7 @@
Optimization="2"
AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..,..\gen"
PreprocessorDefinitions="NDEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;_AMD64_;_WIN64;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
- RuntimeLibrary="0"
+ RuntimeLibrary="2"
RuntimeTypeInfo="true"
WarningLevel="3"
Detect64BitPortabilityProblems="false"
@@ -320,7 +320,7 @@
<Tool
Name="VCLinkerTool"
AdditionalOptions="/machine:AMD64"
- AdditionalDependencies="qpidcommons.lib qpidclients.lib qmfconsoles.lib ws2_32.lib rpcrt4.lib"
+ AdditionalDependencies="qpidcommon.lib qpidclient.lib"
OutputFile="$(OutDir)\txjob.exe"
LinkIncremental="1"
SuppressStartupBanner="true"
diff --git a/qpid/cpp/src/tests/txshift.cpp b/qpid/cpp/src/tests/txshift.cpp
index 5db08d7a53..dd67710526 100644
--- a/qpid/cpp/src/tests/txshift.cpp
+++ b/qpid/cpp/src/tests/txshift.cpp
@@ -155,6 +155,7 @@ struct Worker : FailoverManager::Command, Runnable
SubscriptionManager subs(session);
transfer.subscribeToControl(subs);
subs.run();
+ session.txCommit();//commit accept of control messages
}
};
@@ -173,8 +174,8 @@ int main(int argc, char** argv)
for (size_t i = 0; i < opts.workers; i++) {
workers.push_back(new Worker(connection, opts.workQueue));
}
- for_each(workers.begin(), workers.end(), boost::bind(&Worker::start, _1));
- for_each(workers.begin(), workers.end(), boost::bind(&Worker::join, _1));
+ std::for_each(workers.begin(), workers.end(), boost::bind(&Worker::start, _1));
+ std::for_each(workers.begin(), workers.end(), boost::bind(&Worker::join, _1));
}
return 0;
diff --git a/qpid/cpp/src/tests/txshift.vcproj b/qpid/cpp/src/tests/txshift.vcproj
index aa7d6ca303..3212881351 100644
--- a/qpid/cpp/src/tests/txshift.vcproj
+++ b/qpid/cpp/src/tests/txshift.vcproj
@@ -3,7 +3,7 @@
ProjectType="Visual C++"
Version="9.00"
Name="txshift"
- ProjectGUID="{6E3B2A6B-FECA-1BAD-2235-047BCDC7409E}"
+ ProjectGUID="{6E3B2A6B-FECA-1BAD-2431-8A11DB0D67CE}"
RootNamespace="txshift"
Keyword="Win32Proj"
SignManifests="true"
@@ -21,8 +21,8 @@
<Configurations>
<Configuration
Name="Debug|Win32"
- OutputDirectory="Static_Debug"
- IntermediateDirectory="Static_Debug\txshift\I386"
+ OutputDirectory="."
+ IntermediateDirectory="Debug\txshift\I386"
ConfigurationType="1"
CharacterSet="0"
@@ -55,7 +55,7 @@
PreprocessorDefinitions="_DEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
MinimalRebuild="false"
BasicRuntimeChecks="3"
- RuntimeLibrary="1"
+ RuntimeLibrary="3"
RuntimeTypeInfo="true"
WarningLevel="3"
Detect64BitPortabilityProblems="false"
@@ -76,7 +76,7 @@
/>
<Tool
Name="VCLinkerTool"
- AdditionalDependencies="qpidcommonsd.lib qpidclientsd.lib qmfconsolesd.lib ws2_32.lib rpcrt4.lib"
+ AdditionalDependencies="qpidcommond.lib qpidclientd.lib"
OutputFile="$(OutDir)\txshift.exe"
LinkIncremental="2"
SuppressStartupBanner="true"
@@ -103,8 +103,8 @@
</Configuration>
<Configuration
Name="Release|Win32"
- OutputDirectory="Static_Release"
- IntermediateDirectory="Static_Release\txshift\I386"
+ OutputDirectory="Release"
+ IntermediateDirectory="Release\txshift\I386"
ConfigurationType="1"
CharacterSet="0"
@@ -135,7 +135,7 @@
Optimization="2"
AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..,..\gen"
PreprocessorDefinitions="NDEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
- RuntimeLibrary="0"
+ RuntimeLibrary="2"
RuntimeTypeInfo="true"
WarningLevel="3"
Detect64BitPortabilityProblems="false"
@@ -155,7 +155,7 @@
/>
<Tool
Name="VCLinkerTool"
- AdditionalDependencies="qpidcommons.lib qpidclients.lib qmfconsoles.lib ws2_32.lib rpcrt4.lib"
+ AdditionalDependencies="qpidcommon.lib qpidclient.lib"
OutputFile="$(OutDir)\txshift.exe"
LinkIncremental="1"
SuppressStartupBanner="true"
@@ -184,8 +184,8 @@
</Configuration>
<Configuration
Name="Debug|x64"
- OutputDirectory="Static_Debug"
- IntermediateDirectory="Static_Debug\txshift\AMD64"
+ OutputDirectory="."
+ IntermediateDirectory="Debug\txshift\AMD64"
ConfigurationType="1"
CharacterSet="0"
@@ -218,7 +218,7 @@
PreprocessorDefinitions="_DEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;_AMD64_;_WIN64;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
MinimalRebuild="false"
BasicRuntimeChecks="3"
- RuntimeLibrary="1"
+ RuntimeLibrary="3"
RuntimeTypeInfo="true"
WarningLevel="3"
Detect64BitPortabilityProblems="false"
@@ -240,7 +240,7 @@
<Tool
Name="VCLinkerTool"
AdditionalOptions="/machine:AMD64"
- AdditionalDependencies="qpidcommonsd.lib qpidclientsd.lib qmfconsolesd.lib ws2_32.lib rpcrt4.lib"
+ AdditionalDependencies="qpidcommond.lib qpidclientd.lib"
OutputFile="$(OutDir)\txshift.exe"
LinkIncremental="2"
SuppressStartupBanner="true"
@@ -267,8 +267,8 @@
</Configuration>
<Configuration
Name="Release|x64"
- OutputDirectory="Static_Release"
- IntermediateDirectory="Static_Release\txshift\AMD64"
+ OutputDirectory="Release"
+ IntermediateDirectory="Release\txshift\AMD64"
ConfigurationType="1"
CharacterSet="0"
@@ -299,7 +299,7 @@
Optimization="2"
AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..,..\gen"
PreprocessorDefinitions="NDEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;_AMD64_;_WIN64;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
- RuntimeLibrary="0"
+ RuntimeLibrary="2"
RuntimeTypeInfo="true"
WarningLevel="3"
Detect64BitPortabilityProblems="false"
@@ -320,7 +320,7 @@
<Tool
Name="VCLinkerTool"
AdditionalOptions="/machine:AMD64"
- AdditionalDependencies="qpidcommons.lib qpidclients.lib qmfconsoles.lib ws2_32.lib rpcrt4.lib"
+ AdditionalDependencies="qpidcommon.lib qpidclient.lib"
OutputFile="$(OutDir)\txshift.exe"
LinkIncremental="1"
SuppressStartupBanner="true"
diff --git a/qpid/cpp/src/tests/txtest.vcproj b/qpid/cpp/src/tests/txtest.vcproj
index a56e820dc0..663291a9d5 100644
--- a/qpid/cpp/src/tests/txtest.vcproj
+++ b/qpid/cpp/src/tests/txtest.vcproj
@@ -3,7 +3,7 @@
ProjectType="Visual C++"
Version="9.00"
Name="txtest"
- ProjectGUID="{697786BE-FECA-1BAD-2235-047BCDC7409E}"
+ ProjectGUID="{697786BE-FECA-1BAD-2431-8A11DB0D67CE}"
RootNamespace="txtest"
Keyword="Win32Proj"
SignManifests="true"
@@ -21,8 +21,8 @@
<Configurations>
<Configuration
Name="Debug|Win32"
- OutputDirectory="Static_Debug"
- IntermediateDirectory="Static_Debug\txtest\I386"
+ OutputDirectory="."
+ IntermediateDirectory="Debug\txtest\I386"
ConfigurationType="1"
CharacterSet="0"
@@ -55,7 +55,7 @@
PreprocessorDefinitions="_DEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
MinimalRebuild="false"
BasicRuntimeChecks="3"
- RuntimeLibrary="1"
+ RuntimeLibrary="3"
RuntimeTypeInfo="true"
WarningLevel="3"
Detect64BitPortabilityProblems="false"
@@ -76,7 +76,7 @@
/>
<Tool
Name="VCLinkerTool"
- AdditionalDependencies="qpidcommonsd.lib qpidclientsd.lib qmfconsolesd.lib ws2_32.lib rpcrt4.lib"
+ AdditionalDependencies="qpidcommond.lib qpidclientd.lib"
OutputFile="$(OutDir)\txtest.exe"
LinkIncremental="2"
SuppressStartupBanner="true"
@@ -103,8 +103,8 @@
</Configuration>
<Configuration
Name="Release|Win32"
- OutputDirectory="Static_Release"
- IntermediateDirectory="Static_Release\txtest\I386"
+ OutputDirectory="Release"
+ IntermediateDirectory="Release\txtest\I386"
ConfigurationType="1"
CharacterSet="0"
@@ -135,7 +135,7 @@
Optimization="2"
AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..,..\gen"
PreprocessorDefinitions="NDEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
- RuntimeLibrary="0"
+ RuntimeLibrary="2"
RuntimeTypeInfo="true"
WarningLevel="3"
Detect64BitPortabilityProblems="false"
@@ -155,7 +155,7 @@
/>
<Tool
Name="VCLinkerTool"
- AdditionalDependencies="qpidcommons.lib qpidclients.lib qmfconsoles.lib ws2_32.lib rpcrt4.lib"
+ AdditionalDependencies="qpidcommon.lib qpidclient.lib"
OutputFile="$(OutDir)\txtest.exe"
LinkIncremental="1"
SuppressStartupBanner="true"
@@ -184,8 +184,8 @@
</Configuration>
<Configuration
Name="Debug|x64"
- OutputDirectory="Static_Debug"
- IntermediateDirectory="Static_Debug\txtest\AMD64"
+ OutputDirectory="."
+ IntermediateDirectory="Debug\txtest\AMD64"
ConfigurationType="1"
CharacterSet="0"
@@ -218,7 +218,7 @@
PreprocessorDefinitions="_DEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;_AMD64_;_WIN64;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
MinimalRebuild="false"
BasicRuntimeChecks="3"
- RuntimeLibrary="1"
+ RuntimeLibrary="3"
RuntimeTypeInfo="true"
WarningLevel="3"
Detect64BitPortabilityProblems="false"
@@ -240,7 +240,7 @@
<Tool
Name="VCLinkerTool"
AdditionalOptions="/machine:AMD64"
- AdditionalDependencies="qpidcommonsd.lib qpidclientsd.lib qmfconsolesd.lib ws2_32.lib rpcrt4.lib"
+ AdditionalDependencies="qpidcommond.lib qpidclientd.lib"
OutputFile="$(OutDir)\txtest.exe"
LinkIncremental="2"
SuppressStartupBanner="true"
@@ -267,8 +267,8 @@
</Configuration>
<Configuration
Name="Release|x64"
- OutputDirectory="Static_Release"
- IntermediateDirectory="Static_Release\txtest\AMD64"
+ OutputDirectory="Release"
+ IntermediateDirectory="Release\txtest\AMD64"
ConfigurationType="1"
CharacterSet="0"
@@ -299,7 +299,7 @@
Optimization="2"
AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..,..\gen"
PreprocessorDefinitions="NDEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;_AMD64_;_WIN64;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
- RuntimeLibrary="0"
+ RuntimeLibrary="2"
RuntimeTypeInfo="true"
WarningLevel="3"
Detect64BitPortabilityProblems="false"
@@ -320,7 +320,7 @@
<Tool
Name="VCLinkerTool"
AdditionalOptions="/machine:AMD64"
- AdditionalDependencies="qpidcommons.lib qpidclients.lib qmfconsoles.lib ws2_32.lib rpcrt4.lib"
+ AdditionalDependencies="qpidcommon.lib qpidclient.lib"
OutputFile="$(OutDir)\txtest.exe"
LinkIncremental="1"
SuppressStartupBanner="true"
diff --git a/qpid/cpp/src/tests/unit_test.h b/qpid/cpp/src/tests/unit_test.h
index df3ebfb1fe..fc542e62ad 100644
--- a/qpid/cpp/src/tests/unit_test.h
+++ b/qpid/cpp/src/tests/unit_test.h
@@ -61,7 +61,14 @@
namespace { struct test_name { void test_method(); }; } \
void test_name::test_method()
-#endif // Workaround for BOOST_AUTO_TEST_SUITE_EXPECTED_FAILURES
+#endif // Workaround for BOOST_AUTO_TEST_CASE_EXPECTED_FAILURES
+
+// Correct syntax for boost > 1.36
+#if (BOOST_VERSION > 103500)
+# define QPID_AUTO_TEST_CASE_EXPECTED_FAILURES(name,n) \
+ BOOST_AUTO_TEST_CASE_EXPECTED_FAILURES(name,n) \
+ BOOST_AUTO_TEST_CASE(name)
+#endif // Correct syntax for boost > 1.36
//
// Default definitions for latest version of boost.
diff --git a/qpid/cpp/src/tests/unit_test.vcproj b/qpid/cpp/src/tests/unit_test.vcproj
index ab6d13cd62..8710b617f8 100644
--- a/qpid/cpp/src/tests/unit_test.vcproj
+++ b/qpid/cpp/src/tests/unit_test.vcproj
@@ -3,7 +3,7 @@
ProjectType="Visual C++"
Version="9.00"
Name="unit_test"
- ProjectGUID="{51E5F6B9-FECA-1BAD-2235-047BCDC7409E}"
+ ProjectGUID="{51E5F6B9-FECA-1BAD-2431-8A11DB0D67CE}"
RootNamespace="unit_test"
Keyword="Win32Proj"
SignManifests="true"
@@ -21,8 +21,8 @@
<Configurations>
<Configuration
Name="Debug|Win32"
- OutputDirectory="Static_Debug"
- IntermediateDirectory="Static_Debug\unit_test\I386"
+ OutputDirectory="."
+ IntermediateDirectory="Debug\unit_test\I386"
ConfigurationType="1"
CharacterSet="0"
@@ -52,22 +52,22 @@
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..,..\gen"
- PreprocessorDefinitions="_DEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
+ PreprocessorDefinitions="_DEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS"
MinimalRebuild="false"
BasicRuntimeChecks="3"
- RuntimeLibrary="1"
+ RuntimeLibrary="3"
RuntimeTypeInfo="true"
WarningLevel="3"
Detect64BitPortabilityProblems="false"
DebugInformationFormat="3"
- DisableSpecificWarnings="4244;4800"
+ DisableSpecificWarnings="4244;4800;4290;4355"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
- PreprocessorDefinitions="_DEBUG;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
+ PreprocessorDefinitions="_DEBUG;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS"
Culture="1033"
AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..,..\gen"
/>
@@ -76,7 +76,7 @@
/>
<Tool
Name="VCLinkerTool"
- AdditionalDependencies="qpidcommonsd.lib qpidclientsd.lib qmfconsolesd.lib ws2_32.lib rpcrt4.lib"
+ AdditionalDependencies="qpidcommond.lib qpidclientd.lib qpidbrokerd.lib qmfconsoled.lib"
OutputFile="$(OutDir)\unit_test.exe"
LinkIncremental="2"
SuppressStartupBanner="true"
@@ -103,8 +103,8 @@
</Configuration>
<Configuration
Name="Release|Win32"
- OutputDirectory="Static_Release"
- IntermediateDirectory="Static_Release\unit_test\I386"
+ OutputDirectory="Release"
+ IntermediateDirectory="Release\unit_test\I386"
ConfigurationType="1"
CharacterSet="0"
@@ -134,19 +134,19 @@
Name="VCCLCompilerTool"
Optimization="2"
AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..,..\gen"
- PreprocessorDefinitions="NDEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
- RuntimeLibrary="0"
+ PreprocessorDefinitions="NDEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS"
+ RuntimeLibrary="2"
RuntimeTypeInfo="true"
WarningLevel="3"
Detect64BitPortabilityProblems="false"
- DisableSpecificWarnings="4244;4800"
+ DisableSpecificWarnings="4244;4800;4290;4355"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
- PreprocessorDefinitions="NDEBUG;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
+ PreprocessorDefinitions="NDEBUG;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS"
Culture="1033"
AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..,..\gen"
/>
@@ -155,7 +155,7 @@
/>
<Tool
Name="VCLinkerTool"
- AdditionalDependencies="qpidcommons.lib qpidclients.lib qmfconsoles.lib ws2_32.lib rpcrt4.lib"
+ AdditionalDependencies="qpidcommon.lib qpidclient.lib qpidbroker.lib qmfconsole.lib"
OutputFile="$(OutDir)\unit_test.exe"
LinkIncremental="1"
SuppressStartupBanner="true"
@@ -184,8 +184,8 @@
</Configuration>
<Configuration
Name="Debug|x64"
- OutputDirectory="Static_Debug"
- IntermediateDirectory="Static_Debug\unit_test\AMD64"
+ OutputDirectory="."
+ IntermediateDirectory="Debug\unit_test\AMD64"
ConfigurationType="1"
CharacterSet="0"
@@ -215,22 +215,22 @@
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..,..\gen"
- PreprocessorDefinitions="_DEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;_AMD64_;_WIN64;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
+ PreprocessorDefinitions="_DEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;_AMD64_;_WIN64;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS"
MinimalRebuild="false"
BasicRuntimeChecks="3"
- RuntimeLibrary="1"
+ RuntimeLibrary="3"
RuntimeTypeInfo="true"
WarningLevel="3"
Detect64BitPortabilityProblems="false"
DebugInformationFormat="3"
- DisableSpecificWarnings="4244;4800"
+ DisableSpecificWarnings="4244;4800;4290;4355"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
- PreprocessorDefinitions="_DEBUG;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS;_WIN64"
+ PreprocessorDefinitions="_DEBUG;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_WIN64"
Culture="1033"
AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..,..\gen"
/>
@@ -240,7 +240,7 @@
<Tool
Name="VCLinkerTool"
AdditionalOptions="/machine:AMD64"
- AdditionalDependencies="qpidcommonsd.lib qpidclientsd.lib qmfconsolesd.lib ws2_32.lib rpcrt4.lib"
+ AdditionalDependencies="qpidcommond.lib qpidclientd.lib qpidbrokerd.lib qmfconsoled.lib"
OutputFile="$(OutDir)\unit_test.exe"
LinkIncremental="2"
SuppressStartupBanner="true"
@@ -267,8 +267,8 @@
</Configuration>
<Configuration
Name="Release|x64"
- OutputDirectory="Static_Release"
- IntermediateDirectory="Static_Release\unit_test\AMD64"
+ OutputDirectory="Release"
+ IntermediateDirectory="Release\unit_test\AMD64"
ConfigurationType="1"
CharacterSet="0"
@@ -298,19 +298,19 @@
Name="VCCLCompilerTool"
Optimization="2"
AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..,..\gen"
- PreprocessorDefinitions="NDEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;_AMD64_;_WIN64;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS"
- RuntimeLibrary="0"
+ PreprocessorDefinitions="NDEBUG;WIN32;_CONSOLE;_CRT_NONSTDC_NO_WARNINGS;_AMD64_;_WIN64;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS"
+ RuntimeLibrary="2"
RuntimeTypeInfo="true"
WarningLevel="3"
Detect64BitPortabilityProblems="false"
- DisableSpecificWarnings="4244;4800"
+ DisableSpecificWarnings="4244;4800;4290;4355"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
- PreprocessorDefinitions="NDEBUG;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS;_WIN64"
+ PreprocessorDefinitions="NDEBUG;NOMINMAX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_WIN64"
Culture="1033"
AdditionalIncludeDirectories="$(BOOST_ROOT)\include\$(BOOST_VERSION),$(BOOST_ROOT)\.,..,..\gen"
/>
@@ -320,7 +320,7 @@
<Tool
Name="VCLinkerTool"
AdditionalOptions="/machine:AMD64"
- AdditionalDependencies="qpidcommons.lib qpidclients.lib qmfconsoles.lib ws2_32.lib rpcrt4.lib"
+ AdditionalDependencies="qpidcommon.lib qpidclient.lib qpidbroker.lib qmfconsole.lib"
OutputFile="$(OutDir)\unit_test.exe"
LinkIncremental="1"
SuppressStartupBanner="true"
@@ -361,15 +361,33 @@
RelativePath="Array.cpp">
</File>
<File
+ RelativePath="AsyncCompletion.cpp">
+ </File>
+ <File
RelativePath="AtomicValue.cpp">
</File>
<File
RelativePath="Blob.cpp">
</File>
<File
+ RelativePath="ClientSessionTest.cpp">
+ </File>
+ <File
RelativePath="ConsoleTest.cpp">
</File>
<File
+ RelativePath="DeliveryRecordTest.cpp">
+ </File>
+ <File
+ RelativePath="DtxWorkRecordTest.cpp">
+ </File>
+ <File
+ RelativePath="exception_test.cpp">
+ </File>
+ <File
+ RelativePath="ExchangeTest.cpp">
+ </File>
+ <File
RelativePath="FieldTable.cpp">
</File>
<File
@@ -379,9 +397,15 @@
RelativePath="FramingTest.cpp">
</File>
<File
+ RelativePath="HeadersExchangeTest.cpp">
+ </File>
+ <File
RelativePath="HeaderTest.cpp">
</File>
<File
+ RelativePath="IncompleteMessageList.cpp">
+ </File>
+ <File
RelativePath="InlineAllocator.cpp">
</File>
<File
@@ -394,6 +418,15 @@
RelativePath="ManagementTest.cpp">
</File>
<File
+ RelativePath="MessageBuilderTest.cpp">
+ </File>
+ <File
+ RelativePath="MessageReplayTracker.cpp">
+ </File>
+ <File
+ RelativePath="MessageTest.cpp">
+ </File>
+ <File
RelativePath="ProxyTest.cpp">
</File>
<File
@@ -403,6 +436,15 @@
RelativePath="QueueOptionsTest.cpp">
</File>
<File
+ RelativePath="QueuePolicyTest.cpp">
+ </File>
+ <File
+ RelativePath="QueueRegistryTest.cpp">
+ </File>
+ <File
+ RelativePath="QueueTest.cpp">
+ </File>
+ <File
RelativePath="RangeSet.cpp">
</File>
<File
@@ -430,6 +472,18 @@
RelativePath="StringUtils.cpp">
</File>
<File
+ RelativePath="TimerTest.cpp">
+ </File>
+ <File
+ RelativePath="TopicExchangeTest.cpp">
+ </File>
+ <File
+ RelativePath="TxBufferTest.cpp">
+ </File>
+ <File
+ RelativePath="TxPublishTest.cpp">
+ </File>
+ <File
RelativePath="unit_test.cpp">
</File>
<File
diff --git a/qpid/cpp/xml/cluster.xml b/qpid/cpp/xml/cluster.xml
index 2cf4e915b6..8fdde0ada6 100644
--- a/qpid/cpp/xml/cluster.xml
+++ b/qpid/cpp/xml/cluster.xml
@@ -125,13 +125,13 @@
<field name="member-id" type="uint64"/>
<field name="connection-id" type="uint64"/>
<field name="user-name" type="str8"/>
+ <field name="fragment" type="str32"/>
</control>
<!-- Complete a cluster state update. -->
<control name="membership" code="0x21" label="Cluster membership details.">
<field name="joiners" type="map"/> <!-- member-id -> URL -->
<field name="members" type="map"/> <!-- member-id -> state -->
- <field name="frame-id" type="uint64"/>> <!-- Frame id counter value -->
</control>
<!-- Set the position of a replicated queue. -->
@@ -139,11 +139,12 @@
<field name="queue" type="str8"/>
<field name="position" type="sequence-no"/>
</control>
-
+
<!-- Replicate encoded exchanges/queues. -->
<control name="exchange" code="0x31"><field name="encoded" type="str32"/></control>
<control name="queue" code="0x32"><field name="encoded" type="str32"/></control>
-
+ <!-- Set expiry-id for subsequent messages. -->
+ <control name="expiry-id" code="0x33"><field name="expiry-id" type="uint64"/></control>
</class>
</amqp>
diff --git a/qpid/dotnet/client-010/default.build b/qpid/dotnet/client-010/default.build
index 75eadf0a0c..3a99354e56 100644
--- a/qpid/dotnet/client-010/default.build
+++ b/qpid/dotnet/client-010/default.build
@@ -30,7 +30,7 @@
<!-- Sets build properties consistently accross all assemblies in the project. -->
<property name="build.version.major" value="0"/>
- <property name="build.version.minor" value="10"/>
+ <property name="build.version.minor" value="5"/>
<property name="build.version.build" value="0"/>
<property name="build.version.revision" value="0"/>
<property name="build.company" value="Apache Software Foundation"/>
diff --git a/qpid/dotnet/default.build b/qpid/dotnet/default.build
index b450c2481b..bfd6ada094 100644
--- a/qpid/dotnet/default.build
+++ b/qpid/dotnet/default.build
@@ -30,7 +30,7 @@
<!-- Sets build properties consistently accross all assemblies in the project. -->
<property name="build.version.major" value="0"/>
- <property name="build.version.minor" value="3"/>
+ <property name="build.version.minor" value="5"/>
<property name="build.version.build" value="0"/>
<property name="build.version.revision" value="0"/>
<property name="build.company" value="Apache Software Foundation"/>
diff --git a/qpid/java/010ExcludeList b/qpid/java/010ExcludeList
index c2d254f3ce..3eab025053 100644
--- a/qpid/java/010ExcludeList
+++ b/qpid/java/010ExcludeList
@@ -58,3 +58,5 @@ org.apache.qpid.test.client.timeouts.SyncWaitTimeoutDelayTest#*
org.apache.qpid.server.exchange.ReturnUnroutableMandatoryMessageTest#*
org.apache.qpid.server.queue.PriorityTest#*
org.apache.qpid.server.queue.TimeToLiveTest#*
+// QPID-1727 , QPID-1726 :c++ broker does not support flow to disk on transient queues. Also it requries a persistent store impl. for Apache
+org.apache.qpid.test.client.QueueBrowsingFlowToDiskTest#*
diff --git a/qpid/java/08ExcludeList b/qpid/java/08ExcludeList
index 88eb754950..1d8950dddf 100644
--- a/qpid/java/08ExcludeList
+++ b/qpid/java/08ExcludeList
@@ -6,3 +6,4 @@ org.apache.qpid.test.testcases.FailoverTest#*
org.apache.qpid.test.client.failover.FailoverTest#test4MinuteFailover
// Those tests are written against the 0.10 path
org.apache.qpid.test.unit.message.UTF8Test#*
+org.apache.qpid.client.MessageListenerTest#testSynchronousRecieveNoWait
diff --git a/qpid/java/08ExcludeList-nonvm b/qpid/java/08ExcludeList-nonvm
index eb6c60b225..546dc01f5b 100644
--- a/qpid/java/08ExcludeList-nonvm
+++ b/qpid/java/08ExcludeList-nonvm
@@ -27,3 +27,4 @@ org.apache.qpid.server.security.acl.SimpleACLTest#*
// Those tests are written against the 0.10 path
org.apache.qpid.test.unit.message.UTF8Test#*
+org.apache.qpid.client.MessageListenerTest#testSynchronousRecieveNoWait
diff --git a/qpid/java/ExcludeList b/qpid/java/ExcludeList
index 509f74bbbd..5566c0eb9f 100644
--- a/qpid/java/ExcludeList
+++ b/qpid/java/ExcludeList
@@ -1,8 +1,6 @@
org.apache.qpid.client.MultipleJCAProviderRegistrationTest#test
-// QPID-1451 : testBrowsingWithSelector test is not correct.
-org.apache.qpid.test.client.QueueBrowserAutoAckTest#testBrowsingWithSelector
-org.apache.qpid.test.client.QueueBrowserClientAckTest#testBrowsingWithSelector
-org.apache.qpid.test.client.QueueBrowserDupsOkTest#testBrowsingWithSelector
-org.apache.qpid.test.client.QueueBrowserNoAckTest#testBrowsingWithSelector
-org.apache.qpid.test.client.QueueBrowserPreAckTest#testBrowsingWithSelector
-org.apache.qpid.test.client.QueueBrowserTransactedTest#testBrowsingWithSelector
+// QPID-1715, QPID-1715 : Client Error Handling on close is still broken
+org.apache.qpid.server.queue.QueueCreateTest#testCreatePriorityString
+org.apache.qpid.server.queue.QueueCreateTest#testCreateFlowToDiskValidNoSize
+org.apache.qpid.server.queue.QueueCreateTest#testCreateFlowToDiskInvalid
+org.apache.qpid.server.queue.QueueCreateTest#testCreateFlowToDiskInvalidSize
diff --git a/qpid/java/broker/bin/create-example-ssl-stores.bat b/qpid/java/broker/bin/create-example-ssl-stores.bat
new file mode 100644
index 0000000000..5419c098d5
--- /dev/null
+++ b/qpid/java/broker/bin/create-example-ssl-stores.bat
@@ -0,0 +1,36 @@
+@REM
+@REM Licensed to the Apache Software Foundation (ASF) under one
+@REM or more contributor license agreements. See the NOTICE file
+@REM distributed with this work for additional information
+@REM regarding copyright ownership. The ASF licenses this file
+@REM to you under the Apache License, Version 2.0 (the
+@REM "License"); you may not use this file except in compliance
+@REM with the License. You may obtain a copy of the License at
+@REM
+@REM http://www.apache.org/licenses/LICENSE-2.0
+@REM
+@REM Unless required by applicable law or agreed to in writing,
+@REM software distributed under the License is distributed on an
+@REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+@REM KIND, either express or implied. See the License for the
+@REM specific language governing permissions and limitations
+@REM under the License.
+@REM
+
+@REM Create example keystore for broker and trust store for client/management console.
+@REM
+@REM Use generated qpid.keystore as the brokers keystore
+@REM Use generated qpid.truststore as client/consoles truststore
+@REM All passwords have value: password
+
+@REM Create Broker Keystore:
+keytool -genkey -alias qpidBroker -keyalg RSA -validity 365 -keystore qpid.keystore -storepass password -keypass password -dname "CN=hostname, OU=OrgUnit, O=Org, L=City, C=US"
+
+@REM Export Self Signed Cert:
+keytool -export -alias qpidBroker -keystore qpid.keystore -file qpidBroker.cer -storepass password
+
+@REM Import Broker Cert Into MC TrustStore:
+keytool -import -alias qpidBrokerCert -file qpidBroker.cer -keystore qpid.truststore -storepass password -noprompt
+
+@REM Delete the cert
+del qpidBroker.cer \ No newline at end of file
diff --git a/qpid/java/broker/bin/create-example-ssl-stores.sh b/qpid/java/broker/bin/create-example-ssl-stores.sh
new file mode 100644
index 0000000000..bfcb3dfecf
--- /dev/null
+++ b/qpid/java/broker/bin/create-example-ssl-stores.sh
@@ -0,0 +1,38 @@
+#!/bin/bash
+#
+# 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.
+#
+
+# Create example keystore for broker and trust store for client/management console.
+#
+# Use generated qpid.keystore as the brokers keystore
+# Use generated qpid.truststore as client/consoles truststore
+# All passwords have value: password
+
+#Create Broker Keystore:
+keytool -genkey -alias qpidBroker -keyalg RSA -validity 365 -keystore qpid.keystore \
+-storepass password -keypass password -dname "CN=hostname, OU=OrgUnit, O=Org, L=City, C=US"
+
+#Export Self Signed Cert:
+keytool -export -alias qpidBroker -keystore qpid.keystore -file qpidBroker.cer -storepass password
+
+#Import Broker Cert Into MC TrustStore:
+keytool -import -alias qpidBrokerCert -file qpidBroker.cer -keystore qpid.truststore -storepass password -noprompt
+
+#Delete the cert
+rm qpidBroker.cer
diff --git a/qpid/java/broker/etc/config.xml b/qpid/java/broker/etc/config.xml
index b2b3625cca..e0045c1e74 100644
--- a/qpid/java/broker/etc/config.xml
+++ b/qpid/java/broker/etc/config.xml
@@ -45,7 +45,6 @@
<management>
<enabled>true</enabled>
<jmxport>8999</jmxport>
- <security-enabled>false</security-enabled>
<ssl>
<enabled>true</enabled>
<!-- Update below path to your keystore location, eg ${conf}/qpid.keystore -->
diff --git a/qpid/java/broker/etc/debug.log4j.xml b/qpid/java/broker/etc/debug.log4j.xml
index 71f9502b75..fc0bd9f34f 100644
--- a/qpid/java/broker/etc/debug.log4j.xml
+++ b/qpid/java/broker/etc/debug.log4j.xml
@@ -1,4 +1,4 @@
-<?xml version="1.0"?>
+<?xml version="1.0" encoding="UTF-8"?>
<!--
-
- Licensed to the Apache Software Foundation (ASF) under one
@@ -18,10 +18,10 @@
- specific language governing permissions and limitations
- under the License.
-
- -->
-<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
-<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/">
- <appender name="ArchivingFileAppender" class="org.apache.log4j.QpidCompositeRollingAppender">
+ --><!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
+
+<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/" debug="null" threshold="null">
+ <appender class="org.apache.log4j.QpidCompositeRollingAppender" name="ArchivingFileAppender">
<!-- Ensure that logs allways have the dateFormat set-->
<param name="StaticLogFileName" value="false"/>
<param name="File" value="${QPID_WORK}/log/${logprefix}qpid${logsuffix}.log"/>
@@ -48,7 +48,7 @@
</layout>
</appender>
- <appender name="FileAppender" class="org.apache.log4j.FileAppender">
+ <appender class="org.apache.log4j.FileAppender" name="FileAppender">
<param name="File" value="${QPID_WORK}/log/${logprefix}qpid${logsuffix}.log"/>
<param name="Append" value="false"/>
@@ -57,7 +57,7 @@
</layout>
</appender>
- <appender name="AlertFile" class="org.apache.log4j.FileAppender">
+ <appender class="org.apache.log4j.FileAppender" name="AlertFile">
<param name="File" value="${QPID_WORK}/log/alert.log"/>
<param name="Append" value="false"/>
@@ -66,28 +66,28 @@
</layout>
</appender>
- <appender name="STDOUT" class="org.apache.log4j.ConsoleAppender">
+ <appender class="org.apache.log4j.ConsoleAppender" name="STDOUT">
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%d %-5p [%t] %C{2} (%F:%L) - %m%n"/>
</layout>
</appender>
- <category name="Qpid.Broker">
+ <category additivity="true" name="Qpid.Broker">
<priority value="debug"/>
<appender-ref ref="AlertFile"/>
<!--appender-ref ref="STDOUT"/-->
</category>
- <category name="org.apache.qpid.server.queue.AMQQueueMBean">
+ <category additivity="true" name="org.apache.qpid.server.queue.AMQQueueMBean">
<priority value="info"/>
<appender-ref ref="AlertFile"/>
</category>
<!-- Provide warnings to standard output -->
- <!--category name="org.apache.qpid">
+ <!--category additivity="true" name="org.apache.qpid">
<priority value="warn"/>
<appender-ref ref="STDOUT"/>
</category-->
@@ -96,11 +96,11 @@
<!-- Additional level settings for debugging -->
<!-- Each class in the Broker is a category that can have its logging level adjusted. -->
<!-- This will provide more details if available about that classes processing. -->
- <!--category name="org.apache.qpid.server.txn">
+ <!--category additivity="true" name="org.apache.qpid.server.txn">
<priority value="debug"/>
</category>-->
- <!--<category name="org.apache.qpid.server.store">
+ <!--<category additivity="true" name="org.apache.qpid.server.store">
<priority value="debug"/>
</category-->
diff --git a/qpid/java/broker/etc/log4j.xml b/qpid/java/broker/etc/log4j.xml
index eff5d17588..a395d0fd56 100644
--- a/qpid/java/broker/etc/log4j.xml
+++ b/qpid/java/broker/etc/log4j.xml
@@ -1,4 +1,4 @@
-<?xml version="1.0"?>
+<?xml version="1.0" encoding="UTF-8"?>
<!--
-
- Licensed to the Apache Software Foundation (ASF) under one
@@ -18,10 +18,10 @@
- specific language governing permissions and limitations
- under the License.
-
- -->
-<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
-<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/">
- <appender name="ArchivingFileAppender" class="org.apache.log4j.QpidCompositeRollingAppender">
+ --><!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
+
+<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/" debug="null" threshold="null">
+ <appender class="org.apache.log4j.QpidCompositeRollingAppender" name="ArchivingFileAppender">
<!-- Ensure that logs allways have the dateFormat set-->
<param name="StaticLogFileName" value="false"/>
<param name="File" value="${QPID_WORK}/log/${logprefix}qpid${logsuffix}.log"/>
@@ -48,7 +48,7 @@
</layout>
</appender>
- <appender name="FileAppender" class="org.apache.log4j.FileAppender">
+ <appender class="org.apache.log4j.FileAppender" name="FileAppender">
<param name="File" value="${QPID_WORK}/log/${logprefix}qpid${logsuffix}.log"/>
<param name="Append" value="false"/>
@@ -57,25 +57,25 @@
</layout>
</appender>
- <appender name="STDOUT" class="org.apache.log4j.ConsoleAppender">
+ <appender class="org.apache.log4j.ConsoleAppender" name="STDOUT">
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%d %-5p [%t] %C{2} (%F:%L) - %m%n"/>
</layout>
</appender>
- <!-- Qpid.Broker log is a special log category used to only useful broker startup details -->
- <category name="Qpid.Broker">
+ <!-- Qpid.Broker log is a special log category used to log only useful broker startup details -->
+ <category additivity="true" name="Qpid.Broker">
<priority value="debug"/>
<appender-ref ref="STDOUT"/>
</category>
- <category name="org.apache.qpid.server.queue.AMQQueueMBean">
+ <category additivity="true" name="org.apache.qpid.server.queue.AMQQueueMBean">
<priority value="info"/>
</category>
<!-- Provide warnings to standard output -->
- <category name="org.apache.qpid">
+ <category additivity="true" name="org.apache.qpid">
<priority value="warn"/>
</category>
@@ -83,7 +83,7 @@
<!-- Examples of additional logging settings -->
<!-- Used to generate extra debug. See debug.log4j.xml -->
- <!--<category name="org.apache.qpid.server.store">
+ <!--<category additivity="true" name="org.apache.qpid.server.store">
<priority value="debug"/>
</category-->
diff --git a/qpid/java/broker/etc/persistent_config.xml b/qpid/java/broker/etc/persistent_config.xml
index ed2c2cab1f..67ef28117d 100644
--- a/qpid/java/broker/etc/persistent_config.xml
+++ b/qpid/java/broker/etc/persistent_config.xml
@@ -37,7 +37,6 @@
<management>
<enabled>true</enabled>
<jmxport>8999</jmxport>
- <security-enabled>false</security-enabled>
<ssl>
<enabled>true</enabled>
<!-- Update below path to your keystore location, eg ${conf}/qpid.keystore -->
diff --git a/qpid/java/broker/etc/transient_config.xml b/qpid/java/broker/etc/transient_config.xml
index 19ffeb9720..a21afe7d21 100644
--- a/qpid/java/broker/etc/transient_config.xml
+++ b/qpid/java/broker/etc/transient_config.xml
@@ -37,7 +37,6 @@
<management>
<enabled>true</enabled>
<jmxport>8999</jmxport>
- <security-enabled>false</security-enabled>
<ssl>
<enabled>true</enabled>
<!-- Update below path to your keystore location, eg ${conf}/qpid.keystore -->
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/AMQBrokerManagerMBean.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/AMQBrokerManagerMBean.java
index b3c843ebaa..22bdae8267 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/AMQBrokerManagerMBean.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/AMQBrokerManagerMBean.java
@@ -52,9 +52,9 @@ import org.apache.qpid.server.management.MBeanConstructor;
import org.apache.qpid.server.management.MBeanDescription;
import org.apache.qpid.server.management.ManagedBroker;
import org.apache.qpid.server.management.ManagedObject;
-import org.apache.qpid.server.queue.QueueRegistry;
import org.apache.qpid.server.queue.AMQQueue;
import org.apache.qpid.server.queue.AMQQueueFactory;
+import org.apache.qpid.server.queue.QueueRegistry;
import org.apache.qpid.server.virtualhost.VirtualHost;
import org.apache.qpid.server.transactionlog.TransactionLog;
import org.apache.qpid.server.routing.RoutingTable;
@@ -77,7 +77,7 @@ public class AMQBrokerManagerMBean extends AMQManagedObject implements ManagedBr
@MBeanConstructor("Creates the Broker Manager MBean")
public AMQBrokerManagerMBean(VirtualHost.VirtualHostMBean virtualHostMBean) throws JMException
{
- super(ManagedBroker.class, ManagedBroker.TYPE);
+ super(ManagedBroker.class, ManagedBroker.TYPE, ManagedBroker.VERSION);
_virtualHostMBean = virtualHostMBean;
VirtualHost virtualHost = virtualHostMBean.getVirtualHost();
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 2d0589c223..72a2780c32 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
@@ -20,6 +20,14 @@
*/
package org.apache.qpid.server;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.LinkedHashMap;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.atomic.AtomicBoolean;
+
import org.apache.log4j.Logger;
import org.apache.qpid.AMQException;
import org.apache.qpid.framing.AMQShortString;
@@ -29,12 +37,12 @@ import org.apache.qpid.framing.FieldTable;
import org.apache.qpid.framing.abstraction.MessagePublishInfo;
import org.apache.qpid.server.ack.UnacknowledgedMessageMap;
import org.apache.qpid.server.ack.UnacknowledgedMessageMapImpl;
-import org.apache.qpid.server.configuration.Configurator;
import org.apache.qpid.server.exchange.Exchange;
import org.apache.qpid.server.exchange.NoRouteException;
import org.apache.qpid.server.flow.FlowCreditManager;
import org.apache.qpid.server.flow.Pre0_10CreditManager;
import org.apache.qpid.server.protocol.AMQProtocolSession;
+import org.apache.qpid.server.queue.AMQMessage;
import org.apache.qpid.server.queue.AMQQueue;
import org.apache.qpid.server.queue.IncomingMessage;
import org.apache.qpid.server.queue.QueueEntry;
@@ -45,19 +53,15 @@ import org.apache.qpid.server.subscription.SubscriptionFactoryImpl;
import org.apache.qpid.server.subscription.ClientDeliveryMethod;
import org.apache.qpid.server.subscription.RecordDeliveryMethod;
import org.apache.qpid.server.store.StoreContext;
+import org.apache.qpid.server.subscription.ClientDeliveryMethod;
+import org.apache.qpid.server.subscription.RecordDeliveryMethod;
+import org.apache.qpid.server.subscription.Subscription;
+import org.apache.qpid.server.subscription.SubscriptionFactoryImpl;
import org.apache.qpid.server.txn.LocalTransactionalContext;
import org.apache.qpid.server.txn.NonTransactionalContext;
import org.apache.qpid.server.txn.TransactionalContext;
import org.apache.qpid.server.transactionlog.TransactionLog;
-import java.util.Collection;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Map;
-import java.util.HashMap;
-import java.util.LinkedHashMap;
-import java.util.concurrent.atomic.AtomicBoolean;
-
public class AMQChannel
{
public static final int DEFAULT_PREFETCH = 5000;
@@ -114,9 +118,6 @@ public class AMQChannel
public AMQChannel(AMQProtocolSession session, int channelId, TransactionLog transactionLog)
throws AMQException
{
- //Set values from configuration
- Configurator.configure(this);
-
_session = session;
_channelId = channelId;
_storeContext = new StoreContext("Session: " + session.getClientIdentifier() + "; channel: " + channelId);
@@ -250,7 +251,6 @@ public class AMQChannel
}
catch (NoRouteException e)
{
- //_currentMessage.incrementReference();
_returnMessages.add(e);
}
}
@@ -431,7 +431,7 @@ public class AMQChannel
{
if (_log.isDebugEnabled())
{
- _log.debug(debugIdentity() + " Adding unacked message(" + entry.getMessage().toString() + " DT:" + deliveryTag
+ _log.debug(debugIdentity() + " Adding unacked message(" + entry.toString() + " DT:" + deliveryTag
+ ") with a queue(" + entry.getQueue() + ") for " + subscription);
}
}
@@ -498,7 +498,7 @@ public class AMQChannel
}
else
{
- unacked.discard(_storeContext);
+ unacked.dequeueAndDelete(_storeContext);
}
}
@@ -551,10 +551,10 @@ public class AMQChannel
}
else
{
- _log.warn(System.identityHashCode(this) + " Requested requeue of message(" + unacked.getMessage().debugIdentity()
+ _log.warn(System.identityHashCode(this) + " Requested requeue of message(" + unacked.debugIdentity()
+ "):" + deliveryTag + " but no queue defined and no DeadLetter queue so DROPPING message.");
- unacked.discard(_storeContext);
+ unacked.dequeueAndDelete(_storeContext);
}
}
else
@@ -711,7 +711,7 @@ public class AMQChannel
{
try
{
- message.discard(_storeContext);
+ message.dequeueAndDelete(_storeContext);
message.setQueueDeleted(true);
}
@@ -830,9 +830,7 @@ public class AMQChannel
{
AMQMessage message = bouncedMessage.getAMQMessage();
_session.getProtocolOutputConverter().writeReturn(message, _channelId, bouncedMessage.getReplyCode().getCode(),
- new AMQShortString(bouncedMessage.getMessage()));
-
- message.decrementReference(_storeContext);
+ new AMQShortString(bouncedMessage.getMessage()));
}
_returnMessages.clear();
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 1723d46ef0..8d41cc58d2 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
@@ -82,13 +82,13 @@ public class ExtractResendAndRequeue implements UnacknowledgedMessageMap.Visitor
}
else
{
- queueEntry.discard(_storeContext);
+ queueEntry.dequeueAndDelete(_storeContext);
_log.info("No DeadLetter Queue and requeue not requested so dropping message:" + queueEntry);
}
}
else
{
- queueEntry.discard(_storeContext);
+ queueEntry.dequeueAndDelete(_storeContext);
_log.warn("Message.queue is null and no DeadLetter Queue so dropping message:" + queueEntry);
}
}
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 f3b54034e7..49619ac5b0 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
@@ -20,6 +20,14 @@
*/
package org.apache.qpid.server;
+import java.io.File;
+import java.io.IOException;
+import java.net.BindException;
+import java.net.InetAddress;
+import java.net.InetSocketAddress;
+
+import javax.management.NotCompliantMBeanException;
+
import org.apache.commons.cli.CommandLine;
import org.apache.commons.cli.HelpFormatter;
import org.apache.commons.cli.Option;
@@ -27,36 +35,26 @@ 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.commons.configuration.Configuration;
-import org.apache.commons.configuration.ConfigurationException;
import org.apache.log4j.BasicConfigurator;
import org.apache.log4j.Logger;
import org.apache.log4j.xml.DOMConfigurator;
import org.apache.mina.common.ByteBuffer;
-import org.apache.mina.common.IoAcceptor;
import org.apache.mina.common.FixedSizeByteBufferAllocator;
+import org.apache.mina.common.IoAcceptor;
import org.apache.mina.transport.socket.nio.SocketAcceptorConfig;
import org.apache.mina.transport.socket.nio.SocketSessionConfig;
+import org.apache.mina.util.NewThreadExecutor;
import org.apache.qpid.AMQException;
import org.apache.qpid.common.QpidProperties;
import org.apache.qpid.framing.ProtocolVersion;
import org.apache.qpid.pool.ReadWriteThreadModel;
-import org.apache.qpid.server.configuration.VirtualHostConfiguration;
-import org.apache.qpid.server.management.JMXManagedObjectRegistry;
+import org.apache.qpid.server.configuration.ServerConfiguration;
+import org.apache.qpid.server.configuration.management.ConfigurationManagementMBean;
+import org.apache.qpid.server.logging.management.LoggingManagementMBean;
import org.apache.qpid.server.protocol.AMQPFastProtocolHandler;
import org.apache.qpid.server.protocol.AMQPProtocolProvider;
import org.apache.qpid.server.registry.ApplicationRegistry;
import org.apache.qpid.server.registry.ConfigurationFileApplicationRegistry;
-import org.apache.qpid.server.transport.ConnectorConfiguration;
-import org.apache.qpid.url.URLSyntaxException;
-
-import java.io.File;
-import java.io.IOException;
-import java.net.BindException;
-import java.net.InetAddress;
-import java.net.InetSocketAddress;
-import java.util.Collection;
-import java.util.List;
/**
* Main entry point for AMQPD.
@@ -200,13 +198,6 @@ public class Main
_brokerLogger.error("Initialisation Error : " + e.getMessage());
shutdown(1);
}
- catch (ConfigurationException e)
- {
- System.out.println("Error configuring message broker: " + e);
- _brokerLogger.error("Error configuring message broker: " + e);
- e.printStackTrace();
- shutdown(1);
- }
catch (Throwable e)
{
System.out.println("Error initialising message broker: " + e);
@@ -223,7 +214,7 @@ public class Main
System.exit(status);
}
- protected void startup() throws InitException, ConfigurationException, Exception
+ protected void startup() throws Exception
{
final String QpidHome = System.getProperty(QPID_HOME);
final File defaultConfigFile = new File(QpidHome, DEFAULT_CONFIG_FILE);
@@ -246,53 +237,63 @@ public class Main
String logConfig = commandLine.getOptionValue("l");
String logWatchConfig = commandLine.getOptionValue("w", "0");
+
+ int logWatchTime = 0;
+ try
+ {
+ logWatchTime = Integer.parseInt(logWatchConfig);
+ }
+ catch (NumberFormatException e)
+ {
+ System.err.println("Log watch configuration value of " + logWatchConfig + " is invalid. Must be "
+ + "a non-negative integer. Using default of zero (no watching configured");
+ }
+
+ File logConfigFile;
if (logConfig != null)
{
- File logConfigFile = new File(logConfig);
- configureLogging(logConfigFile, logWatchConfig);
+ logConfigFile = new File(logConfig);
+ configureLogging(logConfigFile, logWatchTime);
}
else
{
File configFileDirectory = configFile.getParentFile();
- File logConfigFile = new File(configFileDirectory, DEFAULT_LOG_CONFIG_FILENAME);
- configureLogging(logConfigFile, logWatchConfig);
+ logConfigFile = new File(configFileDirectory, DEFAULT_LOG_CONFIG_FILENAME);
+ configureLogging(logConfigFile, logWatchTime);
}
ConfigurationFileApplicationRegistry config = new ConfigurationFileApplicationRegistry(configFile);
-
-
- updateManagementPort(config.getConfiguration(), commandLine.getOptionValue("m"));
-
-
+ ServerConfiguration serverConfig = config.getConfiguration();
+ updateManagementPort(serverConfig, commandLine.getOptionValue("m"));
ApplicationRegistry.initialise(config);
+
+ configureLoggingManagementMBean(logConfigFile, logWatchTime);
-
+ ConfigurationManagementMBean configMBean = new ConfigurationManagementMBean();
+ configMBean.register();
+
//fixme .. use QpidProperties.getVersionString when we have fixed the classpath issues
// that are causing the broker build to pick up the wrong properties file and hence say
// Starting Qpid Client
_brokerLogger.info("Starting Qpid Broker " + QpidProperties.getReleaseVersion()
+ " build: " + QpidProperties.getBuildVersion());
- ConnectorConfiguration connectorConfig =
- ApplicationRegistry.getInstance().getConfiguredObject(ConnectorConfiguration.class);
-
- ByteBuffer.setUseDirectBuffers(connectorConfig.enableDirectBuffers);
+ ByteBuffer.setUseDirectBuffers(serverConfig.getEnableDirectBuffers());
// the MINA default is currently to use the pooled allocator although this may change in future
// once more testing of the performance of the simple allocator has been done
- if (!connectorConfig.enablePooledAllocator)
+ if (!serverConfig.getEnablePooledAllocator())
{
ByteBuffer.setAllocator(new FixedSizeByteBufferAllocator());
}
-
- if(connectorConfig.useBiasedWrites)
+ if(serverConfig.getUseBiasedWrites())
{
System.setProperty("org.apache.qpid.use_write_biased_pool","true");
}
- int port = connectorConfig.port;
+ int port = serverConfig.getPort();
String portStr = commandLine.getOptionValue("p");
if (portStr != null)
@@ -306,29 +307,8 @@ public class Main
throw new InitException("Invalid port: " + portStr, e);
}
}
-
- String VIRTUAL_HOSTS = "virtualhosts";
-
- Object virtualHosts = ApplicationRegistry.getInstance().getConfiguration().getProperty(VIRTUAL_HOSTS);
-
- if (virtualHosts != null)
- {
- if (virtualHosts instanceof Collection)
- {
- int totalVHosts = ((Collection) virtualHosts).size();
- for (int vhost = 0; vhost < totalVHosts; vhost++)
- {
- setupVirtualHosts(configFile.getParent(), (String) ((List) virtualHosts).get(vhost));
- }
- }
- else
- {
- setupVirtualHosts(configFile.getParent(), (String) virtualHosts);
- }
- }
-
- bind(port, connectorConfig);
-
+
+ bind(port, serverConfig);
}
/**
@@ -336,86 +316,59 @@ public class Main
* @param configuration
* @param managementPort The string from the command line
*/
- private void updateManagementPort(Configuration configuration, String managementPort)
+ private void updateManagementPort(ServerConfiguration configuration, String managementPort)
{
if (managementPort != null)
{
- int mport;
- int defaultMPort = configuration.getInt(JMXManagedObjectRegistry.MANAGEMENT_PORT_CONFIG_PATH);
try
{
- mport = Integer.parseInt(managementPort);
- configuration.setProperty(JMXManagedObjectRegistry.MANAGEMENT_PORT_CONFIG_PATH, mport);
+ configuration.setJMXManagementPort(Integer.parseInt(managementPort));
}
catch (NumberFormatException e)
{
- _logger.warn("Invalid management port: " + managementPort + " will use default:" + defaultMPort, e);
- }
- }
- }
-
- protected void setupVirtualHosts(String configFileParent, String configFilePath)
- throws ConfigurationException, AMQException, URLSyntaxException
- {
- String configVar = "${conf}";
-
- if (configFilePath.startsWith(configVar))
- {
- configFilePath = configFileParent + configFilePath.substring(configVar.length());
- }
-
- if (configFilePath.indexOf(".xml") != -1)
- {
- VirtualHostConfiguration vHostConfig = new VirtualHostConfiguration(configFilePath);
- vHostConfig.performBindings();
- }
- else
- {
- // the virtualhosts value is a path. Search it for XML files.
-
- File virtualHostDir = new File(configFilePath);
-
- String[] fileNames = virtualHostDir.list();
-
- for (int each = 0; each < fileNames.length; each++)
- {
- if (fileNames[each].endsWith(".xml"))
- {
- VirtualHostConfiguration vHostConfig =
- new VirtualHostConfiguration(configFilePath + "/" + fileNames[each]);
- vHostConfig.performBindings();
- }
+ _logger.warn("Invalid management port: " + managementPort + " will use:" + configuration.getJMXManagementPort(), e);
}
}
}
- protected void bind(int port, ConnectorConfiguration connectorConfig) throws BindException
+ protected void bind(int port, ServerConfiguration config) throws BindException
{
String bindAddr = commandLine.getOptionValue("b");
if (bindAddr == null)
{
- bindAddr = connectorConfig.bindAddress;
+ bindAddr = config.getBind();
}
try
{
- // IoAcceptor acceptor = new SocketAcceptor(connectorConfig.processors);
- IoAcceptor acceptor = connectorConfig.createAcceptor();
+ IoAcceptor acceptor;
+
+ if (ApplicationRegistry.getInstance().getConfiguration().getQpidNIO())
+ {
+ _logger.warn("Using Qpid Multithreaded IO Processing");
+ acceptor = new org.apache.mina.transport.socket.nio.MultiThreadSocketAcceptor(config.getProcessors(), new NewThreadExecutor());
+ }
+ else
+ {
+ _logger.warn("Using Mina IO Processing");
+ acceptor = new org.apache.mina.transport.socket.nio.SocketAcceptor(config.getProcessors(), new NewThreadExecutor());
+ }
+
SocketAcceptorConfig sconfig = (SocketAcceptorConfig) acceptor.getDefaultConfig();
SocketSessionConfig sc = (SocketSessionConfig) sconfig.getSessionConfig();
- sc.setReceiveBufferSize(connectorConfig.socketReceiveBufferSize);
- sc.setSendBufferSize(connectorConfig.socketWriteBuferSize);
- sc.setTcpNoDelay(connectorConfig.tcpNoDelay);
+ sc.setReceiveBufferSize(config.getReceiveBufferSize());
+ sc.setSendBufferSize(config.getWriteBufferSize());
+ sc.setTcpNoDelay(config.getTcpNoDelay());
// if we do not use the executor pool threading model we get the default leader follower
// implementation provided by MINA
- if (connectorConfig.enableExecutorPool)
+ if (config.getEnableExecutorPool())
{
sconfig.setThreadModel(ReadWriteThreadModel.getInstance());
}
- if (!connectorConfig.enableSSL || !connectorConfig.sslOnly)
+ if (!config.getEnableSSL() || !config.getSSLOnly())
{
AMQPFastProtocolHandler handler = new AMQPProtocolProvider().getHandler();
InetSocketAddress bindAddress;
@@ -434,16 +387,16 @@ public class Main
_brokerLogger.info("Qpid.AMQP listening on non-SSL address " + bindAddress);
}
- if (connectorConfig.enableSSL)
+ if (config.getEnableSSL())
{
AMQPFastProtocolHandler handler = new AMQPProtocolProvider().getHandler();
try
{
- bind(acceptor, new InetSocketAddress(connectorConfig.sslPort), handler, sconfig);
+ bind(acceptor, new InetSocketAddress(config.getSSLPort()), handler, sconfig);
//fixme qpid.AMQP should be using qpidproperties to get value
- _brokerLogger.info("Qpid.AMQP listening on SSL port " + connectorConfig.sslPort);
+ _brokerLogger.info("Qpid.AMQP listening on SSL port " + config.getSSLPort());
}
catch (IOException e)
@@ -515,19 +468,8 @@ public class Main
return ip;
}
- private void configureLogging(File logConfigFile, String logWatchConfig)
+ private void configureLogging(File logConfigFile, int logWatchTime)
{
- int logWatchTime = 0;
- try
- {
- logWatchTime = Integer.parseInt(logWatchConfig);
- }
- catch (NumberFormatException e)
- {
- System.err.println("Log watch configuration value of " + logWatchConfig + " is invalid. Must be "
- + "a non-negative integer. Using default of zero (no watching configured");
- }
-
if (logConfigFile.exists() && logConfigFile.canRead())
{
System.out.println("Configuring logger using configuration file " + logConfigFile.getAbsolutePath());
@@ -551,4 +493,17 @@ public class Main
}
}
+ private void configureLoggingManagementMBean(File logConfigFile, int logWatchTime) throws Exception
+ {
+ LoggingManagementMBean blm = new LoggingManagementMBean(logConfigFile.getPath(),logWatchTime);
+
+ try
+ {
+ blm.register();
+ }
+ catch (AMQException e)
+ {
+ throw new InitException("Unable to initialise the Logging Management MBean: ", e);
+ }
+ }
}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/RequiredDeliveryException.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/RequiredDeliveryException.java
index 3f1947d65a..a81b2cc2db 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/RequiredDeliveryException.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/RequiredDeliveryException.java
@@ -56,13 +56,10 @@ public abstract class RequiredDeliveryException extends AMQException
public void setMessage(final AMQMessage payload)
{
-
- // Increment the reference as this message is in the routing phase
- // and so will have the ref decremented as routing fails.
// we need to keep this message around so we can return it in the
- // handler. So increment here.
- _amqMessage = payload.takeReference();
-
+ // handler.
+ // Messages are all kept in memory now. Only queues can push messages out of memory.
+ _amqMessage = payload;
}
public AMQMessage getAMQMessage()
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/ack/TxAck.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/ack/TxAck.java
index db3a05eb52..95de0dc8c3 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/ack/TxAck.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/ack/TxAck.java
@@ -20,7 +20,6 @@
*/
package org.apache.qpid.server.ack;
-import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.HashMap;
@@ -103,7 +102,7 @@ public class TxAck implements TxnOp
//buffer must be marked as persistent:
for (QueueEntry msg : _unacked.values())
{
- if (msg.getMessage().isPersistent())
+ if (msg.isPersistent())
{
return true;
}
@@ -116,22 +115,20 @@ public class TxAck implements TxnOp
//make persistent changes, i.e. dequeue and decrementReference
for (QueueEntry msg : _unacked.values())
{
- //Message has been ack so discard it. This will dequeue and decrement the reference.
- msg.discard(storeContext);
-
+ //Message has been ack so dequeueAndDelete it.
+ // If the message is persistent and this is the last QueueEntry that uses it then the data will be removed
+ // from the transaciton log
+ msg.dequeueAndDelete(storeContext);
}
}
public void undoPrepare()
{
- //decrementReference is annoyingly untransactional (due to
- //in memory counter) so if we failed in prepare for full
- //txn, this op will have to compensate by fixing the count
- //in memory (persistent changes will be rolled back by store)
- for (QueueEntry msg : _unacked.values())
- {
- msg.getMessage().takeReference();
- }
+ //As this is transaction the above dequeueAndDelete will only request the message be dequeue from the
+ // transactionLog. Only when the transaction succesfully completes will it perform any
+ // update of the internal transactionLog reference counting and any resulting message data deletion.
+ // The success or failure of the data deletion is not important to this transaction only that the ack has been
+ // successfully recorded.
}
public void commit(StoreContext storeContext)
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 efdadd4922..5c38185696 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
@@ -89,7 +89,7 @@ public class UnacknowledgedMessageMapImpl implements UnacknowledgedMessageMap
QueueEntry message = _map.remove(deliveryTag);
if(message != null)
{
- _unackedSize -= message.getMessage().getSize();
+ _unackedSize -= message.getSize();
}
@@ -115,7 +115,7 @@ public class UnacknowledgedMessageMapImpl implements UnacknowledgedMessageMap
synchronized (_lock)
{
_map.put(deliveryTag, message);
- _unackedSize += message.getMessage().getSize();
+ _unackedSize += message.getSize();
_lastDeliveryTag = deliveryTag;
}
}
@@ -174,12 +174,14 @@ public class UnacknowledgedMessageMapImpl implements UnacknowledgedMessageMap
" When deliveryTag is:" + deliveryTag + "ES:" + _map.entrySet().toString());
}
- //Message has been ack so discard it. This will dequeue and decrement the reference.
- unacked.getValue().discard(storeContext);
+ //Message has been ack so dequeueAndDelete it.
+ // If the message is persistent and this is the last QueueEntry that uses it then the data will be removed
+ // from the transaciton log
+ unacked.getValue().dequeueAndDelete(storeContext);
it.remove();
- _unackedSize -= unacked.getValue().getMessage().getSize();
+ _unackedSize -= unacked.getValue().getSize();
if (unacked.getKey() == deliveryTag)
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/Configurator.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/Configurator.java
deleted file mode 100644
index 31c1b61a21..0000000000
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/Configurator.java
+++ /dev/null
@@ -1,118 +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.server.configuration;
-
-import java.lang.reflect.Field;
-
-import org.apache.commons.configuration.Configuration;
-import org.apache.log4j.Logger;
-import org.apache.qpid.configuration.Configured;
-import org.apache.qpid.configuration.PropertyException;
-import org.apache.qpid.configuration.PropertyUtils;
-import org.apache.qpid.server.registry.ApplicationRegistry;
-
-/**
- * This class contains utilities for populating classes automatically from values pulled from configuration
- * files.
- */
-public class Configurator
-{
- private static final Logger _logger = Logger.getLogger(Configurator.class);
-
-
- /**
- * Configure a given instance using the supplied configuration. Note that superclasses are <b>not</b>
- * currently configured but this could easily be added if required.
- * @param instance the instance to configure
- * @param config the configuration to use to configure the object
- */
- public static void configure(Object instance, Configuration config)
- {
-
- for (Field f : instance.getClass().getDeclaredFields())
- {
- Configured annotation = f.getAnnotation(Configured.class);
- if (annotation != null)
- {
- setValueInField(f, instance, config, annotation);
- }
- }
- }
-
-
-
- /**
- * Configure a given instance using the application configuration. Note that superclasses are <b>not</b>
- * currently configured but this could easily be added if required.
- * @param instance the instance to configure
- */
- public static void configure(Object instance)
- {
- configure(instance, ApplicationRegistry.getInstance().getConfiguration());
- }
-
- private static void setValueInField(Field f, Object instance, Configuration config, Configured annotation)
- {
- Class fieldClass = f.getType();
- String configPath = annotation.path();
- try
- {
- if (fieldClass == String.class)
- {
- String val = config.getString(configPath, annotation.defaultValue());
- val = PropertyUtils.replaceProperties(val);
- f.set(instance, val);
- }
- else if (fieldClass == int.class)
- {
- int val = config.getInt(configPath, Integer.parseInt(annotation.defaultValue()));
- f.setInt(instance, val);
- }
- else if (fieldClass == long.class)
- {
- long val = config.getLong(configPath, Long.parseLong(annotation.defaultValue()));
- f.setLong(instance, val);
- }
- else if (fieldClass == double.class)
- {
- double val = config.getDouble(configPath, Double.parseDouble(annotation.defaultValue()));
- f.setDouble(instance, val);
- }
- else if (fieldClass == boolean.class)
- {
- boolean val = config.getBoolean(configPath, Boolean.parseBoolean(annotation.defaultValue()));
- f.setBoolean(instance, val);
- }
- else
- {
- _logger.error("Unsupported field type " + fieldClass + " for " + f + " IGNORING configured value");
- }
- }
- catch (PropertyException e)
- {
- _logger.error("Unable to expand property: " + e + " INGORING field " + f, e);
- }
- catch (IllegalAccessException e)
- {
- _logger.error("Unable to access field " + f + " IGNORING configured value");
- }
- }
-}
diff --git a/qpid/java/broker/src/test/java/org/apache/qpid/server/store/TestMemoryMessageStore.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/ExchangeConfiguration.java
index 4e48435962..c7cf0c0892 100644
--- a/qpid/java/broker/src/test/java/org/apache/qpid/server/store/TestMemoryMessageStore.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/ExchangeConfiguration.java
@@ -7,9 +7,9 @@
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
- *
+ *
* http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
@@ -18,34 +18,41 @@
* under the License.
*
*/
-package org.apache.qpid.server.store;
+package org.apache.qpid.server.configuration;
-import org.apache.qpid.server.queue.MessageMetaData;
-import org.apache.qpid.framing.ContentBody;
-import org.apache.qpid.framing.abstraction.ContentChunk;
+import org.apache.commons.configuration.Configuration;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.ConcurrentMap;
-import java.util.List;
-/**
- * Adds some extra methods to the memory message store for testing purposes.
- */
-public class TestMemoryMessageStore extends MemoryMessageStore
+public class ExchangeConfiguration
{
- public TestMemoryMessageStore()
+
+ private Configuration _config;
+ private String _name;
+
+ public ExchangeConfiguration(String exchName, Configuration subset)
+ {
+ _name = exchName;
+ _config = subset;
+ }
+
+ public String getName()
+ {
+ return _name;
+ }
+
+ public String getType()
{
- _metaDataMap = new ConcurrentHashMap<Long, MessageMetaData>();
- _contentBodyMap = new ConcurrentHashMap<Long, List<ContentChunk>>();
+ return _config.getString("type","direct");
}
- public ConcurrentMap<Long, MessageMetaData> getMessageMetaDataMap()
+ public boolean getDurable()
{
- return _metaDataMap;
+ return _config.getBoolean("durable", false);
}
- public ConcurrentMap<Long, List<ContentChunk>> getContentBodyMap()
+ public boolean getAutoDelete()
{
- return _contentBodyMap;
+ return _config.getBoolean("autodelete",false);
}
+
}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/QueueConfiguration.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/QueueConfiguration.java
new file mode 100644
index 0000000000..e6c5dee90d
--- /dev/null
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/QueueConfiguration.java
@@ -0,0 +1,124 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.qpid.server.configuration;
+
+import java.util.List;
+import java.io.File;
+
+import org.apache.commons.configuration.Configuration;
+import org.apache.qpid.server.registry.ApplicationRegistry;
+
+public class QueueConfiguration
+{
+
+ // FIXME AIDAN XXX -- deal with defaults
+
+ private Configuration _config;
+ private String _name;
+ private VirtualHostConfiguration _virtualHostConfiguration;
+
+ public QueueConfiguration(String name, Configuration config, VirtualHostConfiguration virtualHostConfiguration)
+ {
+ _virtualHostConfiguration = virtualHostConfiguration;
+ _config = config;
+ _name = name;
+ }
+
+ public VirtualHostConfiguration getVirtualHostConfiguration()
+ {
+ return _virtualHostConfiguration;
+ }
+
+ public boolean getDurable()
+ {
+ return _config.getBoolean("durable" ,false);
+ }
+
+ public boolean getAutoDelete()
+ {
+ return _config.getBoolean("autodelete", false);
+ }
+
+ public String getOwner()
+ {
+ return _config.getString("owner", null);
+ }
+
+ public boolean getPriority()
+ {
+ return _config.getBoolean("priority", false);
+ }
+
+ public int getPriorities()
+ {
+ return _config.getInt("priorities", -1);
+ }
+
+ public String getExchange()
+ {
+ return _config.getString("exchange", null);
+ }
+
+ public List getRoutingKeys()
+ {
+ return _config.getList("routingKey");
+ }
+
+ public String getName()
+ {
+ return _name;
+ }
+
+ public long getMaximumMessageAge()
+ {
+ return _config.getLong("maximumMessageAge", 0);
+ }
+
+ public long getMaximumQueueDepth()
+ {
+ return _config.getLong("maximumQueueDepth", 0);
+ }
+
+ public long getMaximumMessageSize()
+ {
+ return _config.getLong("maximumMessageSize", 0);
+ }
+
+ public long getMaximumMessageCount()
+ {
+ return _config.getLong("maximumMessageCount", 0);
+ }
+
+ public long getMinimumAlertRepeatGap()
+ {
+ return _config.getLong("minimumAlertRepeatGap", 0);
+ }
+
+ public long getMemoryUsageMaximum()
+ {
+ return _config.getLong("maximumMemoryUsage", 100 * 1024 * 1024); //100Meg
+ }
+
+ public long getMemoryUsageMinimum()
+ {
+ return _config.getLong("minimumMemoryUsage", 0);
+ }
+}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/SecurityConfiguration.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/SecurityConfiguration.java
new file mode 100644
index 0000000000..5d080f8df1
--- /dev/null
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/SecurityConfiguration.java
@@ -0,0 +1,41 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ *
+ */
+
+package org.apache.qpid.server.configuration;
+
+import org.apache.commons.configuration.Configuration;
+
+public class SecurityConfiguration
+{
+
+ private Configuration _conf;
+
+ public SecurityConfiguration(Configuration configuration)
+ {
+ _conf = configuration;
+ }
+
+ public Configuration getConfiguration()
+ {
+ return _conf;
+ }
+
+}
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
new file mode 100644
index 0000000000..c0fe42c5c2
--- /dev/null
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/ServerConfiguration.java
@@ -0,0 +1,514 @@
+/*
+ * 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.configuration;
+
+import java.io.File;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+
+import org.apache.commons.configuration.CompositeConfiguration;
+import org.apache.commons.configuration.Configuration;
+import org.apache.commons.configuration.ConfigurationException;
+import org.apache.commons.configuration.ConfigurationFactory;
+import org.apache.commons.configuration.SystemConfiguration;
+import org.apache.commons.configuration.XMLConfiguration;
+import org.apache.qpid.server.configuration.management.ConfigurationManagementMBean;
+import org.apache.qpid.server.registry.ApplicationRegistry;
+import org.apache.qpid.server.virtualhost.VirtualHost;
+import org.apache.qpid.server.virtualhost.VirtualHostRegistry;
+import org.apache.qpid.tools.messagestore.MessageStoreTool;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import sun.misc.Signal;
+import sun.misc.SignalHandler;
+
+public class ServerConfiguration implements SignalHandler
+{
+
+ private static Configuration _config;
+
+ private static final int DEFAULT_FRAME_SIZE = 65536;
+ private static final int DEFAULT_BUFFER_READ_LIMIT_SIZE = 262144;
+ private static final int DEFAULT_BUFFER_WRITE_LIMIT_SIZE = 262144;
+ private static final int DEFAULT_PORT = 5672;
+ private static final int DEFAUL_SSL_PORT = 8672;
+ private static final long DEFAULT_HOUSEKEEPING_PERIOD = 30000L;
+ private static final int DEFAULT_JMXPORT = 8999;
+
+ private static int _jmxPort = DEFAULT_JMXPORT;
+
+ private Map<String, VirtualHostConfiguration> _virtualHosts = new HashMap<String, VirtualHostConfiguration>();
+ private SecurityConfiguration _securityConfiguration = null;
+
+ private File _configFile;
+
+ private Logger _log = LoggerFactory.getLogger(this.getClass());
+
+ private ConfigurationManagementMBean _mbean;
+
+
+ // Map of environment variables to config items
+ private static final Map<String, String> envVarMap = new HashMap<String, String>();
+
+ {
+ envVarMap.put("QPID_PORT", "connector.port");
+ envVarMap.put("QPID_ENABLEDIRECTBUFFERS", "advanced.enableDirectBuffers");
+ envVarMap.put("QPID_SSLPORT", "connector.ssl.port");
+ envVarMap.put("QPID_NIO", "connector.qpidnio");
+ envVarMap.put("QPID_WRITEBIASED", "advanced.useWriteBiasedPool");
+ envVarMap.put("QPID_JMXPORT", "management.jmxport");
+ envVarMap.put("QPID_FRAMESIZE", "advanced.framesize");
+ envVarMap.put("QPID_MSGAUTH", "security.msg-auth");
+ envVarMap.put("QPID_AUTOREGISTER", "auto_register");
+ envVarMap.put("QPID_MANAGEMENTENABLED", "management.enabled");
+ envVarMap.put("QPID_HEARTBEATDELAY", "heartbeat.delay");
+ envVarMap.put("QPID_HEARTBEATTIMEOUTFACTOR", "heartbeat.timeoutFactor");
+ envVarMap.put("QPID_MAXIMUMMESSAGEAGE", "maximumMessageAge");
+ envVarMap.put("QPID_MAXIMUMMESSAGECOUNT", "maximumMessageCount");
+ envVarMap.put("QPID_MAXIMUMQUEUEDEPTH", "maximumQueueDepth");
+ envVarMap.put("QPID_MAXIMUMMESSAGESIZE", "maximumMessageSize");
+ envVarMap.put("QPID_MINIMUMALERTREPEATGAP", "minimumAlertRepeatGap");
+ envVarMap.put("QPID_SOCKETRECEIVEBUFFER", "connector.socketReceiveBuffer");
+ envVarMap.put("QPID_SOCKETWRITEBUFFER", "connector.socketWriteBuffer");
+ envVarMap.put("QPID_TCPNODELAY", "connector.tcpNoDelay");
+ envVarMap.put("QPID_ENABLEPOOLEDALLOCATOR", "advanced.enablePooledAllocator");
+ }
+
+ public ServerConfiguration(File configurationURL) throws ConfigurationException
+ {
+ this(parseConfig(configurationURL));
+ _configFile = configurationURL;
+ sun.misc.Signal.handle(new sun.misc.Signal("HUP"), this);
+ }
+
+ public ServerConfiguration(Configuration conf) throws ConfigurationException
+ {
+ _config = conf;
+
+ substituteEnvironmentVariables();
+
+ _jmxPort = _config.getInt("management.jmxport", 8999);
+ _securityConfiguration = new SecurityConfiguration(conf.subset("security"));
+
+ setupVirtualHosts(conf);
+
+ }
+
+ private void setupVirtualHosts(Configuration conf) throws ConfigurationException
+ {
+ List vhosts = conf.getList("virtualhosts");
+ Iterator i = vhosts.iterator();
+ while (i.hasNext())
+ {
+ Object thing = i.next();
+ if (thing instanceof String)
+ {
+ XMLConfiguration vhostConfiguration = new XMLConfiguration((String) thing);
+ List hosts = vhostConfiguration.getList("virtualhost.name");
+ for (int j = 0; j < hosts.size(); j++)
+ {
+ String name = (String) hosts.get(j);
+ CompositeConfiguration mungedConf = new CompositeConfiguration();
+ mungedConf.addConfiguration(conf.subset("virtualhosts.virtualhost."+name));
+ mungedConf.addConfiguration(vhostConfiguration.subset("virtualhost." + name));
+ VirtualHostConfiguration vhostConfig = new VirtualHostConfiguration(name, mungedConf, this);
+ _virtualHosts.put(vhostConfig.getName(), vhostConfig);
+ }
+ }
+ }
+ }
+
+ private void substituteEnvironmentVariables()
+ {
+ for (Entry<String, String> var : envVarMap.entrySet())
+ {
+ String val = System.getenv(var.getKey());
+ if (val != null)
+ {
+ _config.setProperty(var.getValue(), val);
+ }
+ }
+ }
+
+ private final static Configuration parseConfig(File file) throws ConfigurationException
+ {
+ ConfigurationFactory factory = new ConfigurationFactory();
+ factory.setConfigurationFileName(file.getAbsolutePath());
+ Configuration conf = factory.getConfiguration();
+ Iterator keys = conf.getKeys();
+ if (!keys.hasNext())
+ {
+ keys = null;
+ conf = flatConfig(file);
+ }
+ return conf;
+ }
+
+ // Our configuration class needs to make the interpolate method
+ // public so it can be called below from the config method.
+ private static class MyConfiguration extends CompositeConfiguration
+ {
+ public String interpolate(String obj)
+ {
+ return super.interpolate(obj);
+ }
+ }
+
+ private final static Configuration flatConfig(File file) throws ConfigurationException
+ {
+ // We have to override the interpolate methods so that
+ // interpolation takes place accross the entirety of the
+ // composite configuration. Without doing this each
+ // configuration object only interpolates variables defined
+ // inside itself.
+ final MyConfiguration conf = new MyConfiguration();
+ conf.addConfiguration(new SystemConfiguration()
+ {
+ protected String interpolate(String o)
+ {
+ return conf.interpolate(o);
+ }
+ });
+ conf.addConfiguration(new XMLConfiguration(file)
+ {
+ protected String interpolate(String o)
+ {
+ return conf.interpolate(o);
+ }
+ });
+ return conf;
+ }
+
+ @Override
+ public void handle(Signal arg0)
+ {
+ try
+ {
+ reparseConfigFile();
+ }
+ catch (ConfigurationException e)
+ {
+ _log.error("Could not reload configuration file", e);
+ }
+ }
+
+ public void reparseConfigFile() throws ConfigurationException
+ {
+ if (_configFile != null)
+ {
+ Configuration newConfig = parseConfig(_configFile);
+ _securityConfiguration = new SecurityConfiguration(newConfig.subset("security"));
+ ApplicationRegistry.getInstance().getAccessManager().configurePlugins(_securityConfiguration);
+
+ VirtualHostRegistry vhostRegistry = ApplicationRegistry.getInstance().getVirtualHostRegistry();
+ for (String hostname : _virtualHosts.keySet())
+ {
+ VirtualHost vhost = vhostRegistry.getVirtualHost(hostname);
+ SecurityConfiguration hostSecurityConfig = new SecurityConfiguration(newConfig.subset("virtualhosts.virtualhost."+hostname+".security"));
+ vhost.getAccessManager().configureHostPlugins(hostSecurityConfig);
+ }
+ }
+ }
+
+ public String getQpidWork()
+ {
+ return System.getProperty("QPID_WORK", System.getProperty("java.io.tmpdir"));
+ }
+
+ public void setJMXManagementPort(int mport)
+ {
+ _jmxPort = mport;
+ }
+
+ public int getJMXManagementPort()
+ {
+ return _jmxPort;
+ }
+
+ public boolean getPlatformMbeanserver()
+ {
+ return _config.getBoolean("management.platform-mbeanserver", true);
+ }
+
+ public String[] getVirtualHosts()
+ {
+ return _virtualHosts.keySet().toArray(new String[_virtualHosts.size()]);
+ }
+
+ public String getPluginDirectory()
+ {
+ return _config.getString("plugin-directory");
+ }
+
+ public VirtualHostConfiguration getVirtualHostConfig(String name)
+ {
+ return _virtualHosts.get(name);
+ }
+
+ public List<String> getPrincipalDatabaseNames()
+ {
+ return _config.getList("security.principal-databases.principal-database.name");
+ }
+
+ public List<String> getPrincipalDatabaseClass()
+ {
+ return _config.getList("security.principal-databases.principal-database.class");
+ }
+
+ public List<String> getPrincipalDatabaseAttributeNames(int index)
+ {
+ String name = "security.principal-databases.principal-database(" + index + ")." + "attributes.attribute.name";
+ return _config.getList(name);
+ }
+
+ public List<String> getPrincipalDatabaseAttributeValues(int index)
+ {
+ String name = "security.principal-databases.principal-database(" + index + ")." + "attributes.attribute.value";
+ return _config.getList(name);
+ }
+
+ public List<String> getManagementPrincipalDBs()
+ {
+ return _config.getList("security.jmx.principal-database");
+ }
+
+ public List<String> getManagementAccessList()
+ {
+ return _config.getList("security.jmx.access");
+ }
+
+ public int getFrameSize()
+ {
+ return _config.getInt("advanced.framesize", DEFAULT_FRAME_SIZE);
+ }
+
+ public boolean getProtectIOEnabled()
+ {
+ return _config.getBoolean("broker.connector.protectio.enabled", false);
+ }
+
+ public int getBufferReadLimit()
+ {
+ return _config.getInt("broker.connector.protectio.readBufferLimitSize", DEFAULT_BUFFER_READ_LIMIT_SIZE);
+ }
+
+ public int getBufferWriteLimit()
+ {
+ return _config.getInt("broker.connector.protectio.writeBufferLimitSize", DEFAULT_BUFFER_WRITE_LIMIT_SIZE);
+ }
+
+ public boolean getSynchedClocks()
+ {
+ return _config.getBoolean("advanced.synced-clocks", false);
+ }
+
+ public boolean getMsgAuth()
+ {
+ return _config.getBoolean("security.msg-auth", false);
+ }
+
+ public String getJMXPrincipalDatabase()
+ {
+ return _config.getString("security.jmx.principal-database");
+ }
+
+ public String getManagementKeyStorePath()
+ {
+ return _config.getString("management.ssl.keyStorePath", null);
+ }
+
+ public boolean getManagementSSLEnabled()
+ {
+ return _config.getBoolean("management.ssl.enabled", true);
+ }
+
+ public String getManagementKeyStorePassword()
+ {
+ return _config.getString("management.ssl.keyStorePassword");
+ }
+
+ public SecurityConfiguration getSecurityConfiguration()
+ {
+ return _securityConfiguration;
+ }
+
+ public boolean getQueueAutoRegister()
+ {
+ return _config.getBoolean("queue.auto_register", true);
+ }
+
+ public boolean getManagementEnabled()
+ {
+ return _config.getBoolean("management.enabled", true);
+ }
+
+ public void setManagementEnabled(boolean enabled)
+ {
+ _config.setProperty("management.enabled", enabled);
+ }
+
+
+ public int getHeartBeatDelay()
+ {
+ return _config.getInt("heartbeat.delay", 5);
+ }
+
+ public double getHeartBeatTimeout()
+ {
+ return _config.getDouble("heartbeat.timeoutFactor", 2.0);
+ }
+
+ public int getDeliveryPoolSize()
+ {
+ return _config.getInt("delivery.poolsize", 0);
+ }
+
+ public long getMaximumMessageAge()
+ {
+ return _config.getLong("maximumMessageAge", 0);
+ }
+
+ public long getMaximumMessageCount()
+ {
+ return _config.getLong("maximumMessageCount", 0);
+ }
+
+ public long getMaximumQueueDepth()
+ {
+ return _config.getLong("maximumQueueDepth", 0);
+ }
+
+ public long getMaximumMessageSize()
+ {
+ return _config.getLong("maximumMessageSize", 0);
+ }
+
+ public long getMinimumAlertRepeatGap()
+ {
+ return _config.getLong("minimumAlertRepeatGap", 0);
+ }
+
+ public int getProcessors()
+ {
+ return _config.getInt("connector.processors", 4);
+ }
+
+ public int getPort()
+ {
+ return _config.getInt("connector.port", DEFAULT_PORT);
+ }
+
+ public String getBind()
+ {
+ return _config.getString("connector.bind", "wildcard");
+ }
+
+ public int getReceiveBufferSize()
+ {
+ return _config.getInt("connector.socketReceiveBuffer", 32767);
+ }
+
+ public int getWriteBufferSize()
+ {
+ return _config.getInt("connector.socketWriteBuffer", 32767);
+ }
+
+ public boolean getTcpNoDelay()
+ {
+ return _config.getBoolean("connector.tcpNoDelay", true);
+ }
+
+ public boolean getEnableExecutorPool()
+ {
+ return _config.getBoolean("advanced.filterchain[@enableExecutorPool]", false);
+ }
+
+ public boolean getEnablePooledAllocator()
+ {
+ return _config.getBoolean("advanced.enablePooledAllocator", false);
+ }
+
+ public boolean getEnableDirectBuffers()
+ {
+ return _config.getBoolean("advanced.enableDirectBuffers", false);
+ }
+
+ public boolean getEnableSSL()
+ {
+ return _config.getBoolean("connector.ssl.enabled", false);
+ }
+
+ public boolean getSSLOnly()
+ {
+ return _config.getBoolean("connector.ssl.sslOnly", true);
+ }
+
+ public int getSSLPort()
+ {
+ return _config.getInt("connector.ssl.port", DEFAUL_SSL_PORT);
+ }
+
+ public String getKeystorePath()
+ {
+ return _config.getString("connector.ssl.keystorePath", "none");
+ }
+
+ public String getKeystorePassword()
+ {
+ return _config.getString("connector.ssl.keystorePassword", "none");
+ }
+
+ public String getCertType()
+ {
+ return _config.getString("connector.ssl.certType", "SunX509");
+ }
+
+ public boolean getQpidNIO()
+ {
+ return _config.getBoolean("connector.qpidnio", false);
+ }
+
+ public boolean getUseBiasedWrites()
+ {
+ return _config.getBoolean("advanced.useWriteBiasedPool", false);
+ }
+
+ public String getDefaultVirtualHost()
+ {
+ return _config.getString("virtualhosts.default");
+ }
+
+ public void setHousekeepingExpiredMessageCheckPeriod(long value)
+ {
+ _config.setProperty("housekeeping.expiredMessageCheckPeriod", value);
+ }
+
+ public long getHousekeepingCheckPeriod()
+ {
+ return _config.getLong("housekeeping.checkPeriod",
+ _config.getLong("housekeeping.expiredMessageCheckPeriod",
+ DEFAULT_HOUSEKEEPING_PERIOD));
+ }
+}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/VirtualHostConfiguration.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/VirtualHostConfiguration.java
index 02fb57c730..343abe4b5a 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/VirtualHostConfiguration.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/VirtualHostConfiguration.java
@@ -20,266 +20,150 @@
*/
package org.apache.qpid.server.configuration;
-import java.util.Collections;
+import java.util.HashMap;
+import java.util.Iterator;
import java.util.List;
+import java.util.Map;
import org.apache.commons.configuration.CompositeConfiguration;
import org.apache.commons.configuration.Configuration;
import org.apache.commons.configuration.ConfigurationException;
-import org.apache.commons.configuration.XMLConfiguration;
-import org.apache.log4j.Logger;
-import org.apache.qpid.AMQException;
-import org.apache.qpid.framing.AMQShortString;
-import org.apache.qpid.framing.FieldTable;
-import org.apache.qpid.server.exchange.Exchange;
-import org.apache.qpid.server.exchange.ExchangeRegistry;
-import org.apache.qpid.server.exchange.ExchangeFactory;
-import org.apache.qpid.server.queue.AMQQueue;
-import org.apache.qpid.server.queue.QueueRegistry;
-import org.apache.qpid.server.queue.AMQQueueFactory;
+import org.apache.commons.configuration.PropertiesConfiguration;
import org.apache.qpid.server.registry.ApplicationRegistry;
-import org.apache.qpid.server.virtualhost.VirtualHost;
-import org.apache.qpid.server.transactionlog.TransactionLog;
-import org.apache.qpid.server.routing.RoutingTable;
+import org.apache.qpid.server.store.MemoryMessageStore;
public class VirtualHostConfiguration
{
- private static final Logger _logger = Logger.getLogger(VirtualHostConfiguration.class);
-
- private static XMLConfiguration _config;
-
- private static final String VIRTUALHOST_PROPERTY_BASE = "virtualhost.";
-
-
- public VirtualHostConfiguration(String configFile) throws ConfigurationException
- {
- _logger.info("Loading Config file:" + configFile);
-
- _config = new XMLConfiguration(configFile);
-
- }
-
-
-
- private void configureVirtualHost(String virtualHostName, Configuration configuration) throws ConfigurationException, AMQException
+ private Configuration _config;
+ private String _name;
+ private Map<String, QueueConfiguration> _queues = new HashMap<String, QueueConfiguration>();
+ private Map<String, ExchangeConfiguration> _exchanges = new HashMap<String, ExchangeConfiguration>();
+ private ServerConfiguration _serverConfiguration;
+
+ public VirtualHostConfiguration(String name, Configuration config,
+ ServerConfiguration serverConfiguration) throws ConfigurationException
{
- _logger.debug("Loding configuration for virtaulhost: "+virtualHostName);
-
+ _serverConfiguration = serverConfiguration;
+ _config = config;
+ _name = name;
- VirtualHost virtualHost = ApplicationRegistry.getInstance().getVirtualHostRegistry().getVirtualHost(virtualHostName);
+ Iterator i = _config.getList("queues.queue.name").iterator();
-
-
- if(virtualHost == null)
+ while (i.hasNext())
{
- throw new ConfigurationException("Unknown virtual host: " + virtualHostName);
+ String queueName = (String) i.next();
+ CompositeConfiguration mungedConf = new CompositeConfiguration();
+ mungedConf.addConfiguration(_config.subset("queues.queue." + queueName));
+ mungedConf.addConfiguration(_config.subset("queues"));
+ _queues.put(queueName, new QueueConfiguration(queueName, mungedConf, this));
}
- List exchangeNames = configuration.getList("exchanges.exchange.name");
-
- for(Object exchangeNameObj : exchangeNames)
+ i = _config.getList("exchanges.exchange.name").iterator();
+ int count = 0;
+ while (i.hasNext())
{
- String exchangeName = String.valueOf(exchangeNameObj);
- configureExchange(virtualHost, exchangeName, configuration);
+ CompositeConfiguration mungedConf = new CompositeConfiguration();
+ mungedConf.addConfiguration(config.subset("exchanges.exchange(" + count++ + ")"));
+ mungedConf.addConfiguration(_config.subset("exchanges"));
+ String exchName = (String) i.next();
+ _exchanges.put(exchName, new ExchangeConfiguration(exchName, mungedConf));
}
-
-
- List queueNames = configuration.getList("queues.queue.name");
-
- for(Object queueNameObj : queueNames)
- {
- String queueName = String.valueOf(queueNameObj);
- configureQueue(virtualHost, queueName, configuration);
- }
-
}
- private void configureExchange(VirtualHost virtualHost, String exchangeNameString, Configuration configuration) throws AMQException
+ /**
+ * All future usages should use the constructor that takes the ServerConfiguration.
+ *
+ * This can be removed after QPID-1696 has been resolved.
+ *
+ * @param name
+ * @param mungedConf
+ * @throws ConfigurationException
+ */
+ @Deprecated
+ public VirtualHostConfiguration(String name, Configuration mungedConf) throws ConfigurationException
{
-
- CompositeConfiguration exchangeConfiguration = new CompositeConfiguration();
-
- exchangeConfiguration.addConfiguration(configuration.subset("exchanges.exchange."+ exchangeNameString));
- exchangeConfiguration.addConfiguration(configuration.subset("exchanges"));
-
- ExchangeRegistry exchangeRegistry = virtualHost.getExchangeRegistry();
- ExchangeFactory exchangeFactory = virtualHost.getExchangeFactory();
-
- AMQShortString exchangeName = new AMQShortString(exchangeNameString);
-
-
- Exchange exchange;
-
-
-
- synchronized (exchangeRegistry)
- {
- exchange = exchangeRegistry.getExchange(exchangeName);
- if(exchange == null)
- {
-
- AMQShortString type = new AMQShortString(exchangeConfiguration.getString("type","direct"));
- boolean durable = exchangeConfiguration.getBoolean("durable",false);
- boolean autodelete = exchangeConfiguration.getBoolean("autodelete",false);
-
- Exchange newExchange = exchangeFactory.createExchange(exchangeName,type,durable,autodelete,0);
- exchangeRegistry.registerExchange(newExchange);
- }
-
- }
+ this(name,mungedConf, ApplicationRegistry.getInstance().getConfiguration());
}
- public static CompositeConfiguration getDefaultQueueConfiguration(VirtualHost host)
+ public String getName()
{
- CompositeConfiguration queueConfiguration = null;
- if (_config == null)
- return null;
-
- Configuration vHostConfiguration = _config.subset(VIRTUALHOST_PROPERTY_BASE + host.getName());
-
- if (vHostConfiguration == null)
- return null;
-
- Configuration defaultQueueConfiguration = vHostConfiguration.subset("queues");
- if (defaultQueueConfiguration != null)
- {
- queueConfiguration = new CompositeConfiguration();
- queueConfiguration.addConfiguration(defaultQueueConfiguration);
- }
-
- return queueConfiguration;
+ return _name;
}
- private void configureQueue(VirtualHost virtualHost, String queueNameString, Configuration configuration) throws AMQException, ConfigurationException
+ public long getHousekeepingExpiredMessageCheckPeriod()
{
- CompositeConfiguration queueConfiguration = new CompositeConfiguration();
-
- queueConfiguration.addConfiguration(configuration.subset("queues.queue."+ queueNameString));
- queueConfiguration.addConfiguration(configuration.subset("queues"));
-
- QueueRegistry queueRegistry = virtualHost.getQueueRegistry();
- RoutingTable routingTable = virtualHost.getRoutingTable();
- ExchangeRegistry exchangeRegistry = virtualHost.getExchangeRegistry();
-
-
- AMQShortString queueName = new AMQShortString(queueNameString);
-
- AMQQueue queue;
-
- synchronized (queueRegistry)
- {
- queue = queueRegistry.getQueue(queueName);
-
- if (queue == null)
- {
- _logger.info("Creating queue '" + queueName + "' on virtual host " + virtualHost.getName());
-
- boolean durable = queueConfiguration.getBoolean("durable" ,false);
- boolean autodelete = queueConfiguration.getBoolean("autodelete", false);
- String owner = queueConfiguration.getString("owner", null);
- FieldTable arguments = null;
- boolean priority = queueConfiguration.getBoolean("priority", false);
- int priorities = queueConfiguration.getInt("priorities", -1);
- if(priority || priorities > 0)
- {
- if(arguments == null)
- {
- arguments = new FieldTable();
- }
- if (priorities < 0)
- {
- priorities = 10;
- }
- arguments.put(new AMQShortString("x-qpid-priorities"), priorities);
- }
-
-
- queue = AMQQueueFactory.createAMQQueueImpl(queueName,
- durable,
- owner == null ? null : new AMQShortString(owner) /* These queues will have no owner */,
- autodelete /* Therefore autodelete makes no sence */,
- virtualHost,
- arguments,
- queueConfiguration);
-
- if (queue.isDurable())
- {
- routingTable.createQueue(queue);
- }
-
- queueRegistry.registerQueue(queue);
- }
- else
- {
- _logger.info("Queue '" + queueNameString + "' already exists on virtual host "+virtualHost.getName()+", not creating.");
- }
-
- String exchangeName = queueConfiguration.getString("exchange", null);
-
- Exchange exchange = exchangeRegistry.getExchange(exchangeName == null ? null : new AMQShortString(exchangeName));
-
- if(exchange == null)
- {
- exchange = virtualHost.getExchangeRegistry().getDefaultExchange();
- }
+ return _config.getLong("housekeeping.expiredMessageCheckPeriod", _serverConfiguration.getHousekeepingCheckPeriod());
+ }
- if (exchange == null)
- {
- throw new ConfigurationException("Attempt to bind queue to unknown exchange:" + exchangeName);
- }
+ public String getAuthenticationDatabase()
+ {
+ return _config.getString("security.authentication.name");
+ }
- synchronized (exchange)
- {
- List routingKeys = queueConfiguration.getList("routingKey");
- if(routingKeys == null || routingKeys.isEmpty())
- {
- routingKeys = Collections.singletonList(queue.getName());
- }
+ public List getCustomExchanges()
+ {
+ return _config.getList("custom-exchanges.class-name");
+ }
- for(Object routingKeyNameObj : routingKeys)
- {
- AMQShortString routingKey = new AMQShortString(String.valueOf(routingKeyNameObj));
-
+ public SecurityConfiguration getSecurityConfiguration()
+ {
+ return new SecurityConfiguration(_config.subset("security"));
+ }
- queue.bind(exchange, routingKey, null);
+ public Configuration getStoreConfiguration()
+ {
+ return _config.subset("store");
+ }
+ public String getRoutingTableClass()
+ {
+ return _config.getString("routingtable.class");
+ }
- _logger.info("Queue '" + queue.getName() + "' bound to exchange:" + exchangeName + " RK:'" + routingKey + "'");
- }
+ public String getTransactionLogClass()
+ {
+ return _config.getString("store.class", MemoryMessageStore.class.getName());
+ }
- if(exchange != virtualHost.getExchangeRegistry().getDefaultExchange())
- {
- queue.bind(virtualHost.getExchangeRegistry().getDefaultExchange(), queue.getName(), null);
- }
- }
+ public List getExchanges()
+ {
+ return _config.getList("exchanges.exchange.name");
+ }
- }
+ public ExchangeConfiguration getExchangeConfiguration(String exchangeName)
+ {
+ return _exchanges.get(exchangeName);
}
+ public String[] getQueueNames()
+ {
+ return _queues.keySet().toArray(new String[_queues.size()]);
+ }
- public void performBindings() throws AMQException, ConfigurationException
+ public QueueConfiguration getQueueConfiguration(String queueName)
{
- List virtualHostNames = _config.getList(VIRTUALHOST_PROPERTY_BASE + "name");
- String defaultVirtualHostName = _config.getString("default");
- if(defaultVirtualHostName != null)
- {
- ApplicationRegistry.getInstance().getVirtualHostRegistry().setDefaultVirtualHostName(defaultVirtualHostName);
- }
- _logger.info("Configuring " + virtualHostNames == null ? 0 : virtualHostNames.size() + " virtual hosts: " + virtualHostNames);
+ return _queues.get(queueName);
+ }
- for(Object nameObject : virtualHostNames)
- {
- String name = String.valueOf(nameObject);
- configureVirtualHost(name, _config.subset(VIRTUALHOST_PROPERTY_BASE + name));
- }
+ public long getMemoryUsageMaximum()
+ {
+ return _config.getLong("queues.maximumMemoryUsage", 0);
+ }
- if (virtualHostNames == null || virtualHostNames.isEmpty())
- {
- throw new ConfigurationException(
- "Virtualhost Configuration document does not contain a valid virtualhost.");
- }
+ public long getMemoryUsageMinimum()
+ {
+ return _config.getLong("queues.minimumMemoryUsage", 0);
}
+ public ServerConfiguration getServerConfiguration()
+ {
+ return _serverConfiguration;
+ }
+ public static final String FLOW_TO_DISK_PATH = "flowToDiskPath";
+ public String getFlowToDiskLocation()
+ {
+ return _config.getString(FLOW_TO_DISK_PATH, getServerConfiguration().getQpidWork());
+ }
}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/management/ConfigurationManagement.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/management/ConfigurationManagement.java
new file mode 100644
index 0000000000..8e4bf01c6a
--- /dev/null
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/management/ConfigurationManagement.java
@@ -0,0 +1,43 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.qpid.server.configuration.management;
+
+import javax.management.MBeanOperationInfo;
+
+import org.apache.commons.configuration.ConfigurationException;
+import org.apache.qpid.server.management.MBeanOperation;
+
+public interface ConfigurationManagement
+{
+
+ String TYPE = "ConfigurationManagement";
+ int VERSION = 1;
+
+ /**
+ * Reload the
+ * @throws ConfigurationException
+ */
+ @MBeanOperation(name="reloadSecurityConfiguration",
+ description = "Force a reload of the security configuration sections",
+ impact = MBeanOperationInfo.ACTION)
+ void reloadSecurityConfiguration() throws ConfigurationException;
+
+}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/AsyncDeliveryConfig.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/management/ConfigurationManagementMBean.java
index 290fedcf7b..ead6053d70 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/AsyncDeliveryConfig.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/management/ConfigurationManagementMBean.java
@@ -18,39 +18,32 @@
* under the License.
*
*/
-package org.apache.qpid.server.queue;
+package org.apache.qpid.server.configuration.management;
-import java.util.concurrent.Executor;
-import java.util.concurrent.Executors;
+import javax.management.NotCompliantMBeanException;
-import org.apache.qpid.configuration.Configured;
+import org.apache.commons.configuration.ConfigurationException;
+import org.apache.qpid.server.management.AMQManagedObject;
import org.apache.qpid.server.registry.ApplicationRegistry;
-public class AsyncDeliveryConfig
+public class ConfigurationManagementMBean extends AMQManagedObject implements ConfigurationManagement
{
- private Executor _executor;
- @Configured(path = "delivery.poolsize", defaultValue = "0")
- public int poolSize;
+ public ConfigurationManagementMBean() throws NotCompliantMBeanException
+ {
+ super(ConfigurationManagement.class, ConfigurationManagement.TYPE, ConfigurationManagement.VERSION);
+ }
- public Executor getExecutor()
+ @Override
+ public String getObjectInstanceName()
{
- if (_executor == null)
- {
- if (poolSize > 0)
- {
- _executor = Executors.newFixedThreadPool(poolSize);
- }
- else
- {
- _executor = Executors.newCachedThreadPool();
- }
- }
- return _executor;
+ return ConfigurationManagement.TYPE;
}
- public static Executor getAsyncDeliveryExecutor()
+ @Override
+ public void reloadSecurityConfiguration() throws ConfigurationException
{
- return ApplicationRegistry.getInstance().getConfiguredObject(AsyncDeliveryConfig.class).getExecutor();
+ ApplicationRegistry.getInstance().getConfiguration().reparseConfigFile();
}
+
}
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 8d24626b73..30af09ce4b 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
@@ -38,13 +38,9 @@ import org.apache.qpid.server.management.Managable;
import org.apache.qpid.server.management.ManagedObject;
import org.apache.qpid.server.management.ManagedObjectRegistry;
import org.apache.qpid.server.queue.QueueRegistry;
-import org.apache.qpid.server.queue.AMQQueue;
import org.apache.qpid.server.registry.ApplicationRegistry;
import org.apache.qpid.server.virtualhost.VirtualHost;
-import java.util.List;
-import java.util.Map;
-
public abstract class AbstractExchange implements Exchange, Managable
{
private AMQShortString _name;
@@ -81,7 +77,7 @@ public abstract class AbstractExchange implements Exchange, Managable
public ExchangeMBean() throws NotCompliantMBeanException
{
- super(ManagedExchange.class, ManagedExchange.TYPE);
+ super(ManagedExchange.class, ManagedExchange.TYPE, ManagedExchange.VERSION);
}
protected void init() throws OpenDataException
@@ -195,7 +191,7 @@ public abstract class AbstractExchange implements Exchange, Managable
public String toString()
{
- return getClass().getName() + "[" + getName() +"]";
+ return getClass().getSimpleName() + "[" + getName() +"]";
}
public ManagedObject getManagedObject()
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/exchange/DefaultExchangeFactory.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/exchange/DefaultExchangeFactory.java
index 9d4c090971..c04b6c559c 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/exchange/DefaultExchangeFactory.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/exchange/DefaultExchangeFactory.java
@@ -25,11 +25,11 @@ import java.util.HashMap;
import java.util.Map;
import org.apache.log4j.Logger;
-import org.apache.commons.configuration.Configuration;
import org.apache.qpid.AMQException;
import org.apache.qpid.AMQUnknownExchangeType;
import org.apache.qpid.framing.AMQShortString;
+import org.apache.qpid.server.configuration.VirtualHostConfiguration;
import org.apache.qpid.server.registry.ApplicationRegistry;
import org.apache.qpid.server.virtualhost.VirtualHost;
@@ -73,7 +73,8 @@ public class DefaultExchangeFactory implements ExchangeFactory
return e;
}
- public void initialise(Configuration hostConfig)
+ @Override
+ public void initialise(VirtualHostConfiguration hostConfig)
{
if (hostConfig == null)
@@ -81,7 +82,7 @@ public class DefaultExchangeFactory implements ExchangeFactory
return;
}
- for(Object className : hostConfig.getList("custom-exchanges.class-name"))
+ for(Object className : hostConfig.getCustomExchanges())
{
try
{
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 e39c005750..e9af92bad8 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
@@ -168,16 +168,14 @@ public class DirectExchange extends AbstractExchange
{
if (_logger.isDebugEnabled())
{
- _logger.debug("Queue (" + queue.getName() + ")" + queue + " is already registered with routing key " + routingKey);
+ _logger.debug("Queue (" + queue + ") is already registered with routing key " + routingKey);
}
}
else
{
if (_logger.isDebugEnabled())
{
- _logger.debug("Binding queue(" + queue.getName() + ") " + queue + " with routing key " + routingKey
- + (args == null ? "" : " and arguments " + args.toString())
- + " to exchange " + this);
+ _logger.debug("Binding queue:" + queue + " with routing key '" + routingKey +"' to exchange:" + this);
}
}
}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/exchange/ExchangeFactory.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/exchange/ExchangeFactory.java
index 0bcfec7181..2f76d41228 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/exchange/ExchangeFactory.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/exchange/ExchangeFactory.java
@@ -26,6 +26,7 @@ import org.apache.commons.configuration.Configuration;
import org.apache.qpid.AMQException;
import org.apache.qpid.framing.AMQShortString;
+import org.apache.qpid.server.configuration.VirtualHostConfiguration;
public interface ExchangeFactory
@@ -34,7 +35,7 @@ public interface ExchangeFactory
int ticket)
throws AMQException;
- void initialise(Configuration hostConfig);
+ void initialise(VirtualHostConfiguration hostConfig);
Collection<ExchangeType<? extends Exchange>> getRegisteredTypes();
}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/exchange/ManagedExchange.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/exchange/ManagedExchange.java
index 5d6d68b3c8..317ff385ab 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/exchange/ManagedExchange.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/exchange/ManagedExchange.java
@@ -40,6 +40,7 @@ import org.apache.qpid.server.queue.ManagedQueue;
public interface ManagedExchange
{
static final String TYPE = "Exchange";
+ static final int VERSION = 1;
/**
* Returns the name of the managed exchange.
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/flow/BytesOnlyCreditManager.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/flow/BytesOnlyCreditManager.java
index 0743e4bb8d..0bb428cd8f 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/flow/BytesOnlyCreditManager.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/flow/BytesOnlyCreditManager.java
@@ -1,6 +1,6 @@
package org.apache.qpid.server.flow;
-import org.apache.qpid.server.queue.AMQMessage;
+import org.apache.qpid.server.queue.QueueEntry;
import java.util.concurrent.atomic.AtomicLong;
@@ -49,9 +49,9 @@ public class BytesOnlyCreditManager extends AbstractFlowCreditManager
return _bytesCredit.get() > 0L;
}
- public boolean useCreditForMessage(AMQMessage msg)
+ public boolean useCreditForMessage(QueueEntry queueEntry)
{
- final long msgSize = msg.getSize();
+ final long msgSize = queueEntry.getSize();
if(hasCredit())
{
if(_bytesCredit.addAndGet(-msgSize) >= 0)
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/flow/FlowCreditManager.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/flow/FlowCreditManager.java
index a249a6e63a..297e5a4826 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/flow/FlowCreditManager.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/flow/FlowCreditManager.java
@@ -1,6 +1,7 @@
package org.apache.qpid.server.flow;
import org.apache.qpid.server.queue.AMQMessage;
+import org.apache.qpid.server.queue.QueueEntry;
/*
*
@@ -40,5 +41,5 @@ public interface FlowCreditManager
public boolean hasCredit();
- public boolean useCreditForMessage(AMQMessage msg);
+ public boolean useCreditForMessage(QueueEntry queueEntry);
}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/flow/LimitlessCreditManager.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/flow/LimitlessCreditManager.java
index d63431c3eb..437b7b0469 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/flow/LimitlessCreditManager.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/flow/LimitlessCreditManager.java
@@ -1,6 +1,6 @@
package org.apache.qpid.server.flow;
-import org.apache.qpid.server.queue.AMQMessage;
+import org.apache.qpid.server.queue.QueueEntry;
/*
*
@@ -37,7 +37,7 @@ public class LimitlessCreditManager extends AbstractFlowCreditManager implements
return true;
}
- public boolean useCreditForMessage(AMQMessage msg)
+ public boolean useCreditForMessage(QueueEntry queueEntry)
{
return true;
}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/flow/MessageAndBytesCreditManager.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/flow/MessageAndBytesCreditManager.java
index 5f0acec03f..15ecb5f292 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/flow/MessageAndBytesCreditManager.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/flow/MessageAndBytesCreditManager.java
@@ -1,6 +1,6 @@
package org.apache.qpid.server.flow;
-import org.apache.qpid.server.queue.AMQMessage;
+import org.apache.qpid.server.queue.QueueEntry;
/*
*
@@ -52,7 +52,7 @@ public class MessageAndBytesCreditManager extends AbstractFlowCreditManager impl
return (_messageCredit > 0L) && ( _bytesCredit > 0L );
}
- public synchronized boolean useCreditForMessage(AMQMessage msg)
+ public synchronized boolean useCreditForMessage(QueueEntry queueEntry)
{
if(_messageCredit == 0L)
{
@@ -61,7 +61,7 @@ public class MessageAndBytesCreditManager extends AbstractFlowCreditManager impl
}
else
{
- final long msgSize = msg.getSize();
+ final long msgSize = queueEntry.getSize();
if(msgSize > _bytesCredit)
{
setSuspended(true);
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/flow/MessageOnlyCreditManager.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/flow/MessageOnlyCreditManager.java
index c1b3a09006..3e28d779b1 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/flow/MessageOnlyCreditManager.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/flow/MessageOnlyCreditManager.java
@@ -1,6 +1,6 @@
package org.apache.qpid.server.flow;
-import org.apache.qpid.server.queue.AMQMessage;
+import org.apache.qpid.server.queue.QueueEntry;
import java.util.concurrent.atomic.AtomicLong;
@@ -50,7 +50,7 @@ public class MessageOnlyCreditManager extends AbstractFlowCreditManager implemen
return _messageCredit.get() > 0L;
}
- public boolean useCreditForMessage(AMQMessage msg)
+ public boolean useCreditForMessage(QueueEntry queueEntry)
{
if(hasCredit())
{
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/flow/Pre0_10CreditManager.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/flow/Pre0_10CreditManager.java
index be0300f2c1..5cdd3a0328 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/flow/Pre0_10CreditManager.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/flow/Pre0_10CreditManager.java
@@ -20,7 +20,7 @@
*/
package org.apache.qpid.server.flow;
-import org.apache.qpid.server.queue.AMQMessage;
+import org.apache.qpid.server.queue.QueueEntry;
public class Pre0_10CreditManager extends AbstractFlowCreditManager implements FlowCreditManager
{
@@ -123,7 +123,7 @@ public class Pre0_10CreditManager extends AbstractFlowCreditManager implements F
&& (_messageCreditLimit == 0L || _messageCredit > 0);
}
- public synchronized boolean useCreditForMessage(final AMQMessage msg)
+ public synchronized boolean useCreditForMessage(final QueueEntry queueEntry)
{
if(_messageCreditLimit != 0L)
{
@@ -137,10 +137,10 @@ public class Pre0_10CreditManager extends AbstractFlowCreditManager implements F
}
else
{
- if((_bytesCredit >= msg.getSize()) || (_bytesCredit == _bytesCreditLimit))
+ if((_bytesCredit >= queueEntry.getSize()) || (_bytesCredit == _bytesCreditLimit))
{
_messageCredit--;
- _bytesCredit -= msg.getSize();
+ _bytesCredit -= queueEntry.getSize();
return true;
}
@@ -166,9 +166,9 @@ public class Pre0_10CreditManager extends AbstractFlowCreditManager implements F
}
else
{
- if((_bytesCredit >= msg.getSize()) || (_bytesCredit == _bytesCreditLimit))
+ if((_bytesCredit >= queueEntry.getSize()) || (_bytesCredit == _bytesCreditLimit))
{
- _bytesCredit -= msg.getSize();
+ _bytesCredit -= queueEntry.getSize();
return true;
}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/handler/BasicGetMethodHandler.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/handler/BasicGetMethodHandler.java
index 0f492a21bb..a626114792 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/handler/BasicGetMethodHandler.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/handler/BasicGetMethodHandler.java
@@ -129,7 +129,7 @@ public class BasicGetMethodHandler implements StateAwareMethodListener<BasicGetB
public void deliverToClient(final Subscription sub, final QueueEntry entry, final long deliveryTag)
throws AMQException
{
- singleMessageCredit.useCreditForMessage(entry.getMessage());
+ singleMessageCredit.useCreditForMessage(entry);
session.getProtocolOutputConverter().writeGetOk(entry, channel.getChannelId(),
deliveryTag, queue.getMessageCount());
@@ -181,9 +181,9 @@ public class BasicGetMethodHandler implements StateAwareMethodListener<BasicGetB
super(channel, protocolSession, consumerTag, filters, noLocal, creditManager, deliveryMethod, recordMethod);
}
- public boolean wouldSuspend(QueueEntry msg)
+ public boolean wouldSuspend(QueueEntry queueEntry)
{
- return !getCreditManager().useCreditForMessage(msg.getMessage());
+ return !getCreditManager().useCreditForMessage(queueEntry);
}
}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/handler/BasicRejectMethodHandler.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/handler/BasicRejectMethodHandler.java
index f3cab10ed7..8b04315d33 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/handler/BasicRejectMethodHandler.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/handler/BasicRejectMethodHandler.java
@@ -65,38 +65,38 @@ public class BasicRejectMethodHandler implements StateAwareMethodListener<BasicR
long deliveryTag = body.getDeliveryTag();
- QueueEntry message = channel.getUnacknowledgedMessageMap().get(deliveryTag);
+ QueueEntry queueEntry = channel.getUnacknowledgedMessageMap().get(deliveryTag);
- if (message == null)
+ if (queueEntry == null)
{
_logger.warn("Dropping reject request as message is null for tag:" + deliveryTag);
// throw evt.getMethod().getChannelException(AMQConstant.NOT_FOUND, "Delivery Tag(" + deliveryTag + ")not known");
}
else
{
- if (message.isQueueDeleted())
+ if (queueEntry.isQueueDeleted())
{
_logger.warn("Message's Queue as already been purged, unable to Reject. " +
"Dropping message should use Dead Letter Queue");
- message = channel.getUnacknowledgedMessageMap().remove(deliveryTag);
- if(message != null)
+ queueEntry = channel.getUnacknowledgedMessageMap().remove(deliveryTag);
+ if(queueEntry != null)
{
- message.discard(channel.getStoreContext());
+ queueEntry.dequeueAndDelete(channel.getStoreContext());
}
//sendtoDeadLetterQueue(msg)
return;
}
- if (!message.getMessage().isReferenced())
+ if (queueEntry.isDeleted())
{
- _logger.warn("Message as already been purged, unable to Reject.");
+ _logger.warn("QueueEntry as already been deleted, unable to Reject.");
return;
}
if (_logger.isDebugEnabled())
{
- _logger.debug("Rejecting: DT:" + deliveryTag + "-" + message.getMessage().debugIdentity() +
+ _logger.debug("Rejecting: DT:" + deliveryTag + "-" + queueEntry.debugIdentity() +
": Requeue:" + body.getRequeue() +
//": Resend:" + evt.getMethod().resend +
" on channel:" + channel.debugIdentity());
@@ -105,7 +105,7 @@ public class BasicRejectMethodHandler implements StateAwareMethodListener<BasicR
// If we haven't requested message to be resent to this consumer then reject it from ever getting it.
//if (!evt.getMethod().resend)
{
- message.reject();
+ queueEntry.reject();
}
if (body.getRequeue())
@@ -115,7 +115,7 @@ public class BasicRejectMethodHandler implements StateAwareMethodListener<BasicR
else
{
_logger.warn("Dropping message as requeue not required and there is no dead letter queue");
- message = channel.getUnacknowledgedMessageMap().remove(deliveryTag);
+ queueEntry = channel.getUnacknowledgedMessageMap().remove(deliveryTag);
//sendtoDeadLetterQueue(AMQMessage message)
// message.queue = channel.getDefaultDeadLetterQueue();
// channel.requeue(deliveryTag);
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/handler/ConnectionSecureOkMethodHandler.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/handler/ConnectionSecureOkMethodHandler.java
index 621003be90..a2a6faf21b 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/handler/ConnectionSecureOkMethodHandler.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/handler/ConnectionSecureOkMethodHandler.java
@@ -25,14 +25,16 @@ import javax.security.sasl.SaslServer;
import org.apache.log4j.Logger;
import org.apache.qpid.AMQException;
-import org.apache.qpid.framing.*;
+import org.apache.qpid.framing.ConnectionCloseBody;
+import org.apache.qpid.framing.ConnectionSecureBody;
+import org.apache.qpid.framing.ConnectionSecureOkBody;
+import org.apache.qpid.framing.ConnectionTuneBody;
+import org.apache.qpid.framing.MethodRegistry;
import org.apache.qpid.protocol.AMQConstant;
-import org.apache.qpid.protocol.AMQMethodEvent;
import org.apache.qpid.server.protocol.AMQProtocolSession;
-import org.apache.qpid.server.protocol.HeartbeatConfig;
import org.apache.qpid.server.registry.ApplicationRegistry;
-import org.apache.qpid.server.security.auth.manager.AuthenticationManager;
import org.apache.qpid.server.security.auth.AuthenticationResult;
+import org.apache.qpid.server.security.auth.manager.AuthenticationManager;
import org.apache.qpid.server.security.auth.sasl.UsernamePrincipal;
import org.apache.qpid.server.state.AMQState;
import org.apache.qpid.server.state.AMQStateManager;
@@ -92,7 +94,7 @@ public class ConnectionSecureOkMethodHandler implements StateAwareMethodListener
ConnectionTuneBody tuneBody =
methodRegistry.createConnectionTuneBody(0xFFFF,
ConnectionStartOkMethodHandler.getConfiguredFrameSize(),
- HeartbeatConfig.getInstance().getDelay());
+ ApplicationRegistry.getInstance().getConfiguration().getHeartBeatDelay());
session.writeFrame(tuneBody.generateFrame(0));
session.setAuthorizedID(new UsernamePrincipal(ss.getAuthorizationID()));
disposeSaslServer(session);
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/handler/ConnectionStartOkMethodHandler.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/handler/ConnectionStartOkMethodHandler.java
index f53e56601b..6698ae888a 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/handler/ConnectionStartOkMethodHandler.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/handler/ConnectionStartOkMethodHandler.java
@@ -23,18 +23,19 @@ package org.apache.qpid.server.handler;
import javax.security.sasl.SaslException;
import javax.security.sasl.SaslServer;
-import org.apache.commons.configuration.Configuration;
import org.apache.log4j.Logger;
import org.apache.qpid.AMQException;
-import org.apache.qpid.framing.*;
-import org.apache.qpid.protocol.AMQMethodEvent;
+import org.apache.qpid.framing.ConnectionCloseBody;
+import org.apache.qpid.framing.ConnectionSecureBody;
+import org.apache.qpid.framing.ConnectionStartOkBody;
+import org.apache.qpid.framing.ConnectionTuneBody;
+import org.apache.qpid.framing.MethodRegistry;
import org.apache.qpid.protocol.AMQConstant;
+import org.apache.qpid.server.configuration.ServerConfiguration;
import org.apache.qpid.server.protocol.AMQProtocolSession;
-import org.apache.qpid.server.protocol.HeartbeatConfig;
-import org.apache.qpid.server.protocol.AMQMinaProtocolSession;
import org.apache.qpid.server.registry.ApplicationRegistry;
-import org.apache.qpid.server.security.auth.manager.AuthenticationManager;
import org.apache.qpid.server.security.auth.AuthenticationResult;
+import org.apache.qpid.server.security.auth.manager.AuthenticationManager;
import org.apache.qpid.server.security.auth.sasl.UsernamePrincipal;
import org.apache.qpid.server.state.AMQState;
import org.apache.qpid.server.state.AMQStateManager;
@@ -47,8 +48,6 @@ public class ConnectionStartOkMethodHandler implements StateAwareMethodListener<
private static ConnectionStartOkMethodHandler _instance = new ConnectionStartOkMethodHandler();
- private static final int DEFAULT_FRAME_SIZE = 65536;
-
public static ConnectionStartOkMethodHandler getInstance()
{
return _instance;
@@ -117,7 +116,7 @@ public class ConnectionStartOkMethodHandler implements StateAwareMethodListener<
ConnectionTuneBody tuneBody = methodRegistry.createConnectionTuneBody(0xFFFF,
getConfiguredFrameSize(),
- HeartbeatConfig.getInstance().getDelay());
+ ApplicationRegistry.getInstance().getConfiguration().getHeartBeatDelay());
session.writeFrame(tuneBody.generateFrame(0));
break;
case CONTINUE:
@@ -153,8 +152,8 @@ public class ConnectionStartOkMethodHandler implements StateAwareMethodListener<
static int getConfiguredFrameSize()
{
- final Configuration config = ApplicationRegistry.getInstance().getConfiguration();
- final int framesize = config.getInt("advanced.framesize", DEFAULT_FRAME_SIZE);
+ final ServerConfiguration config = ApplicationRegistry.getInstance().getConfiguration();
+ final int framesize = config.getFrameSize();
_logger.info("Framesize set to " + framesize);
return framesize;
}
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 b1e02aef7a..7f500cfb8a 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
@@ -20,27 +20,28 @@
*/
package org.apache.qpid.server.handler;
-import java.util.concurrent.atomic.AtomicInteger;
import java.util.UUID;
+import java.util.concurrent.atomic.AtomicInteger;
import org.apache.log4j.Logger;
import org.apache.qpid.AMQException;
-import org.apache.qpid.configuration.Configured;
-
-import org.apache.qpid.framing.*;
+import org.apache.qpid.framing.AMQShortString;
+import org.apache.qpid.framing.MethodRegistry;
+import org.apache.qpid.framing.QueueDeclareBody;
+import org.apache.qpid.framing.QueueDeclareOkBody;
import org.apache.qpid.protocol.AMQConstant;
-import org.apache.qpid.server.configuration.Configurator;
+import org.apache.qpid.server.AMQChannel;
import org.apache.qpid.server.exchange.Exchange;
import org.apache.qpid.server.exchange.ExchangeRegistry;
import org.apache.qpid.server.protocol.AMQProtocolSession;
-import org.apache.qpid.server.queue.QueueRegistry;
import org.apache.qpid.server.queue.AMQQueue;
import org.apache.qpid.server.queue.AMQQueueFactory;
+import org.apache.qpid.server.queue.QueueRegistry;
+import org.apache.qpid.server.registry.ApplicationRegistry;
+import org.apache.qpid.server.routing.RoutingTable;
import org.apache.qpid.server.state.AMQStateManager;
import org.apache.qpid.server.state.StateAwareMethodListener;
import org.apache.qpid.server.virtualhost.VirtualHost;
-import org.apache.qpid.server.AMQChannel;
-import org.apache.qpid.server.routing.RoutingTable;
public class QueueDeclareHandler implements StateAwareMethodListener<QueueDeclareBody>
{
@@ -53,17 +54,10 @@ public class QueueDeclareHandler implements StateAwareMethodListener<QueueDeclar
return _instance;
}
- @Configured(path = "queue.auto_register", defaultValue = "true")
- public boolean autoRegister;
+ public boolean autoRegister = ApplicationRegistry.getInstance().getConfiguration().getQueueAutoRegister();
private final AtomicInteger _counter = new AtomicInteger();
-
- protected QueueDeclareHandler()
- {
- Configurator.configure(this);
- }
-
public void methodReceived(AMQStateManager stateManager, QueueDeclareBody body, int channelId) throws AMQException
{
AMQProtocolSession session = stateManager.getProtocolSession();
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/logging/management/LoggingManagement.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/logging/management/LoggingManagement.java
new file mode 100644
index 0000000000..79d60a6df0
--- /dev/null
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/logging/management/LoggingManagement.java
@@ -0,0 +1,129 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ *
+ */
+package org.apache.qpid.server.logging.management;
+
+import java.io.IOException;
+
+import org.apache.qpid.server.management.MBeanAttribute;
+import org.apache.qpid.server.management.MBeanOperation;
+import org.apache.qpid.server.management.MBeanOperationParameter;
+
+import javax.management.MBeanOperationInfo;
+import javax.management.openmbean.TabularData;
+
+public interface LoggingManagement
+{
+ String TYPE = "LoggingManagement";
+ int VERSION = 1;
+
+ //TabularType and contained CompositeType key/description information
+ String[] COMPOSITE_ITEM_NAMES = {"LoggerName", "Level"};
+ String[] COMPOSITE_ITEM_DESCRIPTIONS = {"Name of the logger", "Level of the logger"};
+ String[] TABULAR_UNIQUE_INDEX = {COMPOSITE_ITEM_NAMES[0]};
+
+ /**
+ * Attribute to represent the log4j xml configuration file's LogWatch interval.
+ * @return The logwatch interval in seconds.
+ */
+ @MBeanAttribute(name="Log4jLogWatchInterval",
+ description = "The log4j xml configuration file LogWatch interval (in seconds). 0 indicates not being checked.")
+ Integer getLog4jLogWatchInterval();
+
+
+ //****** log4j runtime operations ****** //
+
+ /**
+ * Sets the level of an active Log4J logger
+ * @param logger The name of the logger
+ * @param level The level to set the logger to
+ * @return True if successful, false if unsuccessful (eg if an invalid level is specified)
+ */
+ @MBeanOperation(name = "setRuntimeLoggerLevel", description = "Set the runtime logging level for an active log4j logger.",
+ impact = MBeanOperationInfo.ACTION)
+ boolean setRuntimeLoggerLevel(@MBeanOperationParameter(name = "logger", description = "Logger name")String logger,
+ @MBeanOperationParameter(name = "level", description = "Logger level")String level);
+
+ /**
+ * Retrieves a TabularData set of the active log4j loggers and their levels
+ * @return TabularData set of CompositeData rows with logger name and level, or null if there is a problem with the TabularData type
+ */
+ @MBeanOperation(name = "viewEffectiveRuntimeLoggerLevels", description = "View the effective runtime logging level " +
+ "for active log4j logger's.", impact = MBeanOperationInfo.INFO)
+ TabularData viewEffectiveRuntimeLoggerLevels();
+
+ /**
+ * Sets the level of the active Log4J RootLogger
+ * @param level The level to set the RootLogger to
+ * @return True if successful, false if unsuccessful (eg if an invalid level is specified)
+ */
+ @MBeanOperation(name = "setRuntimeRootLoggerLevel", description = "Set the runtime logging level for the active log4j Root Logger.",
+ impact = MBeanOperationInfo.ACTION)
+ boolean setRuntimeRootLoggerLevel(@MBeanOperationParameter(name = "level", description = "Logger level")String level);
+
+ /**
+ * Attribute to represent the level of the active Log4J RootLogger
+ * @return The level of the RootLogger.
+ */
+ @MBeanAttribute(name = "getRuntimeRootLoggerLevel", description = "Get the runtime logging level for the active log4j Root Logger.")
+ String getRuntimeRootLoggerLevel();
+
+
+ //****** log4j XML configuration file operations ****** //
+
+ /**
+ * Updates the level of an existing Log4J logger within the xml configuration file
+ * @param logger The name of the logger
+ * @param level The level to set the logger to
+ * @return True if successful, false if unsuccessful (eg if an invalid logger or level is specified)
+ * @throws IOException if there is an error parsing the configuration file.
+ */
+ @MBeanOperation(name = "setConfigFileLoggerLevel", description = "Set the logging level for an existing logger " +
+ "in the log4j xml configuration file", impact = MBeanOperationInfo.ACTION)
+ boolean setConfigFileLoggerLevel(@MBeanOperationParameter(name = "logger", description = "logger name")String logger,
+ @MBeanOperationParameter(name = "level", description = "Logger level")String level) throws IOException;
+
+ /**
+ * Retrieves a TabularData set of the existing Log4J loggers within the xml configuration file
+ * @return TabularData set of CompositeData rows with logger name and level, or null if there is a problem with the TabularData type
+ * @throws IOException if there is an error parsing the configuration file.
+ */
+ @MBeanOperation(name = "viewConfigFileLoggerLevels", description = "Get the logging level defined for the logger's " +
+ "in the log4j xml configuration file.", impact = MBeanOperationInfo.INFO)
+ TabularData viewConfigFileLoggerLevels() throws IOException;
+
+ /**
+ * Updates the level of the Log4J RootLogger within the xml configuration file if it is present
+ * @param level The level to set the logger to
+ * @return True if successful, false if not (eg an invalid level is specified, or root logger level isnt already defined)
+ * @throws IOException if there is an error parsing the configuration file.
+ */
+ @MBeanOperation(name = "setConfigFileRootLoggerLevel", description = "Set the logging level for the Root Logger " +
+ "in the log4j xml configuration file.", impact = MBeanOperationInfo.ACTION)
+ boolean setConfigFileRootLoggerLevel(@MBeanOperationParameter(name = "level", description = "Logger level")String level) throws IOException;
+
+ /**
+ * Attribute to represent the level of the Log4J RootLogger within the xml configuration file
+ * @return The level of the RootLogger, or null if it is not present
+ */
+ @MBeanAttribute(name = "getConfigFileRootLoggerLevel", description = "Get the logging level for the Root Logger " +
+ "in the log4j xml configuration file.")
+ String getConfigFileRootLoggerLevel() throws IOException;
+}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/logging/management/LoggingManagementMBean.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/logging/management/LoggingManagementMBean.java
new file mode 100644
index 0000000000..f84cbbd786
--- /dev/null
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/logging/management/LoggingManagementMBean.java
@@ -0,0 +1,667 @@
+/*
+ * 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.logging.management;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Enumeration;
+import java.util.List;
+
+import org.apache.qpid.server.management.MBeanDescription;
+import org.apache.qpid.server.management.AMQManagedObject;
+
+import org.apache.log4j.Level;
+import org.apache.log4j.LogManager;
+import org.apache.log4j.Logger;
+import org.apache.log4j.xml.Log4jEntityResolver;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.NodeList;
+import org.xml.sax.ErrorHandler;
+import org.xml.sax.SAXException;
+import org.xml.sax.SAXParseException;
+
+import javax.management.JMException;
+import javax.management.openmbean.CompositeData;
+import javax.management.openmbean.CompositeDataSupport;
+import javax.management.openmbean.CompositeType;
+import javax.management.openmbean.OpenDataException;
+import javax.management.openmbean.OpenType;
+import javax.management.openmbean.SimpleType;
+import javax.management.openmbean.TabularData;
+import javax.management.openmbean.TabularDataSupport;
+import javax.management.openmbean.TabularType;
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.transform.OutputKeys;
+import javax.xml.transform.Transformer;
+import javax.xml.transform.TransformerException;
+import javax.xml.transform.TransformerFactory;
+import javax.xml.transform.dom.DOMSource;
+import javax.xml.transform.stream.StreamResult;
+
+
+/** MBean class for BrokerLoggingManagerMBean. It implements all the management features exposed for managing logging. */
+@MBeanDescription("Logging Management Interface")
+public class LoggingManagementMBean extends AMQManagedObject implements LoggingManagement
+{
+
+ private static final Logger _logger = Logger.getLogger(LoggingManagementMBean.class);
+ private String _log4jConfigFileName;
+ private int _log4jLogWatchInterval;
+
+ static TabularType _loggerLevelTabularType;
+ static CompositeType _loggerLevelCompositeType;
+
+ static
+ {
+ try
+ {
+ OpenType[] loggerLevelItemTypes = new OpenType[]{SimpleType.STRING, SimpleType.STRING};
+
+ _loggerLevelCompositeType = new CompositeType("LoggerLevelList", "Logger Level Data",
+ COMPOSITE_ITEM_NAMES, COMPOSITE_ITEM_DESCRIPTIONS, loggerLevelItemTypes);
+
+ _loggerLevelTabularType = new TabularType("LoggerLevel", "List of loggers with levels",
+ _loggerLevelCompositeType, TABULAR_UNIQUE_INDEX);
+ }
+ catch (OpenDataException e)
+ {
+ _logger.error("Tabular data setup for viewing logger levels was incorrect.");
+ _loggerLevelTabularType = null;
+ }
+ }
+
+ public LoggingManagementMBean(String log4jConfigFileName, int log4jLogWatchInterval) throws JMException
+ {
+ super(LoggingManagement.class, LoggingManagement.TYPE, LoggingManagement.VERSION);
+ _log4jConfigFileName = log4jConfigFileName;
+ _log4jLogWatchInterval = log4jLogWatchInterval;
+ }
+
+ public String getObjectInstanceName()
+ {
+ return LoggingManagement.TYPE;
+ }
+
+ public Integer getLog4jLogWatchInterval()
+ {
+ return _log4jLogWatchInterval;
+ }
+
+ @SuppressWarnings("unchecked")
+ public synchronized boolean setRuntimeLoggerLevel(String logger, String level)
+ {
+ //check specified level is valid
+ Level newLevel;
+ try
+ {
+ newLevel = getLevel(level);
+ }
+ catch (Exception e)
+ {
+ return false;
+ }
+
+ //check specified logger exists
+ Enumeration loggers = LogManager.getCurrentLoggers();
+ Boolean loggerExists = false;
+
+ while(loggers.hasMoreElements())
+ {
+ Logger log = (Logger) loggers.nextElement();
+ if (log.getName().equals(logger))
+ {
+ loggerExists = true;
+ break;
+ }
+ }
+
+ if(!loggerExists)
+ {
+ return false;
+ }
+
+ //set the logger to the new level
+ _logger.info("Setting level to " + level + " for logger: " + logger);
+
+ Logger log = Logger.getLogger(logger);
+ log.setLevel(newLevel);
+
+ return true;
+ }
+
+ @SuppressWarnings("unchecked")
+ public synchronized TabularData viewEffectiveRuntimeLoggerLevels()
+ {
+ if (_loggerLevelTabularType == null)
+ {
+ _logger.warn("TabluarData type not set up correctly");
+ return null;
+ }
+
+ _logger.info("Getting levels for currently active log4j loggers");
+
+ Enumeration loggers = LogManager.getCurrentLoggers();
+
+ TabularData loggerLevelList = new TabularDataSupport(_loggerLevelTabularType);
+
+ Logger logger;
+ String loggerName;
+ String level;
+
+ try
+ {
+ while(loggers.hasMoreElements()){
+ logger = (Logger) loggers.nextElement();
+
+ loggerName = logger.getName();
+ level = logger.getEffectiveLevel().toString();
+
+ Object[] itemData = {loggerName, level};
+ CompositeData loggerData = new CompositeDataSupport(_loggerLevelCompositeType, COMPOSITE_ITEM_NAMES, itemData);
+ loggerLevelList.put(loggerData);
+ }
+ }
+ catch (OpenDataException e)
+ {
+ _logger.warn("Unable to create logger level list due to :" + e);
+ return null;
+ }
+
+ return loggerLevelList;
+
+ }
+
+ public synchronized String getRuntimeRootLoggerLevel()
+ {
+ Logger rootLogger = Logger.getRootLogger();
+
+ return rootLogger.getLevel().toString();
+ }
+
+ public synchronized boolean setRuntimeRootLoggerLevel(String level)
+ {
+ Level newLevel;
+ try
+ {
+ newLevel = getLevel(level);
+ }
+ catch (Exception e)
+ {
+ return false;
+ }
+
+ _logger.info("Setting RootLogger level to " + level);
+
+ Logger log = Logger.getRootLogger();
+ log.setLevel(newLevel);
+
+ return true;
+ }
+
+ //method to convert from a string to a log4j Level, throws exception if the given value is invalid
+ private Level getLevel(String level) throws Exception
+ {
+ Level newLevel = Level.toLevel(level);
+
+ //above Level.toLevel call returns a DEBUG Level if the request fails. Check the result.
+ if (newLevel.equals(Level.DEBUG) && !(level.equalsIgnoreCase("debug")))
+ {
+ //received DEBUG but we did not ask for it, the Level request failed.
+ throw new Exception("Invalid level name");
+ }
+
+ return newLevel;
+ }
+
+ //handler to catch errors signalled by the JAXP parser and throw an appropriate exception
+ private class SaxErrorHandler implements ErrorHandler
+ {
+
+ public void error(SAXParseException e) throws SAXException
+ {
+ throw new SAXException("Error parsing XML file: " + e.getMessage());
+ }
+
+ public void fatalError(SAXParseException e) throws SAXException
+ {
+ throw new SAXException("Fatal error parsing XML file: " + e.getMessage());
+ }
+
+ public void warning(SAXParseException e) throws SAXException
+ {
+ throw new SAXException("Warning parsing XML file: " + e.getMessage());
+ }
+ }
+
+ //method to parse the XML configuration file, validating it in the process, and returning a DOM Document of the content.
+ private synchronized Document parseConfigFile(String fileName) throws IOException
+ {
+ //check file was specified, exists, and is readable
+ if(fileName == null)
+ {
+ _logger.warn("No log4j XML configuration file has been set");
+ throw new IOException("No log4j XML configuration file has been set");
+ }
+
+ File configFile = new File(fileName);
+
+ if (!configFile.exists())
+ {
+ _logger.warn("Specified log4j XML configuration file does not exist: " + fileName);
+ throw new IOException("Specified log4j XML configuration file does not exist");
+ }
+ else if (!configFile.canRead())
+ {
+ _logger.warn("Specified log4j XML configuration file is not readable: " + fileName);
+ throw new IOException("Specified log4j XML configuration file is not readable");
+ }
+
+ //parse it
+ DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();
+ DocumentBuilder docBuilder;
+ Document doc;
+
+ ErrorHandler errHandler = new SaxErrorHandler();
+ try
+ {
+ docFactory.setValidating(true);
+ docBuilder = docFactory.newDocumentBuilder();
+ docBuilder.setErrorHandler(errHandler);
+ docBuilder.setEntityResolver(new Log4jEntityResolver());
+ doc = docBuilder.parse(fileName);
+ }
+ catch (ParserConfigurationException e)
+ {
+ _logger.warn("Unable to parse the log4j XML file due to possible configuration error: " + e);
+ //recommended that MBeans should use java.* and javax.* exceptions only
+ throw new IOException("Unable to parse the log4j XML file due to possible configuration error: " + e.getMessage());
+ }
+ catch (SAXException e)
+ {
+ _logger.warn("The specified log4j XML file is invalid: " + e);
+ //recommended that MBeans should use standard java.* and javax.* exceptions only
+ throw new IOException("The specified log4j XML file is invalid: " + e.getMessage());
+ }
+ catch (IOException e)
+ {
+ _logger.warn("Unable to parse the specified log4j XML file" + e);
+ throw new IOException("Unable to parse the specified log4j XML file", e);
+ }
+
+ return doc;
+ }
+
+
+ private synchronized boolean writeUpdatedConfigFile(String log4jConfigFileName, Document doc) throws IOException
+ {
+ File log4jConfigFile = new File(log4jConfigFileName);
+
+ if (!log4jConfigFile.canWrite())
+ {
+ _logger.warn("Specified log4j XML configuration file is not writable: " + log4jConfigFile);
+ throw new IOException("Specified log4j XML configuration file is not writable");
+ }
+
+ Transformer transformer = null;
+ try
+ {
+ transformer = TransformerFactory.newInstance().newTransformer();
+ }
+ catch (Exception e)
+ {
+ _logger.warn("Could not create an XML transformer: " +e);
+ return false;
+ }
+
+ transformer.setOutputProperty(OutputKeys.INDENT, "yes");
+ transformer.setOutputProperty(OutputKeys.DOCTYPE_SYSTEM, "log4j.dtd");
+ DOMSource source = new DOMSource(doc);
+
+ File tmp;
+ try
+ {
+ tmp = File.createTempFile("LogManMBeanTemp", ".tmp");
+ tmp.deleteOnExit();
+ StreamResult result = new StreamResult(tmp);
+ transformer.transform(source, result);
+ }
+ catch (TransformerException e)
+ {
+ _logger.warn("Could not transform the XML into new file: " +e);
+ return false;
+ }
+ catch (IOException e)
+ {
+ _logger.warn("Could not create the new file: " +e);
+ return false;
+ }
+
+ // Swap temp file in to replace existing configuration file.
+ File old = new File(log4jConfigFile.getAbsoluteFile() + ".old");
+ if (old.exists())
+ {
+ old.delete();
+ }
+ log4jConfigFile.renameTo(old);
+ return tmp.renameTo(log4jConfigFile);
+ }
+
+
+ /* The log4j XML configuration file DTD defines three possible element
+ * combinations for specifying optional logger+level settings.
+ * Must account for the following:
+ *
+ * <category name="x"> <priority value="y"/> </category> OR
+ * <category name="x"> <level value="y"/> </category> OR
+ * <logger name="x"> <level value="y"/> </logger>
+ *
+ * Noting also that the level/priority child element is optional too,
+ * and not the only possible child element.
+ */
+
+
+ public synchronized TabularData viewConfigFileLoggerLevels() throws IOException
+ {
+ if (_loggerLevelTabularType == null)
+ {
+ _logger.warn("TabluarData type not set up correctly");
+ return null;
+ }
+
+ _logger.info("Getting logger levels from log4j configuration file");
+
+ Document doc = parseConfigFile(_log4jConfigFileName);
+
+ TabularData loggerLevelList = new TabularDataSupport(_loggerLevelTabularType);
+
+ //retrieve the 'category' element nodes
+ NodeList categoryElements = doc.getElementsByTagName("category");
+
+ String categoryName;
+ String priority = null;
+
+ for (int i = 0; i < categoryElements.getLength(); i++)
+ {
+ Element categoryElement = (Element) categoryElements.item(i);
+ categoryName = categoryElement.getAttribute("name");
+
+ //retrieve the category's mandatory 'priority' or 'level' element's value.
+ //It may not be the only child node, so request by tag name.
+ NodeList priorityElements = categoryElement.getElementsByTagName("priority");
+ NodeList levelElements = categoryElement.getElementsByTagName("level");
+
+ if (priorityElements.getLength() != 0)
+ {
+ Element priorityElement = (Element) priorityElements.item(0);
+ priority = priorityElement.getAttribute("value").toUpperCase();
+ }
+ else if (levelElements.getLength() != 0)
+ {
+ Element levelElement = (Element) levelElements.item(0);
+ priority = levelElement.getAttribute("value").toUpperCase();
+ }
+ else
+ {
+ //there is no exiting priority or level to view, move onto next category/logger
+ continue;
+ }
+
+ try
+ {
+ Object[] itemData = {categoryName, priority};
+ CompositeData loggerData = new CompositeDataSupport(_loggerLevelCompositeType, COMPOSITE_ITEM_NAMES, itemData);
+ loggerLevelList.put(loggerData);
+ }
+ catch (OpenDataException e)
+ {
+ _logger.warn("Unable to create logger level list due to :" + e);
+ return null;
+ }
+ }
+
+ //retrieve the 'logger' element nodes
+ NodeList loggerElements = doc.getElementsByTagName("logger");
+
+ String loggerName;
+ String level;
+
+ for (int i = 0; i < loggerElements.getLength(); i++)
+ {
+ Element loggerElement = (Element) loggerElements.item(i);
+ loggerName = loggerElement.getAttribute("name");
+
+ //retrieve the logger's mandatory 'level' element's value
+ //It may not be the only child node, so request by tag name.
+ NodeList levelElements = loggerElement.getElementsByTagName("level");
+
+ Element levelElement = (Element) levelElements.item(0);
+ level = levelElement.getAttribute("value").toUpperCase();
+
+ try
+ {
+ Object[] itemData = {loggerName, level};
+ CompositeData loggerData = new CompositeDataSupport(_loggerLevelCompositeType, COMPOSITE_ITEM_NAMES, itemData);
+ loggerLevelList.put(loggerData);
+ }
+ catch (OpenDataException e)
+ {
+ _logger.warn("Unable to create logger level list due to :" + e);
+ return null;
+ }
+ }
+
+ return loggerLevelList;
+ }
+
+ public synchronized boolean setConfigFileLoggerLevel(String logger, String level) throws IOException
+ {
+ //check that the specified level is a valid log4j Level
+ try
+ {
+ getLevel(level);
+ }
+ catch (Exception e)
+ {
+ //it isnt a valid level
+ return false;
+ }
+
+ _logger.info("Setting level to " + level + " for logger '" + logger
+ + "' in log4j xml configuration file: " + _log4jConfigFileName);
+
+ Document doc = parseConfigFile(_log4jConfigFileName);
+
+ //retrieve the 'category' and 'logger' element nodes
+ NodeList categoryElements = doc.getElementsByTagName("category");
+ NodeList loggerElements = doc.getElementsByTagName("logger");
+
+ //collect them into a single elements list
+ List<Element> logElements = new ArrayList<Element>();
+
+ for (int i = 0; i < categoryElements.getLength(); i++)
+ {
+ logElements.add((Element) categoryElements.item(i));
+ }
+ for (int i = 0; i < loggerElements.getLength(); i++)
+ {
+ logElements.add((Element) loggerElements.item(i));
+ }
+
+ //try to locate the specified logger/category in the elements retrieved
+ Element logElement = null;
+ for (Element e : logElements)
+ {
+ if (e.getAttribute("name").equals(logger))
+ {
+ logElement = e;
+ break;
+ }
+ }
+
+ if (logElement == null)
+ {
+ //no loggers/categories with given name found, does not exist to update
+ _logger.warn("Specified logger does not exist in the configuration file: " +logger);
+ return false;
+ }
+
+ //retrieve the optional 'priority' or 'level' sub-element value.
+ //It may not be the only child node, so request by tag name.
+ NodeList priorityElements = logElement.getElementsByTagName("priority");
+ NodeList levelElements = logElement.getElementsByTagName("level");
+
+ Element levelElement = null;
+ if (priorityElements.getLength() != 0)
+ {
+ levelElement = (Element) priorityElements.item(0);
+ }
+ else if (levelElements.getLength() != 0)
+ {
+ levelElement = (Element) levelElements.item(0);
+ }
+ else
+ {
+ //there is no exiting priority or level element to update
+ return false;
+ }
+
+ //update the element with the new level/priority
+ levelElement.setAttribute("value", level);
+
+ //output the new file
+ return writeUpdatedConfigFile(_log4jConfigFileName, doc);
+ }
+
+
+ /* The log4j XML configuration file DTD defines 2 possible element
+ * combinations for specifying the optional root logger level settings
+ * Must account for the following:
+ *
+ * <root> <priority value="y"/> </root> OR
+ * <root> <level value="y"/> </root>
+ *
+ * Noting also that the level/priority child element is optional too,
+ * and not the only possible child element.
+ */
+
+ public synchronized String getConfigFileRootLoggerLevel() throws IOException
+ {
+ _logger.info("Getting root logger level from log4j configuration file");
+
+ Document doc = parseConfigFile(_log4jConfigFileName);
+
+ //retrieve the optional 'root' element node
+ NodeList rootElements = doc.getElementsByTagName("root");
+
+ if (rootElements.getLength() == 0)
+ {
+ //there is not root logger definition
+ return null;
+ }
+
+ Element rootElement = (Element) rootElements.item(0);
+
+ //retrieve the optional 'priority' or 'level' element value.
+ //It may not be the only child node, so request by tag name.
+ NodeList priorityElements = rootElement.getElementsByTagName("priority");
+ NodeList levelElements = rootElement.getElementsByTagName("level");
+ String priority = null;
+
+ if (priorityElements.getLength() != 0)
+ {
+ Element priorityElement = (Element) priorityElements.item(0);
+ priority = priorityElement.getAttribute("value");
+ }
+ else if(levelElements.getLength() != 0)
+ {
+ Element levelElement = (Element) levelElements.item(0);
+ priority = levelElement.getAttribute("value");
+ }
+
+ if(priority != null)
+ {
+ return priority.toUpperCase();
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ public synchronized boolean setConfigFileRootLoggerLevel(String level) throws IOException
+ {
+ //check that the specified level is a valid log4j Level
+ try
+ {
+ getLevel(level);
+ }
+ catch (Exception e)
+ {
+ //it isnt a valid level
+ return false;
+ }
+
+ _logger.info("Setting level to " + level + " for the Root logger in " +
+ "log4j xml configuration file: " + _log4jConfigFileName);
+
+ Document doc = parseConfigFile(_log4jConfigFileName);
+
+ //retrieve the optional 'root' element node
+ NodeList rootElements = doc.getElementsByTagName("root");
+
+ if (rootElements.getLength() == 0)
+ {
+ return false;
+ }
+
+ Element rootElement = (Element) rootElements.item(0);
+
+ //retrieve the optional 'priority' or 'level' sub-element value.
+ //It may not be the only child node, so request by tag name.
+ NodeList priorityElements = rootElement.getElementsByTagName("priority");
+ NodeList levelElements = rootElement.getElementsByTagName("level");
+
+ Element levelElement = null;
+ if (priorityElements.getLength() != 0)
+ {
+ levelElement = (Element) priorityElements.item(0);
+ }
+ else if (levelElements.getLength() != 0)
+ {
+ levelElement = (Element) levelElements.item(0);
+ }
+ else
+ {
+ //there is no exiting priority/level to update
+ return false;
+ }
+
+ //update the element with the new level/priority
+ levelElement.setAttribute("value", level);
+
+ //output the new file
+ return writeUpdatedConfigFile(_log4jConfigFileName, doc);
+ }
+}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/management/AMQManagedObject.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/management/AMQManagedObject.java
index a2c2bd62a2..c6e07f6f48 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/management/AMQManagedObject.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/management/AMQManagedObject.java
@@ -50,10 +50,10 @@ public abstract class AMQManagedObject extends DefaultManagedObject
protected MBeanInfo _mbeanInfo;
- protected AMQManagedObject(Class<?> managementInterface, String typeName)
+ protected AMQManagedObject(Class<?> managementInterface, String typeName, int version)
throws NotCompliantMBeanException
{
- super(managementInterface, typeName);
+ super(managementInterface, typeName, version);
buildMBeanInfo();
}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/management/DefaultManagedObject.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/management/DefaultManagedObject.java
index 84526dbc11..67aee90ba4 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/management/DefaultManagedObject.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/management/DefaultManagedObject.java
@@ -39,13 +39,15 @@ public abstract class DefaultManagedObject extends StandardMBean implements Mana
private Class<?> _managementInterface;
private String _typeName;
+ private int _version;
- protected DefaultManagedObject(Class<?> managementInterface, String typeName)
+ protected DefaultManagedObject(Class<?> managementInterface, String typeName, int version)
throws NotCompliantMBeanException
{
super(managementInterface);
_managementInterface = managementInterface;
_typeName = typeName;
+ _version = version;
}
public String getType()
@@ -115,6 +117,10 @@ public abstract class DefaultManagedObject extends StandardMBean implements Mana
objectName.append(getHierarchicalName(this));
objectName.append("name=").append(name);
+ objectName.append(",");
+ objectName.append("version=").append(_version);
+
+
return new ObjectName(objectName.toString());
}
@@ -132,6 +138,9 @@ public abstract class DefaultManagedObject extends StandardMBean implements Mana
objectName.append(hierarchyName.substring(0, hierarchyName.lastIndexOf(",")));
}
+ objectName.append(",");
+ objectName.append("version=").append(_version);
+
return new ObjectName(objectName.toString());
}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/management/JMXManagedObjectRegistry.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/management/JMXManagedObjectRegistry.java
index a0d2c7dc66..3fc460b325 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/management/JMXManagedObjectRegistry.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/management/JMXManagedObjectRegistry.java
@@ -32,9 +32,12 @@ import org.apache.qpid.server.security.auth.rmi.RMIPasswordAuthenticator;
import org.apache.qpid.server.security.auth.sasl.crammd5.CRAMMD5HashedInitialiser;
import org.apache.qpid.server.security.auth.sasl.plain.PlainInitialiser;
+import javax.management.InstanceNotFoundException;
import javax.management.JMException;
+import javax.management.MBeanRegistrationException;
import javax.management.MBeanServer;
import javax.management.MBeanServerFactory;
+import javax.management.ObjectName;
import javax.management.remote.JMXConnectorServer;
import javax.management.remote.JMXConnectorServerFactory;
import javax.management.remote.JMXServiceURL;
@@ -85,7 +88,7 @@ public class JMXManagedObjectRegistry implements ManagedObjectRegistry
IApplicationRegistry appRegistry = ApplicationRegistry.getInstance();
// Retrieve the config parameters
- boolean platformServer = appRegistry.getConfiguration().getBoolean("management.platform-mbeanserver", true);
+ boolean platformServer = appRegistry.getConfiguration().getPlatformMbeanserver();
_mbeanServer =
platformServer ? ManagementFactory.getPlatformMBeanServer()
@@ -104,196 +107,164 @@ public class JMXManagedObjectRegistry implements ManagedObjectRegistry
}
IApplicationRegistry appRegistry = ApplicationRegistry.getInstance();
-
- boolean jmxmpSecurity = appRegistry.getConfiguration().getBoolean("management.security-enabled", false);
- int port = appRegistry.getConfiguration().getInt(MANAGEMENT_PORT_CONFIG_PATH, MANAGEMENT_PORT_DEFAULT);
+ int port = appRegistry.getConfiguration().getJMXManagementPort();
//retrieve the Principal Database assigned to JMX authentication duties
- String jmxDatabaseName = appRegistry.getConfiguration().getString("security.jmx.principal-database");
+ String jmxDatabaseName = appRegistry.getConfiguration().getJMXPrincipalDatabase();
Map<String, PrincipalDatabase> map = appRegistry.getDatabaseManager().getDatabases();
PrincipalDatabase db = map.get(jmxDatabaseName);
final JMXConnectorServer cs;
HashMap<String,Object> env = new HashMap<String,Object>();
- if (jmxmpSecurity)
+ //Socket factories for the RMIConnectorServer, either default or SLL depending on configuration
+ RMIClientSocketFactory csf;
+ RMIServerSocketFactory ssf;
+
+ //check ssl enabled option in config, default to true if option is not set
+ boolean sslEnabled = appRegistry.getConfiguration().getManagementSSLEnabled();
+
+ if (sslEnabled)
{
- // For SASL using JMXMP
- JMXServiceURL jmxURL = new JMXServiceURL("jmxmp", null, port);
+ //set the SSL related system properties used by the SSL RMI socket factories to the values
+ //given in the configuration file, unless command line settings have already been specified
+ String keyStorePath;
- String saslType = null;
- if (db instanceof Base64MD5PasswordFilePrincipalDatabase)
+ if(System.getProperty("javax.net.ssl.keyStore") != null)
{
- saslType = "SASL/CRAM-MD5";
- env.put("jmx.remote.profiles", "SASL/CRAM-MD5");
- CRAMMD5HashedInitialiser initialiser = new CRAMMD5HashedInitialiser();
- initialiser.initialise(db);
- env.put("jmx.remote.sasl.callback.handler", initialiser.getCallbackHandler());
+ keyStorePath = System.getProperty("javax.net.ssl.keyStore");
}
- else if (db instanceof PlainPasswordFilePrincipalDatabase)
+ else
{
- saslType = "SASL/PLAIN";
- PlainInitialiser initialiser = new PlainInitialiser();
- initialiser.initialise(db);
- env.put("jmx.remote.sasl.callback.handler", initialiser.getCallbackHandler());
- env.put("jmx.remote.profiles", "SASL/PLAIN");
+ keyStorePath = appRegistry.getConfiguration().getManagementKeyStorePath();
}
- //workaround NPE generated from env map classloader issue when using Eclipse 3.4 to launch
- env.put("jmx.remote.profile.provider.class.loader", this.getClass().getClassLoader());
-
- _log.warn("Starting JMXMP based JMX ConnectorServer on port '" + port + "' with " + saslType);
- _startupLog.warn("Starting JMXMP based JMX ConnectorServer on port '" + port + "' with " + saslType);
-
- cs = JMXConnectorServerFactory.newJMXConnectorServer(jmxURL, env, _mbeanServer);
- }
- else
- {
- //Socket factories for the RMIConnectorServer, either default or SLL depending on configuration
- RMIClientSocketFactory csf;
- RMIServerSocketFactory ssf;
-
- //check ssl enabled option in config, default to true if option is not set
- boolean sslEnabled = appRegistry.getConfiguration().getBoolean("management.ssl.enabled", true);
-
- if (sslEnabled)
+ //check the keystore path value is valid
+ if (keyStorePath == null)
{
- //set the SSL related system properties used by the SSL RMI socket factories to the values
- //given in the configuration file, unless command line settings have already been specified
- String keyStorePath;
-
- if(System.getProperty("javax.net.ssl.keyStore") != null)
+ throw new ConfigurationException("JMX management SSL keystore path not defined, " +
+ "unable to start SSL protected JMX ConnectorServer");
+ }
+ else
+ {
+ //ensure the system property is set
+ System.setProperty("javax.net.ssl.keyStore", keyStorePath);
+
+ //check the file is usable
+ File ksf = new File(keyStorePath);
+
+ if (!ksf.exists())
{
- keyStorePath = System.getProperty("javax.net.ssl.keyStore");
+ throw new FileNotFoundException("Cannot find JMX management SSL keystore file " + ksf + "\n"
+ + "Check broker configuration, or see create-example-ssl-stores script"
+ + "in the bin/ directory if you need to generate an example store.");
}
- else{
- keyStorePath = appRegistry.getConfiguration().getString("management.ssl.keyStorePath", null);
+ if (!ksf.canRead())
+ {
+ throw new FileNotFoundException("Cannot read JMX management SSL keystore file: "
+ + ksf + ". Check permissions.");
}
- //check the keystore path value is valid
- if (keyStorePath == null)
+ _log.info("JMX ConnectorServer using SSL keystore file " + ksf.getAbsolutePath());
+ _startupLog.info("JMX ConnectorServer using SSL keystore file " + ksf.getAbsolutePath());
+ }
+
+ //check the key store password is set
+ if (System.getProperty("javax.net.ssl.keyStorePassword") == null)
+ {
+
+ if (appRegistry.getConfiguration().getManagementKeyStorePassword() == null)
{
- throw new ConfigurationException("JMX management SSL keystore path not defined, " +
- "unable to start SSL protected JMX ConnectorServer");
+ throw new ConfigurationException("JMX management SSL keystore password not defined, " +
+ "unable to start requested SSL protected JMX server");
}
else
{
- //ensure the system property is set
- System.setProperty("javax.net.ssl.keyStore", keyStorePath);
-
- //check the file is usable
- File ksf = new File(keyStorePath);
-
- if (!ksf.exists())
- {
- throw new FileNotFoundException("Cannot find JMX management SSL keystore file " + ksf);
- }
- if (!ksf.canRead())
- {
- throw new FileNotFoundException("Cannot read JMX management SSL keystore file: "
- + ksf + ". Check permissions.");
- }
-
- _log.info("JMX ConnectorServer using SSL keystore file " + ksf.getAbsolutePath());
- _startupLog.info("JMX ConnectorServer using SSL keystore file " + ksf.getAbsolutePath());
+ System.setProperty("javax.net.ssl.keyStorePassword",
+ appRegistry.getConfiguration().getManagementKeyStorePassword());
}
+ }
- //check the key store password is set
- if (System.getProperty("javax.net.ssl.keyStorePassword") == null)
- {
-
- if (appRegistry.getConfiguration().getString("management.ssl.keyStorePassword") == null)
- {
- throw new ConfigurationException("JMX management SSL keystore password not defined, " +
- "unable to start requested SSL protected JMX server");
- }
- else
- {
- System.setProperty("javax.net.ssl.keyStorePassword",
- appRegistry.getConfiguration().getString("management.ssl.keyStorePassword"));
- }
- }
+ //create the SSL RMI socket factories
+ csf = new SslRMIClientSocketFactory();
+ ssf = new SslRMIServerSocketFactory();
+
+ _log.warn("Starting JMX ConnectorServer on port '"+ port + "' (+" +
+ (port +PORT_EXPORT_OFFSET) + ") with SSL");
+ _startupLog.warn("Starting JMX ConnectorServer on port '"+ port + "' (+" +
+ (port +PORT_EXPORT_OFFSET) + ") with SSL");
+ }
+ else
+ {
+ //Do not specify any specific RMI socket factories, resulting in use of the defaults.
+ csf = null;
+ ssf = null;
- //create the SSL RMI socket factories
- csf = new SslRMIClientSocketFactory();
- ssf = new SslRMIServerSocketFactory();
+ _log.warn("Starting JMX ConnectorServer on port '" + port + "' (+" + (port +PORT_EXPORT_OFFSET) + ")");
+ _startupLog.warn("Starting JMX ConnectorServer on port '" + port + "' (+" + (port +PORT_EXPORT_OFFSET) + ")");
+ }
- _log.warn("Starting JMX ConnectorServer on port '"+ port + "' (+" +
- (port +PORT_EXPORT_OFFSET) + ") with SSL");
- _startupLog.warn("Starting JMX ConnectorServer on port '"+ port + "' (+" +
- (port +PORT_EXPORT_OFFSET) + ") with SSL");
- }
- else
- {
- //Do not specify any specific RMI socket factories, resulting in use of the defaults.
- csf = null;
- ssf = null;
-
- _log.warn("Starting JMX ConnectorServer on port '" + port + "' (+" + (port +PORT_EXPORT_OFFSET) + ")");
- _startupLog.warn("Starting JMX ConnectorServer on port '" + port + "' (+" + (port +PORT_EXPORT_OFFSET) + ")");
- }
-
- //add a JMXAuthenticator implementation the env map to authenticate the RMI based JMX connector server
- RMIPasswordAuthenticator rmipa = new RMIPasswordAuthenticator();
- rmipa.setPrincipalDatabase(db);
- env.put(JMXConnectorServer.AUTHENTICATOR, rmipa);
-
- /*
- * Start a RMI registry on the management port, to hold the JMX RMI ConnectorServer stub.
- * Using custom socket factory to prevent anyone (including us unfortunately) binding to the registry using RMI.
- * As a result, only binds made using the object reference will succeed, thus securing it from external change.
- */
- System.setProperty("java.rmi.server.randomIDs", "true");
- _rmiRegistry = LocateRegistry.createRegistry(port, null, new CustomRMIServerSocketFactory());
-
- /*
- * We must now create the RMI ConnectorServer manually, as the JMX Factory methods use RMI calls
- * to bind the ConnectorServer to the registry, which will now fail as for security we have
- * locked it from any RMI based modifications, including our own. Instead, we will manually bind
- * the RMIConnectorServer stub to the registry using its object reference, which will still succeed.
- *
- * The registry is exported on the defined management port 'port'. We will export the RMIConnectorServer
- * on 'port +1'. Use of these two well-defined ports will ease any navigation through firewall's.
- */
- final RMIServerImpl rmiConnectorServerStub = new RMIJRMPServerImpl(port+PORT_EXPORT_OFFSET, csf, ssf, env);
- final String hostname = InetAddress.getLocalHost().getHostName();
- final JMXServiceURL externalUrl = new JMXServiceURL(
- "service:jmx:rmi://"+hostname+":"+(port+PORT_EXPORT_OFFSET)+"/jndi/rmi://"+hostname+":"+port+"/jmxrmi");
-
- final JMXServiceURL internalUrl = new JMXServiceURL("rmi", hostname, port+PORT_EXPORT_OFFSET);
- cs = new RMIConnectorServer(internalUrl, env, rmiConnectorServerStub, _mbeanServer)
+ //add a JMXAuthenticator implementation the env map to authenticate the RMI based JMX connector server
+ RMIPasswordAuthenticator rmipa = new RMIPasswordAuthenticator();
+ rmipa.setPrincipalDatabase(db);
+ env.put(JMXConnectorServer.AUTHENTICATOR, rmipa);
+
+ /*
+ * Start a RMI registry on the management port, to hold the JMX RMI ConnectorServer stub.
+ * Using custom socket factory to prevent anyone (including us unfortunately) binding to the registry using RMI.
+ * As a result, only binds made using the object reference will succeed, thus securing it from external change.
+ */
+ System.setProperty("java.rmi.server.randomIDs", "true");
+ _rmiRegistry = LocateRegistry.createRegistry(port, null, new CustomRMIServerSocketFactory());
+
+ /*
+ * We must now create the RMI ConnectorServer manually, as the JMX Factory methods use RMI calls
+ * to bind the ConnectorServer to the registry, which will now fail as for security we have
+ * locked it from any RMI based modifications, including our own. Instead, we will manually bind
+ * the RMIConnectorServer stub to the registry using its object reference, which will still succeed.
+ *
+ * The registry is exported on the defined management port 'port'. We will export the RMIConnectorServer
+ * on 'port +1'. Use of these two well-defined ports will ease any navigation through firewall's.
+ */
+ final RMIServerImpl rmiConnectorServerStub = new RMIJRMPServerImpl(port+PORT_EXPORT_OFFSET, csf, ssf, env);
+ final String hostname = InetAddress.getLocalHost().getHostName();
+ final JMXServiceURL externalUrl = new JMXServiceURL(
+ "service:jmx:rmi://"+hostname+":"+(port+PORT_EXPORT_OFFSET)+"/jndi/rmi://"+hostname+":"+port+"/jmxrmi");
+
+ final JMXServiceURL internalUrl = new JMXServiceURL("rmi", hostname, port+PORT_EXPORT_OFFSET);
+ cs = new RMIConnectorServer(internalUrl, env, rmiConnectorServerStub, _mbeanServer)
+ {
+ @Override
+ public synchronized void start() throws IOException
{
- @Override
- public synchronized void start() throws IOException
+ try
{
- try
- {
- //manually bind the connector server to the registry at key 'jmxrmi', like the out-of-the-box agent
- _rmiRegistry.bind("jmxrmi", rmiConnectorServerStub);
- }
- catch (AlreadyBoundException abe)
- {
- //key was already in use. shouldnt happen here as its a new registry, unbindable by normal means.
-
- //IOExceptions are the only checked type throwable by the method, wrap and rethrow
- IOException ioe = new IOException(abe.getMessage());
- ioe.initCause(abe);
- throw ioe;
- }
-
- //now do the normal tasks
- super.start();
- }
-
- @Override
- public JMXServiceURL getAddress()
- {
- //must return our pre-crafted url that includes the full details, inc JNDI details
- return externalUrl;
- }
+ //manually bind the connector server to the registry at key 'jmxrmi', like the out-of-the-box agent
+ _rmiRegistry.bind("jmxrmi", rmiConnectorServerStub);
+ }
+ catch (AlreadyBoundException abe)
+ {
+ //key was already in use. shouldnt happen here as its a new registry, unbindable by normal means.
- };
- }
+ //IOExceptions are the only checked type throwable by the method, wrap and rethrow
+ IOException ioe = new IOException(abe.getMessage());
+ ioe.initCause(abe);
+ throw ioe;
+ }
+
+ //now do the normal tasks
+ super.start();
+ }
+
+ @Override
+ public JMXServiceURL getAddress()
+ {
+ //must return our pre-crafted url that includes the full details, inc JNDI details
+ return externalUrl;
+ }
+
+ };
+
//Add the custom invoker as an MBeanServerForwarder, and start the RMIConnectorServer.
MBeanServerForwarder mbsf = MBeanInvocationHandlerImpl.newProxyInstance();
@@ -379,6 +350,17 @@ public class JMXManagedObjectRegistry implements ManagedObjectRegistry
// Stopping the RMI registry
UnicastRemoteObject.unexportObject(_rmiRegistry, true);
}
+ for (ObjectName name : _mbeanServer.queryNames(null, null))
+ {
+ try
+ {
+ _mbeanServer.unregisterMBean(name);
+ }
+ catch (JMException e)
+ {
+ // Really shouldn't happen, but we'll ignore that...
+ }
+ }
}
}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/management/MBeanInvocationHandlerImpl.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/management/MBeanInvocationHandlerImpl.java
index a0ecc2bd85..e9b4d85e66 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/management/MBeanInvocationHandlerImpl.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/management/MBeanInvocationHandlerImpl.java
@@ -20,6 +20,8 @@
*/
package org.apache.qpid.server.management;
+import org.apache.qpid.server.configuration.management.ConfigurationManagement;
+import org.apache.qpid.server.logging.management.LoggingManagement;
import org.apache.qpid.server.security.access.management.UserManagement;
import org.apache.log4j.Logger;
@@ -37,6 +39,8 @@ import java.lang.reflect.Method;
import java.security.AccessController;
import java.security.Principal;
import java.security.AccessControlContext;
+import java.util.ArrayList;
+import java.util.HashSet;
import java.util.Set;
import java.util.Properties;
@@ -53,9 +57,16 @@ public class MBeanInvocationHandlerImpl implements InvocationHandler
public final static String READWRITE = "readwrite";
public final static String READONLY = "readonly";
private final static String DELEGATE = "JMImplementation:type=MBeanServerDelegate";
- private MBeanServer mbs;
+ private MBeanServer _mbs;
private static Properties _userRoles = new Properties();
+ private static HashSet<String> _adminOnlyMethods = new HashSet<String>();
+ {
+ _adminOnlyMethods.add(UserManagement.TYPE);
+ _adminOnlyMethods.add(LoggingManagement.TYPE);
+ _adminOnlyMethods.add(ConfigurationManagement.TYPE);
+ }
+
public static MBeanServerForwarder newProxyInstance()
{
final InvocationHandler handler = new MBeanInvocationHandlerImpl();
@@ -71,7 +82,7 @@ public class MBeanInvocationHandlerImpl implements InvocationHandler
if (methodName.equals("getMBeanServer"))
{
- return mbs;
+ return _mbs;
}
if (methodName.equals("setMBeanServer"))
@@ -80,11 +91,11 @@ public class MBeanInvocationHandlerImpl implements InvocationHandler
{
throw new IllegalArgumentException("Null MBeanServer");
}
- if (mbs != null)
+ if (_mbs != null)
{
throw new IllegalArgumentException("MBeanServer object already initialized");
}
- mbs = (MBeanServer) args[0];
+ _mbs = (MBeanServer) args[0];
return null;
}
@@ -95,12 +106,12 @@ public class MBeanInvocationHandlerImpl implements InvocationHandler
// Allow operations performed locally on behalf of the connector server itself
if (subject == null)
{
- return method.invoke(mbs, args);
+ return method.invoke(_mbs, args);
}
if (args == null || DELEGATE.equals(args[0]))
{
- return method.invoke(mbs, args);
+ return method.invoke(_mbs, args);
}
// Restrict access to "createMBean" and "unregisterMBean" to any user
@@ -124,7 +135,7 @@ public class MBeanInvocationHandlerImpl implements InvocationHandler
{
if (isAdmin(identity))
{
- return method.invoke(mbs, args);
+ return method.invoke(_mbs, args);
}
else
{
@@ -135,14 +146,14 @@ public class MBeanInvocationHandlerImpl implements InvocationHandler
// Following users can perform any operation other than "createMBean" and "unregisterMBean"
if (isAllowedToModify(identity))
{
- return method.invoke(mbs, args);
+ return method.invoke(_mbs, args);
}
// These users can only call "getAttribute" on the MBeanServerDelegate MBean
// Here we can add other fine grained permissions like specific method for a particular mbean
if (isReadOnlyUser(identity) && isReadOnlyMethod(method, args))
{
- return method.invoke(mbs, args);
+ return method.invoke(_mbs, args);
}
throw new SecurityException("Access denied");
@@ -153,9 +164,9 @@ public class MBeanInvocationHandlerImpl implements InvocationHandler
if (args[0] instanceof ObjectName)
{
ObjectName object = (ObjectName) args[0];
- return UserManagement.TYPE.equals(object.getKeyProperty("type"));
+
+ return _adminOnlyMethods.contains(object.getKeyProperty("type"));
}
-
return false;
}
@@ -196,7 +207,10 @@ public class MBeanInvocationHandlerImpl implements InvocationHandler
private boolean isReadOnlyMethod(Method method, Object[] args)
{
String methodName = method.getName();
- if (methodName.startsWith("query") || methodName.startsWith("get"))
+
+ //handle standard get/set/query and select 'is' methods from MBeanServer
+ if (methodName.startsWith("query") || methodName.startsWith("get")
+ ||methodName.startsWith("isInstanceOf") || methodName.startsWith("isRegistered"))
{
return true;
}
@@ -205,8 +219,11 @@ public class MBeanInvocationHandlerImpl implements InvocationHandler
return false;
}
+ //handle invocation of other methods on mbeans
if ((args[0] instanceof ObjectName) && (methodName.equals("invoke")))
{
+
+ //get invoked method name
String mbeanMethod = (args.length > 1) ? (String) args[1] : null;
if (mbeanMethod == null)
{
@@ -215,7 +232,8 @@ public class MBeanInvocationHandlerImpl implements InvocationHandler
try
{
- MBeanInfo mbeanInfo = mbs.getMBeanInfo((ObjectName) args[0]);
+ //check if the given method is tagged with an INFO impact attribute
+ MBeanInfo mbeanInfo = _mbs.getMBeanInfo((ObjectName) args[0]);
if (mbeanInfo != null)
{
MBeanOperationInfo[] opInfos = mbeanInfo.getOperations();
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/management/ManagedBroker.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/management/ManagedBroker.java
index 45e2e91ed7..c18417fc43 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/management/ManagedBroker.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/management/ManagedBroker.java
@@ -40,12 +40,13 @@ public interface ManagedBroker
{
static final String TYPE = "VirtualHostManager";
+ static final int VERSION = 1 ;
+
/**
* Creates a new Exchange.
* @param name
* @param type
* @param durable
- * @param passive
* @throws IOException
* @throws JMException
*/
@@ -73,7 +74,6 @@ public interface ManagedBroker
* @param queueName
* @param durable
* @param owner
- * @param autoDelete
* @throws IOException
* @throws JMException
*/
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/plugins/PluginManager.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/plugins/PluginManager.java
index 1b7919e8b7..dbfcefb6ab 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/plugins/PluginManager.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/plugins/PluginManager.java
@@ -34,7 +34,9 @@ import org.apache.qpid.server.security.access.ACLPlugin;
import org.apache.qpid.server.security.access.ACLPluginFactory;
import org.apache.qpid.server.security.access.plugins.AllowAll;
import org.apache.qpid.server.security.access.plugins.DenyAll;
+import org.apache.qpid.server.security.access.plugins.LegacyAccessPlugin;
import org.apache.qpid.server.security.access.plugins.SimpleXML;
+import org.apache.qpid.server.security.access.plugins.network.FirewallPlugin;
import org.osgi.framework.BundleActivator;
import org.osgi.framework.BundleException;
import org.osgi.util.tracker.ServiceTracker;
@@ -165,6 +167,8 @@ public class PluginManager
_securityPlugins.put(SimpleXML.class.getName(), SimpleXML.FACTORY);
_securityPlugins.put(AllowAll.class.getName(), AllowAll.FACTORY);
_securityPlugins.put(DenyAll.class.getName(), DenyAll.FACTORY);
+ _securityPlugins.put(LegacyAccessPlugin.class.getName(), LegacyAccessPlugin.FACTORY);
+ _securityPlugins.put(FirewallPlugin.class.getName(), FirewallPlugin.FACTORY);
}
return _securityPlugins;
}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/protocol/AMQMinaProtocolSession.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/protocol/AMQMinaProtocolSession.java
index 4b69842c49..205ca73f13 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/protocol/AMQMinaProtocolSession.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/protocol/AMQMinaProtocolSession.java
@@ -582,7 +582,7 @@ public class AMQMinaProtocolSession implements AMQProtocolSession, Managable
if (delay > 0)
{
_minaProtocolSession.setIdleTime(IdleStatus.WRITER_IDLE, delay);
- _minaProtocolSession.setIdleTime(IdleStatus.READER_IDLE, HeartbeatConfig.getInstance().getTimeout(delay));
+ _minaProtocolSession.setIdleTime(IdleStatus.READER_IDLE, (int) (ApplicationRegistry.getInstance().getConfiguration().getHeartBeatTimeout() * delay));
}
}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/protocol/AMQPFastProtocolHandler.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/protocol/AMQPFastProtocolHandler.java
index d8dbf97e49..0dbefd8798 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/protocol/AMQPFastProtocolHandler.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/protocol/AMQPFastProtocolHandler.java
@@ -20,6 +20,9 @@
*/
package org.apache.qpid.server.protocol;
+import java.io.IOException;
+import java.net.InetSocketAddress;
+
import org.apache.log4j.Logger;
import org.apache.mina.common.ByteBuffer;
import org.apache.mina.common.IdleStatus;
@@ -34,15 +37,19 @@ import org.apache.mina.filter.executor.ExecutorFilter;
import org.apache.mina.util.SessionUtil;
import org.apache.qpid.AMQException;
import org.apache.qpid.codec.AMQCodecFactory;
-import org.apache.qpid.framing.*;
+import org.apache.qpid.framing.AMQDataBlock;
+import org.apache.qpid.framing.AMQProtocolHeaderException;
+import org.apache.qpid.framing.AMQShortString;
+import org.apache.qpid.framing.ConnectionCloseBody;
+import org.apache.qpid.framing.HeartbeatBody;
+import org.apache.qpid.framing.MethodRegistry;
+import org.apache.qpid.framing.ProtocolInitiation;
+import org.apache.qpid.framing.ProtocolVersion;
+import org.apache.qpid.server.configuration.ServerConfiguration;
import org.apache.qpid.server.registry.ApplicationRegistry;
import org.apache.qpid.server.registry.IApplicationRegistry;
-import org.apache.qpid.server.transport.ConnectorConfiguration;
import org.apache.qpid.ssl.SSLContextFactory;
-import java.io.IOException;
-import java.net.InetSocketAddress;
-
/**
* The protocol handler handles "protocol events" for all connections. The state
* associated with an individual connection is accessed through the protocol session.
@@ -56,9 +63,6 @@ public class AMQPFastProtocolHandler extends IoHandlerAdapter
private final IApplicationRegistry _applicationRegistry;
- private static String DEFAULT_BUFFER_READ_LIMIT_SIZE = "262144";
- private static String DEFAULT_BUFFER_WRITE_LIMIT_SIZE = "262144";
-
private final int BUFFER_READ_LIMIT_SIZE;
private final int BUFFER_WRITE_LIMIT_SIZE;
@@ -72,8 +76,8 @@ public class AMQPFastProtocolHandler extends IoHandlerAdapter
_applicationRegistry = applicationRegistry;
// Read the configuration from the application registry
- BUFFER_READ_LIMIT_SIZE = Integer.parseInt(_applicationRegistry.getConfiguration().getString("broker.connector.protectio.readBufferLimitSize", DEFAULT_BUFFER_READ_LIMIT_SIZE));
- BUFFER_WRITE_LIMIT_SIZE = Integer.parseInt(_applicationRegistry.getConfiguration().getString("broker.connector.protectio.writeBufferLimitSize", DEFAULT_BUFFER_WRITE_LIMIT_SIZE));
+ BUFFER_READ_LIMIT_SIZE = _applicationRegistry.getConfiguration().getBufferReadLimit();
+ BUFFER_WRITE_LIMIT_SIZE = _applicationRegistry.getConfiguration().getBufferWriteLimit();
_logger.debug("AMQPFastProtocolHandler created");
}
@@ -92,17 +96,22 @@ public class AMQPFastProtocolHandler extends IoHandlerAdapter
_logger.info("Protocol session created for:" + protocolSession.getRemoteAddress());
final QpidProtocolCodecFilter pcf = new QpidProtocolCodecFilter(codecFactory);
-
- ConnectorConfiguration connectorConfig = ApplicationRegistry.getInstance().
- getConfiguredObject(ConnectorConfiguration.class);
- if (connectorConfig.enableExecutorPool)
+ final ServerConfiguration config = _applicationRegistry.getConfiguration();
+
+ String keystorePath = config.getKeystorePath();
+ String keystorePassword = config.getKeystorePassword();
+ String certType = config.getCertType();
+ SSLContextFactory sslContextFactory = null;
+ boolean isSsl = false;
+ if (config.getEnableSSL() && isSSLClient(config, protocolSession))
{
- if (connectorConfig.enableSSL && isSSLClient(connectorConfig, protocolSession))
+ sslContextFactory = new SSLContextFactory(keystorePath, keystorePassword, certType);
+ isSsl = true;
+ }
+ if (config.getEnableExecutorPool())
+ {
+ if (isSsl)
{
- String keystorePath = connectorConfig.keystorePath;
- String keystorePassword = connectorConfig.keystorePassword;
- String certType = connectorConfig.certType;
- SSLContextFactory sslContextFactory = new SSLContextFactory(keystorePath, keystorePassword, certType);
protocolSession.getFilterChain().addAfter("AsynchronousReadFilter", "sslFilter",
new SSLFilter(sslContextFactory.buildServerContext()));
}
@@ -111,19 +120,14 @@ public class AMQPFastProtocolHandler extends IoHandlerAdapter
else
{
protocolSession.getFilterChain().addLast("protocolFilter", pcf);
- if (connectorConfig.enableSSL && isSSLClient(connectorConfig, protocolSession))
+ if (isSsl)
{
- String keystorePath = connectorConfig.keystorePath;
- String keystorePassword = connectorConfig.keystorePassword;
- String certType = connectorConfig.certType;
- SSLContextFactory sslContextFactory = new SSLContextFactory(keystorePath, keystorePassword, certType);
protocolSession.getFilterChain().addBefore("protocolFilter", "sslFilter",
new SSLFilter(sslContextFactory.buildServerContext()));
}
-
}
- if (ApplicationRegistry.getInstance().getConfiguration().getBoolean("broker.connector.protectio.enabled", false))
+ if (ApplicationRegistry.getInstance().getConfiguration().getProtectIOEnabled())
{
try
{
@@ -271,10 +275,10 @@ public class AMQPFastProtocolHandler extends IoHandlerAdapter
}
}
- protected boolean isSSLClient(ConnectorConfiguration connectionConfig,
+ protected boolean isSSLClient(ServerConfiguration connectionConfig,
IoSession protocolSession)
{
InetSocketAddress addr = (InetSocketAddress) protocolSession.getLocalAddress();
- return addr.getPort() == connectionConfig.sslPort;
+ return addr.getPort() == connectionConfig.getSSLPort();
}
}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/protocol/AMQProtocolSessionMBean.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/protocol/AMQProtocolSessionMBean.java
index bd072985c4..5dd3cc075a 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/protocol/AMQProtocolSessionMBean.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/protocol/AMQProtocolSessionMBean.java
@@ -37,7 +37,6 @@
*/
package org.apache.qpid.server.protocol;
-import java.security.Principal;
import java.util.Date;
import java.util.List;
@@ -58,7 +57,6 @@ import javax.management.openmbean.TabularDataSupport;
import javax.management.openmbean.TabularType;
import org.apache.qpid.AMQException;
-import org.apache.qpid.framing.AMQFrame;
import org.apache.qpid.framing.AMQShortString;
import org.apache.qpid.framing.ConnectionCloseBody;
import org.apache.qpid.framing.MethodRegistry;
@@ -93,7 +91,7 @@ public class AMQProtocolSessionMBean extends AMQManagedObject implements Managed
@MBeanConstructor("Creates an MBean exposing an AMQ Broker Connection")
public AMQProtocolSessionMBean(AMQMinaProtocolSession session) throws NotCompliantMBeanException, OpenDataException
{
- super(ManagedConnection.class, ManagedConnection.TYPE);
+ super(ManagedConnection.class, ManagedConnection.TYPE, ManagedConnection.VERSION);
_session = session;
String remote = getRemoteAddress();
remote = "anonymous".equals(remote) ? (remote + hashCode()) : remote;
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/protocol/HeartbeatConfig.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/protocol/HeartbeatConfig.java
deleted file mode 100644
index 310deaaf55..0000000000
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/protocol/HeartbeatConfig.java
+++ /dev/null
@@ -1,67 +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.server.protocol;
-
-import org.apache.qpid.configuration.Configured;
-import org.apache.qpid.server.registry.ApplicationRegistry;
-
-public class HeartbeatConfig
-{
- @Configured(path = "heartbeat.delay", defaultValue = "5")
- public int delay = 5;//in secs
- @Configured(path = "heartbeat.timeoutFactor", defaultValue = "2.0")
- public double timeoutFactor = 2;
-
- public double getTimeoutFactor()
- {
- return timeoutFactor;
- }
-
- public void setTimeoutFactor(double timeoutFactor)
- {
- this.timeoutFactor = timeoutFactor;
- }
-
- public int getDelay()
- {
- return delay;
- }
-
- public void setDelay(int delay)
- {
- this.delay = delay;
- }
-
- int getTimeout(int writeDelay)
- {
- return (int) (timeoutFactor * writeDelay);
- }
-
- public static HeartbeatConfig getInstance()
- {
- return ApplicationRegistry.getInstance().getConfiguredObject(HeartbeatConfig.class);
- }
-
- public String toString()
- {
- return "HeartBeatConfig{delay = " + delay + " timeoutFactor = " + timeoutFactor + "}";
- }
-}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/protocol/ManagedConnection.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/protocol/ManagedConnection.java
index e6e713ac6d..e75b09a0cb 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/protocol/ManagedConnection.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/protocol/ManagedConnection.java
@@ -41,6 +41,7 @@ import org.apache.qpid.server.management.MBeanOperationParameter;
public interface ManagedConnection
{
static final String TYPE = "Connection";
+ static final int VERSION = 1;
@MBeanAttribute(name = "ClientId", description = "Client Id")
String getClientId();
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/AMQMessage.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/AMQMessage.java
index 2bd6e612f8..8dac12fe24 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/AMQMessage.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/AMQMessage.java
@@ -60,30 +60,6 @@ public interface AMQMessage
//Check the status of this message
- /**
- * Called selectors to determin if the message has already been sent
- *
- * @return _deliveredToConsumer
- */
- boolean getDeliveredToConsumer();
-
- /**
- * Called to enforce the 'immediate' flag.
- *
- * @returns true if the message is marked for immediate delivery but has not been marked as delivered
- * to a consumer
- */
- boolean immediateAndNotDelivered();
-
- /**
- * Checks to see if the message has expired. If it has the message is dequeued.
- *
- * @return true if the message has expire
- *
- * @throws org.apache.qpid.AMQException
- */
- boolean expired() throws AMQException;
-
/** Is this a persistent message
*
* @return true if the message is persistent
@@ -91,13 +67,8 @@ public interface AMQMessage
boolean isPersistent();
- /**
- * Called when this message is delivered to a consumer. (used to implement the 'immediate' flag functionality).
- * And for selector efficiency.
- */
- void setDeliveredToConsumer();
+ boolean isImmediate();
- void setExpiration(long expiration);
void setClientIdentifier(AMQProtocolSession.ProtocolSessionIdentifier sessionIdentifier);
@@ -113,22 +84,16 @@ public interface AMQMessage
void addContentBodyFrame(StoreContext storeContext, ContentChunk contentChunk, boolean isLastContentBody)
throws AMQException;
+ void recoverFromMessageMetaData(MessageMetaData mmd);
+
+ void recoverContentBodyFrame(ContentChunk contentChunk, boolean isLastContentBody) throws AMQException;
- void removeMessage(StoreContext storeContext) throws AMQException;
String toString();
String debugIdentity();
- // Reference counting methods
-
- void decrementReference(StoreContext storeContext) throws MessageCleanupException;
-
- boolean incrementReference(int queueCount);
-
- boolean incrementReference();
-
- AMQMessage takeReference();
+ void setExpiration(long expiration);
- boolean isReferenced();
+ long getExpiration();
}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/AMQMessageHandle.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/AMQMessageHandle.java
deleted file mode 100644
index 93ac21fc7c..0000000000
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/AMQMessageHandle.java
+++ /dev/null
@@ -1,75 +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.server.queue;
-
-import org.apache.qpid.AMQException;
-import org.apache.qpid.framing.ContentHeaderBody;
-import org.apache.qpid.server.store.StoreContext;
-import org.apache.qpid.framing.abstraction.ContentChunk;
-import org.apache.qpid.framing.abstraction.MessagePublishInfo;
-
-/**
- * A pluggable way of getting message data. Implementations can provide intelligent caching for example or
- * even no caching at all to minimise the broker memory footprint.
- */
-public interface AMQMessageHandle
-{
- ContentHeaderBody getContentHeaderBody(StoreContext context) throws AMQException;
-
- /**
- *
- * @return the messageId for the message associated with this handle
- */
- Long getMessageId();
-
-
- /**
- * @return the number of body frames associated with this message
- */
- int getBodyCount(StoreContext context) throws AMQException;
-
- /**
- * @return the size of the body
- */
- long getBodySize(StoreContext context) throws AMQException;
-
- /**
- * Get a particular content body
- * @param index the index of the body to retrieve, must be between 0 and getBodyCount() - 1
- * @return a content body
- * @throws IllegalArgumentException if the index is invalid
- */
- ContentChunk getContentChunk(StoreContext context, int index) throws IllegalArgumentException, AMQException;
-
- void addContentBodyFrame(StoreContext storeContext, ContentChunk contentBody, boolean isLastContentBody) throws AMQException;
-
- MessagePublishInfo getMessagePublishInfo(StoreContext context) throws AMQException;
-
- boolean isPersistent();
-
- void setPublishAndContentHeaderBody(StoreContext storeContext, MessagePublishInfo messagePublishInfo,
- ContentHeaderBody contentHeaderBody)
- throws AMQException;
-
- void removeMessage(StoreContext storeContext) throws AMQException;
-
- long getArrivalTime();
-}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/AMQPriorityQueue.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/AMQPriorityQueue.java
index 34a70c6969..00dec57ed5 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/AMQPriorityQueue.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/AMQPriorityQueue.java
@@ -36,12 +36,12 @@ public class AMQPriorityQueue extends SimpleAMQQueue
int priorities)
throws AMQException
{
- super(name, durable, owner, autoDelete, virtualHost, new PriorityQueueList.Factory(priorities));
+ super(name, durable, owner, autoDelete, virtualHost, new PriorityQueueEntryList.Factory(priorities));
}
public int getPriorities()
{
- return ((PriorityQueueList) _entries).getPriorities();
+ return ((PriorityQueueEntryList) _entries).getPriorities();
}
@Override
@@ -68,4 +68,10 @@ public class AMQPriorityQueue extends SimpleAMQQueue
}
}
+ @Override
+ public String getType()
+ {
+ return getClass().getSimpleName() + "[" + getName() + "][Priorities:" + getPriorities() + "]";
+ }
+
}
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 2d4a9c4b40..43ec6c4d15 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
@@ -20,9 +20,10 @@
*/
package org.apache.qpid.server.queue;
-import org.apache.commons.configuration.Configuration;
import org.apache.qpid.server.management.Managable;
import org.apache.qpid.server.store.StoreContext;
+import org.apache.qpid.server.configuration.QueueConfiguration;
+import org.apache.qpid.server.configuration.ServerConfiguration;
import org.apache.qpid.server.exchange.Exchange;
import org.apache.qpid.server.virtualhost.VirtualHost;
import org.apache.qpid.server.subscription.Subscription;
@@ -67,6 +68,8 @@ public interface AMQQueue extends Managable, Comparable<AMQQueue>
boolean isEmpty();
+ boolean isFlowed();
+
int getMessageCount();
int getUndeliveredMessageCount();
@@ -80,25 +83,18 @@ public interface AMQQueue extends Managable, Comparable<AMQQueue>
boolean isDeleted();
-
int delete() throws AMQException;
-
QueueEntry enqueue(StoreContext storeContext, AMQMessage message) throws AMQException;
void requeue(StoreContext storeContext, QueueEntry entry) throws AMQException;
void dequeue(StoreContext storeContext, QueueEntry entry) throws FailedDequeueException;
-
-
boolean resend(final QueueEntry entry, final Subscription subscription) throws AMQException;
-
-
void addQueueDeleteTask(final Task task);
-
List<QueueEntry> getMessagesOnTheQueue();
List<QueueEntry> getMessagesOnTheQueue(long fromMessageId, long toMessageId);
@@ -117,7 +113,15 @@ public interface AMQQueue extends Managable, Comparable<AMQQueue>
void removeMessagesFromQueue(long fromMessageId, long toMessageId, StoreContext storeContext);
+ long getMemoryUsageMaximum();
+ void setMemoryUsageMaximum(long maximumMemoryUsage);
+
+ long getMemoryUsageMinimum();
+
+ void setMemoryUsageMinimum(long minimumMemoryUsage);
+
+ long getMemoryUsageCurrent();
long getMaximumMessageSize();
@@ -141,6 +145,8 @@ public interface AMQQueue extends Managable, Comparable<AMQQueue>
long getMinimumAlertRepeatGap();
+ void setMinimumAlertRepeatGap(long value);
+
void deleteMessageFromTop(StoreContext storeContext) throws AMQException;
@@ -162,7 +168,6 @@ public interface AMQQueue extends Managable, Comparable<AMQQueue>
void stop();
-
/**
* ExistingExclusiveSubscription signals a failure to create a subscription, because an exclusive subscription
* already exists.
@@ -210,6 +215,4 @@ public interface AMQQueue extends Managable, Comparable<AMQQueue>
{
public void doTask(AMQQueue queue) throws AMQException;
}
-
- void configure(Configuration virtualHostDefaultQueueConfiguration);
}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/AMQQueueFactory.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/AMQQueueFactory.java
index be8c19d18f..6ba22321f1 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/AMQQueueFactory.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/AMQQueueFactory.java
@@ -20,45 +20,49 @@
*/
package org.apache.qpid.server.queue;
-import org.apache.commons.configuration.Configuration;
+import org.apache.qpid.AMQException;
import org.apache.qpid.framing.AMQShortString;
import org.apache.qpid.framing.FieldTable;
-import org.apache.qpid.server.configuration.VirtualHostConfiguration;
+import org.apache.qpid.protocol.AMQConstant;
+import org.apache.qpid.server.configuration.QueueConfiguration;
import org.apache.qpid.server.virtualhost.VirtualHost;
-import org.apache.qpid.AMQException;
-
public class AMQQueueFactory
{
public static final AMQShortString X_QPID_PRIORITIES = new AMQShortString("x-qpid-priorities");
+ public static final AMQShortString QPID_MAX_COUNT = new AMQShortString("qpid.max_count");
+ public static final AMQShortString QPID_MAX_SIZE = new AMQShortString("qpid.max_size");
+ public static final AMQShortString QPID_POLICY_TYPE = new AMQShortString("qpid.policy_type");
+ public static final String QPID_FLOW_TO_DISK = "flow_to_disk";
public static AMQQueue createAMQQueueImpl(AMQShortString name,
- boolean durable,
- AMQShortString owner,
- boolean autoDelete,
- VirtualHost virtualHost, final FieldTable arguments)
-
- throws AMQException
- {
-
- return createAMQQueueImpl(name, durable, owner, autoDelete,
- virtualHost, arguments,
- VirtualHostConfiguration.getDefaultQueueConfiguration(virtualHost));
- }
-
- public static AMQQueue createAMQQueueImpl(AMQShortString name,
boolean durable,
AMQShortString owner,
boolean autoDelete,
- VirtualHost virtualHost, final FieldTable arguments,
- Configuration queueConfiguration)
+ VirtualHost virtualHost, final FieldTable arguments)
throws AMQException
{
- final int priorities = arguments == null ? 1 : arguments.containsKey(X_QPID_PRIORITIES) ? arguments.getInteger(X_QPID_PRIORITIES) : 1;
+ int priorities = 1;
+
+ if (arguments != null && arguments.containsKey(X_QPID_PRIORITIES))
+ {
+ Integer priority = arguments.getInteger(X_QPID_PRIORITIES);
+
+ if (priority != null)
+ {
+ priorities = priority.intValue();
+ }
+ else
+ {
+ throw new AMQException(AMQConstant.INVALID_ARGUMENT,
+ "Queue create request with non integer value for :" + X_QPID_PRIORITIES + "=" + arguments.get(X_QPID_PRIORITIES), null);
+ }
+
+ }
AMQQueue q = null;
- if(priorities > 1)
+ if (priorities > 1)
{
q = new AMQPriorityQueue(name, durable, owner, autoDelete, virtualHost, priorities);
}
@@ -66,13 +70,77 @@ public class AMQQueueFactory
{
q = new SimpleAMQQueue(name, durable, owner, autoDelete, virtualHost);
}
- if (q != null && queueConfiguration != null)
+
+ final String queuePolicyType = arguments == null ? null :
+ arguments.containsKey(QPID_POLICY_TYPE) ? arguments.getString(QPID_POLICY_TYPE) : null;
+
+ if (queuePolicyType != null)
{
- q.configure(queueConfiguration);
+ if (queuePolicyType.equals(QPID_FLOW_TO_DISK))
+ {
+ if (arguments.containsKey(QPID_MAX_SIZE))
+ {
+
+ final long queueSize = arguments.getInteger(QPID_MAX_SIZE);
+
+ if (queueSize < 0)
+ {
+ throw new AMQException(AMQConstant.INVALID_ARGUMENT,
+ "Queue create request with negative size:" + queueSize, null);
+ }
+
+ q.setMemoryUsageMaximum(queueSize);
+ }
+ else
+ {
+ throw new AMQException(AMQConstant.INVALID_ARGUMENT,
+ "Queue create request with no qpid.max_size value,", null);
+ }
+ }
+ else
+ {
+ throw new AMQException(AMQConstant.NOT_IMPLEMENTED,
+ "Queue create request with unknown Policy Type:" + queuePolicyType, null);
+ }
+
}
//Register the new queue
virtualHost.getQueueRegistry().registerQueue(q);
return q;
}
+
+ public static AMQQueue createAMQQueueImpl(QueueConfiguration config, VirtualHost host) throws AMQException
+ {
+ AMQShortString queueName = new AMQShortString(config.getName());
+
+ boolean durable = config.getDurable();
+ boolean autodelete = config.getAutoDelete();
+ AMQShortString owner = (config.getOwner() != null) ? new AMQShortString(config.getOwner()) : null;
+ FieldTable arguments = null;
+ boolean priority = config.getPriority();
+ int priorities = config.getPriorities();
+ if (priority || priorities > 0)
+ {
+ if (arguments == null)
+ {
+ arguments = new FieldTable();
+ }
+ if (priorities < 0)
+ {
+ priorities = 10;
+ }
+ arguments.put(new AMQShortString("x-qpid-priorities"), priorities);
+ }
+
+ AMQQueue q = createAMQQueueImpl(queueName, durable, owner, autodelete, host, arguments);
+ q.setMaximumMessageAge(config.getMaximumMessageAge());
+ q.setMaximumQueueDepth(config.getMaximumQueueDepth());
+ q.setMaximumMessageSize(config.getMaximumMessageSize());
+ q.setMaximumMessageCount(config.getMaximumMessageCount());
+ q.setMinimumAlertRepeatGap(config.getMinimumAlertRepeatGap());
+ q.setMemoryUsageMaximum(config.getMemoryUsageMaximum());
+ q.setMemoryUsageMinimum(config.getMemoryUsageMinimum());
+ return q;
+ }
}
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 a08719875d..2ff54fb748 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
@@ -100,7 +100,7 @@ public class AMQQueueMBean extends AMQManagedObject implements ManagedQueue, Que
@MBeanConstructor("Creates an MBean exposing an AMQQueue")
public AMQQueueMBean(AMQQueue queue) throws JMException
{
- super(ManagedQueue.class, ManagedQueue.TYPE);
+ super(ManagedQueue.class, ManagedQueue.TYPE, ManagedQueue.VERSION);
_queue = queue;
_queueName = jmxEncode(new StringBuffer(queue.getName()), 0).toString();
}
@@ -221,11 +221,12 @@ public class AMQQueueMBean extends AMQManagedObject implements ManagedQueue, Que
_queue.setMaximumMessageCount(value);
}
+ /**
+ * returns the maximum total size of messages(bytes) in the queue.
+ */
public Long getMaximumQueueDepth()
{
- long queueDepthInBytes = _queue.getMaximumQueueDepth();
-
- return queueDepthInBytes >> 10;
+ return _queue.getMaximumQueueDepth();
}
public void setMaximumQueueDepth(Long value)
@@ -233,20 +234,49 @@ public class AMQQueueMBean extends AMQManagedObject implements ManagedQueue, Que
_queue.setMaximumQueueDepth(value);
}
+ public Long getMemoryUsageMaximum()
+ {
+ return _queue.getMemoryUsageMaximum();
+ }
+
+ public void setMemoryUsageMaximum(Long maximumMemoryUsage)
+ {
+ _queue.setMemoryUsageMaximum(maximumMemoryUsage);
+ }
+
+ public Long getMemoryUsageMinimum()
+ {
+ return _queue.getMemoryUsageMinimum();
+ }
+
+ public void setMemoryUsageMinimum(Long minimumMemoryUsage)
+ {
+ _queue.setMemoryUsageMinimum(minimumMemoryUsage);
+ }
+
+ public Long getMemoryUsageCurrent()
+ {
+ return _queue.getMemoryUsageCurrent();
+ }
+
+ public boolean isFlowed()
+ {
+ return _queue.isFlowed();
+ }
+
/**
- * returns the size of messages(KB) in the queue.
+ * returns the total size of messages(bytes) in the queue.
*/
public Long getQueueDepth() throws JMException
{
- long queueBytesSize = _queue.getQueueDepth();
-
- return queueBytesSize >> 10;
+ return _queue.getQueueDepth();
}
/**
* Checks if there is any notification to be send to the listeners
+ * @param queueEntry
*/
- public void checkForNotification(AMQMessage msg) throws AMQException
+ public void checkForNotification(QueueEntry queueEntry) throws AMQException
{
final Set<NotificationCheck> notificationChecks = _queue.getNotificationChecks();
@@ -260,7 +290,7 @@ public class AMQQueueMBean extends AMQManagedObject implements ManagedQueue, Que
{
if (check.isMessageSpecific() || (_lastNotificationTimes[check.ordinal()] < thresholdTime))
{
- if (check.notifyIfNecessary(msg, _queue, this))
+ if (check.notifyIfNecessary(queueEntry, _queue, this))
{
_lastNotificationTimes[check.ordinal()] = currentTime;
}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/FileQueueBackingStore.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/FileQueueBackingStore.java
new file mode 100644
index 0000000000..a22eea2b5e
--- /dev/null
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/FileQueueBackingStore.java
@@ -0,0 +1,380 @@
+/*
+ *
+ * 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.log4j.Logger;
+import org.apache.mina.common.ByteBuffer;
+import org.apache.qpid.AMQException;
+import org.apache.qpid.framing.AMQShortString;
+import org.apache.qpid.framing.BasicContentHeaderProperties;
+import org.apache.qpid.framing.ContentHeaderBody;
+import org.apache.qpid.framing.abstraction.ContentChunk;
+import org.apache.qpid.framing.abstraction.MessagePublishInfo;
+import org.apache.qpid.util.FileUtils;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+
+public class FileQueueBackingStore implements QueueBackingStore
+{
+ private static final Logger _log = Logger.getLogger(FileQueueBackingStore.class);
+
+ private String _flowToDiskLocation;
+
+ public FileQueueBackingStore(String location)
+ {
+ _flowToDiskLocation = location;
+ }
+
+ public AMQMessage load(Long messageId)
+ {
+ _log.info("Loading Message (ID:" + messageId + ")");
+
+ MessageMetaData mmd;
+
+ File handle = getFileHandle(messageId);
+
+ ObjectInputStream input = null;
+
+ Exception error = null;
+ try
+ {
+ input = new ObjectInputStream(new FileInputStream(handle));
+
+ long arrivaltime = input.readLong();
+
+ final AMQShortString exchange = new AMQShortString(input.readUTF());
+ final AMQShortString routingKey = new AMQShortString(input.readUTF());
+ final boolean mandatory = input.readBoolean();
+ final boolean immediate = input.readBoolean();
+
+ int bodySize = input.readInt();
+ byte[] underlying = new byte[bodySize];
+
+ input.readFully(underlying, 0, bodySize);
+
+ ByteBuffer buf = ByteBuffer.wrap(underlying);
+
+ ContentHeaderBody chb = ContentHeaderBody.createFromBuffer(buf, bodySize);
+
+ int chunkCount = input.readInt();
+
+ // There are WAY to many annonymous MPIs in the code this should be made concrete.
+ MessagePublishInfo info = new MessagePublishInfo()
+ {
+
+ public AMQShortString getExchange()
+ {
+ return exchange;
+ }
+
+ public void setExchange(AMQShortString exchange)
+ {
+
+ }
+
+ public boolean isImmediate()
+ {
+ return immediate;
+ }
+
+ public boolean isMandatory()
+ {
+ return mandatory;
+ }
+
+ public AMQShortString getRoutingKey()
+ {
+ return routingKey;
+ }
+ };
+
+ mmd = new MessageMetaData(info, chb, chunkCount);
+ mmd.setArrivalTime(arrivaltime);
+
+ AMQMessage message;
+ if (((BasicContentHeaderProperties) chb.properties).getDeliveryMode() == 2)
+ {
+ message = new PersistentAMQMessage(messageId, null);
+ }
+ else
+ {
+ message = new TransientAMQMessage(messageId);
+ }
+
+ message.recoverFromMessageMetaData(mmd);
+
+ for (int chunk = 0; chunk < chunkCount; chunk++)
+ {
+ int length = input.readInt();
+
+ byte[] data = new byte[length];
+
+ input.readFully(data, 0, length);
+
+ try
+ {
+ message.recoverContentBodyFrame(new RecoverDataBuffer(length, data), (chunk + 1 == chunkCount));
+ }
+ catch (AMQException e)
+ {
+ //ignore as this will not occur.
+ // It is thrown by the _transactionLog method in load on PersistentAMQMessage
+ // but we have created the message with a null log and will never call that method.
+ }
+ }
+
+ return message;
+ }
+ catch (Exception e)
+ {
+ error = e;
+ }
+ finally
+ {
+ try
+ {
+ if (input != null)
+ {
+ input.close();
+ }
+ }
+ catch (IOException e)
+ {
+ _log.info("Unable to close input on message(" + messageId + ") recovery due to:" + e.getMessage());
+ }
+ }
+
+ throw new UnableToRecoverMessageException(error);
+ }
+
+ /**
+ * Thread safety is ensured here by synchronizing on the message object.
+ *
+ * This is safe as load() calls will fail until the first thread through here has created the file on disk
+ * and fully written the content.
+ *
+ * After this point new AMQMessages can exist that reference the same data thus breaking the synchronisation.
+ *
+ * Thread safety is maintained here as the existence of the file is checked allowing then subsequent unload() calls
+ * to skip the writing.
+ *
+ * Multiple unload() calls will initially be blocked using the synchronization until the data exists on disk thus
+ * safely allowing any reference to the message to be cleared prompting a load call.
+ *
+ * @param message the message to unload
+ * @throws UnableToFlowMessageException
+ */
+ public void unload(AMQMessage message) throws UnableToFlowMessageException
+ {
+ //Synchorize on the message to ensure that one only thread can unload at a time.
+ // If a second unload is attempted then it will block until the unload has completed.
+ synchronized (message)
+ {
+ long messageId = message.getMessageId();
+
+ File handle = getFileHandle(messageId);
+
+ //If we have written the data once then we don't need to do it again.
+ if (handle.exists())
+ {
+ if (_log.isDebugEnabled())
+ {
+ _log.debug("Message(ID:" + messageId + ") already unloaded.");
+ }
+ return;
+ }
+
+ if (_log.isInfoEnabled())
+ {
+ _log.info("Unloading Message (ID:" + messageId + ")");
+ }
+
+ ObjectOutputStream writer = null;
+ Exception error = null;
+
+ try
+ {
+ writer = new ObjectOutputStream(new FileOutputStream(handle));
+
+ writer.writeLong(message.getArrivalTime());
+
+ MessagePublishInfo mpi = message.getMessagePublishInfo();
+ writer.writeUTF(String.valueOf(mpi.getExchange()));
+ writer.writeUTF(String.valueOf(mpi.getRoutingKey()));
+ writer.writeBoolean(mpi.isMandatory());
+ writer.writeBoolean(mpi.isImmediate());
+ ContentHeaderBody chb = message.getContentHeaderBody();
+
+ // write out the content header body
+ final int bodySize = chb.getSize();
+ byte[] underlying = new byte[bodySize];
+ ByteBuffer buf = ByteBuffer.wrap(underlying);
+ chb.writePayload(buf);
+
+ writer.writeInt(bodySize);
+ writer.write(underlying, 0, bodySize);
+
+ int bodyCount = message.getBodyCount();
+ writer.writeInt(bodyCount);
+
+ //WriteContentBody
+ for (int index = 0; index < bodyCount; index++)
+ {
+ ContentChunk chunk = message.getContentChunk(index);
+ int length = chunk.getSize();
+
+ byte[] chunk_underlying = new byte[length];
+
+ ByteBuffer chunk_buf = chunk.getData();
+
+ chunk_buf.duplicate().rewind().get(chunk_underlying);
+
+ writer.writeInt(length);
+ writer.write(chunk_underlying, 0, length);
+ }
+ }
+ catch (FileNotFoundException e)
+ {
+ error = e;
+ }
+ catch (IOException e)
+ {
+ error = e;
+ }
+ finally
+ {
+ // In a FileNotFound situation writer will be null.
+ if (writer != null)
+ {
+ try
+ {
+ writer.flush();
+ writer.close();
+ }
+ catch (IOException e)
+ {
+ error = e;
+ }
+ }
+ }
+
+ if (error != null)
+ {
+ _log.error("Unable to unload message(" + messageId + ") to disk, restoring state.");
+ handle.delete();
+ throw new UnableToFlowMessageException(messageId, error);
+ }
+ }
+ }
+
+ /**
+ * Use the messageId to calculate the file path on disk.
+ *
+ * Current implementation will give us 256 bins.
+ * Therefore the maximum messages that can be flowed before error/platform is:
+ * ext3 : 256 bins * 32000 = 8192000
+ * FAT32 : 256 bins * 65534 = 16776704
+ * Other FS have much greater limits than we need to worry about.
+ *
+ * @param messageId the Message we need a file Handle for.
+ *
+ * @return the File handle
+ */
+ private File getFileHandle(long messageId)
+ {
+ // grab the 8 LSB to give us 256 bins
+ long bin = messageId & 0xFFL;
+
+ String bin_path = _flowToDiskLocation + File.separator + bin;
+ File bin_dir = new File(bin_path);
+
+ if (!bin_dir.exists())
+ {
+ bin_dir.mkdirs();
+ }
+
+ String id = bin_path + File.separator + messageId;
+
+ return new File(id);
+ }
+
+ public void delete(Long messageId)
+ {
+ File handle = getFileHandle(messageId);
+
+ if (handle.exists())
+ {
+ if (_log.isInfoEnabled())
+ {
+ _log.info("Message(" + messageId + ") delete flowToDisk.");
+ }
+ if (!handle.delete())
+ {
+ throw new RuntimeException("Unable to delete flowToDisk data");
+ }
+ }
+ }
+
+ public void close()
+ {
+ _log.info("Closing Backing store at:" + _flowToDiskLocation);
+ if (!FileUtils.delete(new File(_flowToDiskLocation), true))
+ {
+ _log.error("Unable to fully delete backing store location");
+ }
+ }
+
+ private class RecoverDataBuffer implements ContentChunk
+ {
+ private int _length;
+ private ByteBuffer _dataBuffer;
+
+ public RecoverDataBuffer(int length, byte[] data)
+ {
+ _length = length;
+ _dataBuffer = ByteBuffer.wrap(data);
+ }
+
+ public int getSize()
+ {
+ return _length;
+ }
+
+ public ByteBuffer getData()
+ {
+ return _dataBuffer;
+ }
+
+ public void reduceToFit()
+ {
+
+ }
+
+ }
+
+}
+
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/FileQueueBackingStoreFactory.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/FileQueueBackingStoreFactory.java
new file mode 100644
index 0000000000..21073c22ae
--- /dev/null
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/FileQueueBackingStoreFactory.java
@@ -0,0 +1,166 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.qpid.server.queue;
+
+import org.apache.commons.configuration.ConfigurationException;
+import org.apache.log4j.Logger;
+import org.apache.qpid.server.configuration.VirtualHostConfiguration;
+import org.apache.qpid.server.virtualhost.VirtualHost;
+import org.apache.qpid.util.FileUtils;
+
+import java.io.File;
+
+public class FileQueueBackingStoreFactory implements QueueBackingStoreFactory
+{
+ private static final Logger _log = Logger.getLogger(FileQueueBackingStoreFactory.class);
+
+ private String _flowToDiskLocation;
+ private static final String QUEUE_BACKING_DIR = "queueBacking";
+
+ public void configure(VirtualHost virtualHost, VirtualHostConfiguration config) throws ConfigurationException
+ {
+ setFlowToDisk(virtualHost.getName(), config.getFlowToDiskLocation());
+ }
+
+ private void setFlowToDisk(String vHostName, String location) throws ConfigurationException
+ {
+ if (vHostName == null)
+ {
+ throw new ConfigurationException("Unable to setup to Flow to Disk as Virtualhost name was not specified");
+ }
+
+ if (location == null)
+ {
+ throw new ConfigurationException("Unable to setup to Flow to Disk as location was not specified.");
+ }
+
+ _flowToDiskLocation = location;
+
+ _flowToDiskLocation += File.separator + QUEUE_BACKING_DIR + File.separator + vHostName;
+
+ //Check the location we will create QUEUE_BACKING_DIR in.
+ File root = new File(location);
+ if (!root.exists())
+ {
+ throw new ConfigurationException("Specified Flow to Disk root does not exist:" + root.getAbsolutePath());
+ }
+ else
+ {
+
+ if (root.isFile())
+ {
+ throw new ConfigurationException("Unable to create Temporary Flow to Disk store as specified root is a file:" +
+ root.getAbsolutePath());
+ }
+
+ if (!root.canWrite())
+ {
+ throw new ConfigurationException("Unable to create Temporary Flow to Disk store. Unable to write to specified root:" +
+ root.getAbsolutePath());
+ }
+
+ }
+
+ // if we don't mark QUEUE_BAKCING_DIR as a deleteOnExit it will remain.
+ File backingDir = new File(location + File.separator + QUEUE_BACKING_DIR);
+ if (backingDir.exists())
+ {
+ if (!FileUtils.delete(backingDir, true))
+ {
+ throw new ConfigurationException("Unable to delete existing Flow to Disk root at:"
+ + backingDir.getAbsolutePath());
+ }
+
+ if (backingDir.isFile())
+ {
+ throw new ConfigurationException("Unable to create Temporary Flow to Disk root as specified location is a file:" +
+ backingDir.getAbsolutePath());
+ }
+ }
+
+ backingDir.deleteOnExit();
+ if (!backingDir.mkdirs())
+ {
+ throw new ConfigurationException("Unable to create Temporary Flow to Disk root:" + location + File.separator + QUEUE_BACKING_DIR);
+ }
+
+
+ File store = new File(_flowToDiskLocation);
+ if (store.exists())
+ {
+ if (!FileUtils.delete(store, true))
+ {
+ throw new ConfigurationException("Unable to delete existing Flow to Disk store at:"
+ + store.getAbsolutePath());
+ }
+
+ if (store.isFile())
+ {
+ throw new ConfigurationException("Unable to create Temporary Flow to Disk store as specified location is a file:" +
+ store.getAbsolutePath());
+ }
+
+ }
+
+ _log.info("Creating Flow to Disk Store : " + store.getAbsolutePath());
+ store.deleteOnExit();
+ if (!store.mkdir())
+ {
+ throw new ConfigurationException("Unable to create Temporary Flow to Disk store:" + store.getAbsolutePath());
+ }
+ }
+
+ public QueueBackingStore createBacking(AMQQueue queue)
+ {
+ return new FileQueueBackingStore(createStore(queue.getName().toString()));
+ }
+
+ private String createStore(String name)
+ {
+ return createStore(name, 0);
+ }
+
+ private String createStore(String name, int index)
+ {
+
+ String store = _flowToDiskLocation + File.separator + name;
+ if (index > 0)
+ {
+ store += "-" + index;
+ }
+
+ //TODO ensure store is safe for the OS
+
+ File storeFile = new File(store);
+
+ if (storeFile.exists())
+ {
+ return createStore(name, index + 1);
+ }
+
+ storeFile.mkdirs();
+
+ storeFile.deleteOnExit();
+
+ return store;
+ }
+
+}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/FlowableBaseQueueEntryList.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/FlowableBaseQueueEntryList.java
new file mode 100644
index 0000000000..5e5901bcd7
--- /dev/null
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/FlowableBaseQueueEntryList.java
@@ -0,0 +1,485 @@
+/*
+ *
+ * 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.log4j.Logger;
+import org.apache.qpid.pool.ReferenceCountingExecutorService;
+import org.apache.qpid.server.virtualhost.VirtualHost;
+
+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;
+
+/** This is an abstract base class to handle */
+public abstract class FlowableBaseQueueEntryList implements QueueEntryList
+{
+ protected static final Logger _log = Logger.getLogger(FlowableBaseQueueEntryList.class);
+
+ private final AtomicInteger _atomicQueueCount = new AtomicInteger(0);
+ private final AtomicLong _atomicQueueSize = new AtomicLong(0L);
+ protected final AtomicLong _atomicQueueInMemory = new AtomicLong(0L);
+ /** The maximum amount of memory that is allocated to this queue. Beyond this the queue will flow to disk. */
+
+ protected long _memoryUsageMaximum = -1L;
+
+ /** The minimum amount of memory that is allocated to this queue. If the queueDepth hits this level then more flowed data can be read in. */
+ protected long _memoryUsageMinimum = 0;
+ private volatile AtomicBoolean _flowed;
+ private QueueBackingStore _backingStore;
+ protected AMQQueue _queue;
+ private Executor _inhaler;
+ private Executor _purger;
+ private AtomicBoolean _stopped;
+ private AtomicReference<MessageInhaler> _asynchronousInhaler = new AtomicReference(null);
+ protected boolean _disabled;
+ private AtomicReference<MessagePurger> _asynchronousPurger = new AtomicReference(null);
+ private static final int BATCH_PROCESS_COUNT = 100;
+
+ FlowableBaseQueueEntryList(AMQQueue queue)
+ {
+ _queue = queue;
+ _flowed = new AtomicBoolean(false);
+ VirtualHost vhost = queue.getVirtualHost();
+ if (vhost != null)
+ {
+ _backingStore = vhost.getQueueBackingStoreFactory().createBacking(queue);
+ }
+
+ _stopped = new AtomicBoolean(false);
+ _inhaler = ReferenceCountingExecutorService.getInstance().acquireExecutorService();
+ _purger = ReferenceCountingExecutorService.getInstance().acquireExecutorService();
+ _disabled = true;
+ }
+
+ public void setFlowed(boolean flowed)
+ {
+ if (_flowed.get() != flowed)
+ {
+ _log.warn("Marking Queue(" + _queue.getName() + ") as flowed (" + flowed + ")");
+ _flowed.set(flowed);
+ }
+ }
+
+ protected void showUsage()
+ {
+ showUsage("");
+ }
+
+ protected void showUsage(String prefix)
+ {
+ if (_log.isDebugEnabled())
+ {
+ _log.debug(prefix + " Queue(" + _queue + ":" + _queue.getName() + ") usage:" + memoryUsed()
+ + "/" + getMemoryUsageMinimum() + "<>" + getMemoryUsageMaximum()
+ + "/" + dataSize());
+ }
+ }
+
+ public boolean isFlowed()
+ {
+ return _flowed.get();
+ }
+
+ public int size()
+ {
+ return _atomicQueueCount.get();
+ }
+
+ public long dataSize()
+ {
+ return _atomicQueueSize.get();
+ }
+
+ public long memoryUsed()
+ {
+ return _atomicQueueInMemory.get();
+ }
+
+ public void setMemoryUsageMaximum(long maximumMemoryUsage)
+ {
+ _memoryUsageMaximum = maximumMemoryUsage;
+
+ if (maximumMemoryUsage >= 0)
+ {
+ _disabled = false;
+ }
+
+ // Don't attempt to start the inhaler/purger unless we have a minimum value specified.
+ if (_memoryUsageMaximum >= 0)
+ {
+ setMemoryUsageMinimum(_memoryUsageMaximum / 2);
+
+ // if we have now have to much memory in use we need to purge.
+ if (_memoryUsageMaximum < _atomicQueueInMemory.get())
+ {
+ setFlowed(true);
+ startPurger();
+ }
+ }
+ else
+ {
+ if (_log.isInfoEnabled())
+ {
+ _log.info("Disabling Flow to Disk for queue:" + _queue.getName());
+ }
+ _disabled = true;
+ }
+ }
+
+ public long getMemoryUsageMaximum()
+ {
+ return _memoryUsageMaximum;
+ }
+
+ public void setMemoryUsageMinimum(long minimumMemoryUsage)
+ {
+ _memoryUsageMinimum = minimumMemoryUsage;
+
+ // Don't attempt to start the inhaler unless we have a minimum value specified.
+ if (_memoryUsageMinimum > 0)
+ {
+ checkAndStartInhaler();
+ }
+ }
+
+ private void checkAndStartInhaler()
+ {
+ // If we've increased the minimum memory above what we have in memory then
+ // we need to inhale more if there is more
+ if (!_disabled && _atomicQueueInMemory.get() < _memoryUsageMinimum && _atomicQueueSize.get() > 0)
+ {
+ startInhaler();
+ }
+ }
+
+ private void startInhaler()
+ {
+ MessageInhaler inhaler = new MessageInhaler();
+
+ if (_asynchronousInhaler.compareAndSet(null, inhaler))
+ {
+ _inhaler.execute(inhaler);
+ }
+ }
+
+ private void startPurger()
+ {
+ MessagePurger purger = new MessagePurger();
+
+ if (_asynchronousPurger.compareAndSet(null, purger))
+ {
+ _purger.execute(purger);
+ }
+ }
+
+ public long getMemoryUsageMinimum()
+ {
+ return _memoryUsageMinimum;
+ }
+
+ /**
+ * Only to be called by the QueueEntry
+ *
+ * @param queueEntry the entry to unload
+ */
+ public void entryUnloadedUpdateMemory(QueueEntry queueEntry)
+ {
+ if (!_disabled && _atomicQueueInMemory.addAndGet(-queueEntry.getSize()) < 0)
+ {
+ _log.error("InMemory Count just went below 0:" + queueEntry.debugIdentity());
+ }
+
+ checkAndStartInhaler();
+ }
+
+ /**
+ * Only to be called from the QueueEntry
+ *
+ * @param queueEntry the entry to load
+ */
+ public void entryLoadedUpdateMemory(QueueEntry queueEntry)
+ {
+ if (!_disabled && _atomicQueueInMemory.addAndGet(queueEntry.getSize()) > _memoryUsageMaximum)
+ {
+ _log.error("Loaded to much data!:" + _atomicQueueInMemory.get() + "/" + _memoryUsageMaximum);
+ setFlowed(true);
+ startPurger();
+ }
+ }
+
+ public void stop()
+ {
+ if (!_stopped.getAndSet(true))
+ {
+ // The SimpleAMQQueue keeps running when stopped so we should just release the services
+ // rather than actively shutdown our threads.
+ //Shutdown thread for inhaler.
+ ReferenceCountingExecutorService.getInstance().releaseExecutorService();
+ ReferenceCountingExecutorService.getInstance().releaseExecutorService();
+
+ _backingStore.close();
+ }
+ }
+
+ protected void incrementCounters(final QueueEntryImpl queueEntry)
+ {
+ _atomicQueueCount.incrementAndGet();
+ _atomicQueueSize.addAndGet(queueEntry.getSize());
+ long inUseMemory = _atomicQueueInMemory.addAndGet(queueEntry.getSize());
+
+ if (!_disabled && inUseMemory > _memoryUsageMaximum)
+ {
+ setFlowed(true);
+ queueEntry.unload();
+ }
+ }
+
+ protected void dequeued(QueueEntryImpl queueEntry)
+ {
+ _atomicQueueCount.decrementAndGet();
+ _atomicQueueSize.addAndGet(-queueEntry.getSize());
+ if (!queueEntry.isFlowed())
+ {
+ if (_atomicQueueInMemory.addAndGet(-queueEntry.getSize()) < 0)
+ {
+ _log.error("InMemory Count just went below 0 on dequeue.");
+ }
+ }
+ }
+
+ public QueueBackingStore getBackingStore()
+ {
+ return _backingStore;
+ }
+
+ private class MessageInhaler implements Runnable
+ {
+ public void run()
+ {
+ String threadName = Thread.currentThread().getName();
+ Thread.currentThread().setName("Inhaler-" + _queue.getVirtualHost().getName() + "-" + _queue.getName());
+ try
+ {
+ inhaleList(this);
+ }
+ finally
+ {
+ Thread.currentThread().setName(threadName);
+ }
+ }
+ }
+
+ private void inhaleList(MessageInhaler messageInhaler)
+ {
+ if (_log.isInfoEnabled())
+ {
+ _log.info("Inhaler Running:" + _queue.getName());
+ showUsage("Inhaler Running:" + _queue.getName());
+ }
+ // If in memory count is at or over max then we can't inhale
+ if (_atomicQueueInMemory.get() >= _memoryUsageMaximum)
+ {
+ if (_log.isDebugEnabled())
+ {
+ _log.debug("Unable to start inhaling as we are already over quota:" +
+ _atomicQueueInMemory.get() + ">=" + _memoryUsageMaximum);
+ }
+ return;
+ }
+
+ _asynchronousInhaler.compareAndSet(messageInhaler, null);
+ int inhaled = 1;
+
+ while ((_atomicQueueInMemory.get() < _memoryUsageMaximum) // we havn't filled our max memory
+ && (_atomicQueueInMemory.get() < _atomicQueueSize.get()) // we haven't loaded all that is available
+ && (inhaled < BATCH_PROCESS_COUNT) // limit the number of runs we do
+ && (inhaled > 0) // ensure we could inhale something
+ && _asynchronousInhaler.compareAndSet(null, messageInhaler)) // Ensure we are the running inhaler
+ {
+ inhaled = 0;
+ QueueEntryIterator iterator = iterator();
+
+ // If the inhaler is running and delivery rate picks up ensure that we just don't chase the delivery thread.
+ while ((_atomicQueueInMemory.get() < _memoryUsageMaximum)
+ && !iterator.getNode().isAvailable() && iterator.advance())
+ {
+ //Find first AVAILABLE node
+ }
+
+ // Because the above loop checks then moves on to the next entry a check for atTail will return true but
+ // we won't have checked the last entry to see if we can load it. So create atEndofList and update it based
+ // on the return from advance() which returns true if it can advance.
+ boolean atEndofList = false;
+ while ((_atomicQueueInMemory.get() < _memoryUsageMaximum) // we havn't filled our max memory
+ && (inhaled < BATCH_PROCESS_COUNT) // limit the number of runs we do
+ && !atEndofList) // We have reached end of list QueueEntries
+ {
+ QueueEntry entry = iterator.getNode();
+
+ if (entry.isAvailable() && entry.isFlowed())
+ {
+ if (_atomicQueueInMemory.get() + entry.getSize() > _memoryUsageMaximum)
+ {
+ // We don't have space for this message so we need to stop inhaling.
+ if (_log.isDebugEnabled())
+ {
+ _log.debug("Entry won't fit in memory stopping inhaler:" + entry.debugIdentity());
+ }
+ inhaled = BATCH_PROCESS_COUNT;
+ }
+ else
+ {
+ entry.load();
+ inhaled++;
+ }
+ }
+
+ atEndofList = !iterator.advance();
+ }
+
+ if (iterator.atTail())
+ {
+ setFlowed(false);
+ }
+
+ _asynchronousInhaler.set(null);
+ }
+
+ if (_log.isInfoEnabled())
+ {
+ _log.info("Inhaler Stopping:" + _queue.getName());
+ showUsage("Inhaler Stopping:" + _queue.getName());
+ }
+
+ //If we have become flowed or have more capacity since we stopped then schedule the thread to run again.
+ if (_flowed.get() && _atomicQueueInMemory.get() < _memoryUsageMaximum)
+ {
+ if (_log.isInfoEnabled())
+ {
+ _log.info("Rescheduling Inhaler:" + _queue.getName());
+ }
+ _inhaler.execute(messageInhaler);
+ }
+
+ }
+
+ private class MessagePurger implements Runnable
+ {
+ public void run()
+ {
+ String threadName = Thread.currentThread().getName();
+ Thread.currentThread().setName("Purger-" + _queue.getVirtualHost().getName() + "-" + _queue.getName());
+ try
+ {
+ purgeList(this);
+ }
+ finally
+ {
+ Thread.currentThread().setName(threadName);
+ }
+ }
+ }
+
+ private void purgeList(MessagePurger messagePurger)
+ {
+ // If in memory count is at or over max then we can't inhale
+ if (_atomicQueueInMemory.get() <= _memoryUsageMinimum)
+ {
+ if (_log.isDebugEnabled())
+ {
+ _log.debug("Unable to start purging as we are already below our minimum cache level:" +
+ _atomicQueueInMemory.get() + "<=" + _memoryUsageMinimum);
+ }
+ return;
+ }
+
+ if (_log.isInfoEnabled())
+ {
+ _log.info("Purger Running:" + _queue.getName());
+ showUsage("Purger Running:" + _queue.getName());
+ }
+
+ _asynchronousPurger.compareAndSet(messagePurger, null);
+ int purged = 0;
+
+ while ((_atomicQueueInMemory.get() > _memoryUsageMinimum)
+ && purged < BATCH_PROCESS_COUNT
+ && _asynchronousPurger.compareAndSet(null, messagePurger))
+ {
+ QueueEntryIterator iterator = iterator();
+
+ //There are potentially AQUIRED messages that can be purged but we can't purge the last AQUIRED message
+ // as it may have just become AQUIRED and not yet delivered.
+
+ //To be safe only purge available messages. This should be fine as long as we have a small prefetch.
+ while (!iterator.getNode().isAvailable() && iterator.advance())
+ {
+ //Find first AVAILABLE node
+ }
+
+ // Count up the memory usage to find our minimum point
+ long memoryUsage = 0;
+ boolean atTail = false;
+ while ((memoryUsage < _memoryUsageMaximum) && !atTail)
+ {
+ QueueEntry entry = iterator.getNode();
+
+ if (entry.isAvailable() && !entry.isFlowed())
+ {
+ memoryUsage += entry.getSize();
+ }
+
+ atTail = !iterator.advance();
+ }
+
+ //Purge remainging mesages on queue
+ while (!atTail && (purged < BATCH_PROCESS_COUNT))
+ {
+ QueueEntry entry = iterator.getNode();
+
+ if (entry.isAvailable() && !entry.isFlowed())
+ {
+ entry.unload();
+ purged++;
+ }
+
+ atTail = !iterator.advance();
+ }
+
+ _asynchronousPurger.set(null);
+ }
+
+ if (_log.isInfoEnabled())
+ {
+ _log.info("Purger Stopping:" + _queue.getName());
+ showUsage("Purger Stopping:" + _queue.getName());
+ }
+
+ //If we are still flowed and are over the minimum value then schedule to run again.
+ if (_flowed.get() && _atomicQueueInMemory.get() > _memoryUsageMinimum)
+ {
+ _log.info("Rescheduling Purger:" + _queue.getName());
+ _purger.execute(messagePurger);
+ }
+ }
+}
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 94580a00ac..5eafd281c0 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
@@ -43,7 +43,7 @@ public class IncomingMessage implements Filterable<RuntimeException>
private static final Logger _logger = Logger.getLogger(IncomingMessage.class);
private static final boolean SYNCHED_CLOCKS =
- ApplicationRegistry.getInstance().getConfiguration().getBoolean("advanced.synced-clocks", false);
+ ApplicationRegistry.getInstance().getConfiguration().getSynchedClocks();
private final MessagePublishInfo _messagePublishInfo;
private ContentHeaderBody _contentHeaderBody;
@@ -51,7 +51,7 @@ public class IncomingMessage implements Filterable<RuntimeException>
private final TransactionalContext _txnContext;
private static final boolean MSG_AUTH =
- ApplicationRegistry.getInstance().getConfiguration().getBoolean("security.msg-auth", false);
+ ApplicationRegistry.getInstance().getConfiguration().getMsgAuth();
/**
@@ -78,6 +78,10 @@ public class IncomingMessage implements Filterable<RuntimeException>
final AMQProtocolSession publisher,
TransactionLog messasgeStore)
{
+ if (publisher == null)
+ {
+ throw new NullPointerException("Message Publisher cannot be null");
+ }
_messagePublishInfo = info;
_txnContext = txnContext;
_publisher = publisher;
@@ -152,8 +156,7 @@ public class IncomingMessage implements Filterable<RuntimeException>
_logger.debug("Delivering message " + getMessageId() + " to " + _destinationQueues);
}
- try
- {
+
// first we allow the handle to know that the message has been fully received. This is useful if it is
// maintaining any calculated values based on content chunks
_message.setPublishAndContentHeaderBody(_txnContext.getStoreContext(), _messagePublishInfo, getContentHeaderBody());
@@ -192,7 +195,6 @@ public class IncomingMessage implements Filterable<RuntimeException>
{
int offset;
final int queueCount = _destinationQueues.size();
- _message.incrementReference(queueCount);
if(queueCount == 1)
{
offset = 0;
@@ -218,12 +220,8 @@ public class IncomingMessage implements Filterable<RuntimeException>
}
return _message;
- }
- finally
- {
- // Remove refence for routing process . Reference count should now == delivered queue count
- if(_message != null) _message.decrementReference(_txnContext.getStoreContext());
- }
+
+
}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/ManagedQueue.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/ManagedQueue.java
index 2bc94995e9..d91d45a446 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/ManagedQueue.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/ManagedQueue.java
@@ -41,6 +41,7 @@ import org.apache.qpid.server.management.MBeanOperationParameter;
public interface ManagedQueue
{
static final String TYPE = "Queue";
+ static final int VERSION = 2;
/**
* Returns the Name of the ManagedQueue.
@@ -71,7 +72,7 @@ public interface ManagedQueue
* @return
* @throws IOException
*/
- @MBeanAttribute(name="QueueDepth", description="Size of messages(KB) in the queue")
+ @MBeanAttribute(name="QueueDepth", description="The total size(Bytes) of messages in the queue")
Long getQueueDepth() throws IOException, JMException;
/**
@@ -115,22 +116,22 @@ public interface ManagedQueue
boolean isAutoDelete() throws IOException;
/**
- * Returns the maximum age of a message (expiration time)
+ * Returns the maximum age of a message (expiration time) in milliseconds
* @return the maximum age
* @throws IOException
*/
Long getMaximumMessageAge() throws IOException;
/**
- * Sets the maximum age of a message
+ * Sets the maximum age of a message in milliseconds
* @param age maximum age of message.
* @throws IOException
*/
- @MBeanAttribute(name="MaximumMessageAge", description="Threshold high value for message age on the broker")
+ @MBeanAttribute(name="MaximumMessageAge", description="Threshold high value(milliseconds) for message age")
void setMaximumMessageAge(Long age) throws IOException;
/**
- * Returns the maximum size of a message (in kbytes) allowed to be accepted by the
+ * Returns the maximum size of a message (in Bytes) allowed to be accepted by the
* ManagedQueue. This is useful in setting notifications or taking
* appropriate action, if the size of the message received is more than
* the allowed size.
@@ -141,12 +142,12 @@ public interface ManagedQueue
Long getMaximumMessageSize() throws IOException;
/**
- * Sets the maximum size of the message (in kbytes) that is allowed to be
+ * Sets the maximum size of the message (in Bytes) that is allowed to be
* accepted by the Queue.
* @param size maximum size of message.
* @throws IOException
*/
- @MBeanAttribute(name="MaximumMessageSize", description="Threshold high value(KB) for a message size")
+ @MBeanAttribute(name="MaximumMessageSize", description="Threshold high value(Bytes) for a message size")
void setMaximumMessageSize(Long size) throws IOException;
/**
@@ -180,9 +181,65 @@ public interface ManagedQueue
* @param value
* @throws IOException
*/
- @MBeanAttribute(name="MaximumQueueDepth", description="The threshold high value(KB) for Queue Depth")
+ @MBeanAttribute(name="MaximumQueueDepth", description="The threshold high value(Bytes) for Queue Depth")
void setMaximumQueueDepth(Long value) throws IOException;
+ /**
+ * View the limit on the memory that this queue will utilise.
+ *
+ * Used by Flow to Disk.
+ *
+ * @return The maximum memory(B) that the queue will occuy.
+ */
+ public Long getMemoryUsageMaximum();
+
+ /**
+ * Place a limit on the memory that this queue will utilise.
+ *
+ * Used by Flow to Disk
+ *
+ * @param maximumMemoryUsage The new maximum memory(B) to be used by this queue
+ */
+ @MBeanAttribute(name="MemoryUsageMaximum", description="The maximum memory(Bytes) that the queue will occupy.")
+ public void setMemoryUsageMaximum(Long maximumMemoryUsage);
+
+ /**
+ * View the minimum amount of memory that has been defined for this queue.
+ *
+ * Used by Flow to Disk
+ *
+ * @return The minimum amount of queue data(B) that the queue will attempt to keep in memory
+ */
+ public Long getMemoryUsageMinimum();
+
+ /**
+ * Set the minimum amount of memory that has been defined for this queue.
+ *
+ * Used by Flow to Disk
+ *
+ * @param minimumMemoryUsage The new minimum memory(B) level to be used by this queue
+ */
+ @MBeanAttribute(name="MemoryUsageMinimum", description="The minimum memory(Bytes) that the queue will occupy.")
+ public void setMemoryUsageMinimum(Long minimumMemoryUsage);
+
+ /**
+ * View the amount of memory(B) that this queue is using.
+ *
+ * @return The current memory(B) usage of this queue.
+ */
+ @MBeanAttribute(name="MemoryUsageCurrent", description="The current amount of memory(Bytes) used by this queue.")
+ public Long getMemoryUsageCurrent();
+
+ /**
+ * When a queue exceeds its MemoryUsageMaximum value then the Queue will start flowing to disk.
+ *
+ * This boolean is used to show that change in state.
+ *
+ * @return true if the Queue is currently flowing to disk
+ */
+ @MBeanAttribute(name="isFlowed", description="true if the queue is currently flowing to disk.")
+ public boolean isFlowed();
+
//********** Operations *****************//
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/MessageFactory.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/MessageFactory.java
index e5e0b6e312..9924733178 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/MessageFactory.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/MessageFactory.java
@@ -42,19 +42,19 @@ public class MessageFactory
_messageId = new AtomicLong(0L);
}
- public void start()
+ public void recoveryComplete()
{
_state = State.OPEN;
}
/**
- * Only used by test as test suite is run in a single VM we need to beable to re-enable recovery mode.
- */
- protected void enableRecover()
+ * Only to be used by tests as this will cause violate the principal that message IDs should not be reused.
+ */
+ public void reset()
{
_state = State.RECOVER;
+ _messageId = new AtomicLong(0L);
}
-
/**
* Normal message creation path
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/NotificationCheck.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/NotificationCheck.java
index e33b0c83c7..a83d661de2 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/NotificationCheck.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/NotificationCheck.java
@@ -20,14 +20,12 @@
*/
package org.apache.qpid.server.queue;
-import org.apache.qpid.AMQException;
-
public enum NotificationCheck
{
MESSAGE_COUNT_ALERT
{
- boolean notifyIfNecessary(AMQMessage msg, AMQQueue queue, QueueNotificationListener listener)
+ boolean notifyIfNecessary(QueueEntry queueEntry, AMQQueue queue, QueueNotificationListener listener)
{
int msgCount;
final long maximumMessageCount = queue.getMaximumMessageCount();
@@ -41,19 +39,19 @@ public enum NotificationCheck
},
MESSAGE_SIZE_ALERT(true)
{
- boolean notifyIfNecessary(AMQMessage msg, AMQQueue queue, QueueNotificationListener listener)
+ boolean notifyIfNecessary(QueueEntry queueEntry, AMQQueue queue, QueueNotificationListener listener)
{
final long maximumMessageSize = queue.getMaximumMessageSize();
if(maximumMessageSize != 0)
{
// Check for threshold message size
- long messageSize = (msg == null) ? 0 : msg.getContentHeaderBody().bodySize;
+ long messageSize = (queueEntry == null) ? 0 : queueEntry.getSize();
if (messageSize >= maximumMessageSize)
{
listener.notifyClients(this, queue, messageSize + "b : Maximum message size threshold (" +
maximumMessageSize + ") breached. [Message ID=" +
- (msg == null ? "null" : msg.getMessageId()) + "]");
+ (queueEntry == null ? "null" : queueEntry.getMessageId()) + "]");
return true;
}
}
@@ -63,7 +61,7 @@ public enum NotificationCheck
},
QUEUE_DEPTH_ALERT
{
- boolean notifyIfNecessary(AMQMessage msg, AMQQueue queue, QueueNotificationListener listener)
+ boolean notifyIfNecessary(QueueEntry queueEntry, AMQQueue queue, QueueNotificationListener listener)
{
// Check for threshold queue depth in bytes
final long maximumQueueDepth = queue.getMaximumQueueDepth();
@@ -84,7 +82,7 @@ public enum NotificationCheck
},
MESSAGE_AGE_ALERT
{
- boolean notifyIfNecessary(AMQMessage msg, AMQQueue queue, QueueNotificationListener listener)
+ boolean notifyIfNecessary(QueueEntry queueEntry, AMQQueue queue, QueueNotificationListener listener)
{
final long maxMessageAge = queue.getMaximumMessageAge();
@@ -126,6 +124,6 @@ public enum NotificationCheck
return _messageSpecific;
}
- abstract boolean notifyIfNecessary(AMQMessage msg, AMQQueue queue, QueueNotificationListener listener);
+ abstract boolean notifyIfNecessary(QueueEntry queueEntry, AMQQueue queue, QueueNotificationListener listener);
}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/PersistentAMQMessage.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/PersistentAMQMessage.java
index 804bb29ecd..9c644cc010 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/PersistentAMQMessage.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/PersistentAMQMessage.java
@@ -52,30 +52,19 @@ public class PersistentAMQMessage extends TransientAMQMessage
throws AMQException
{
super.setPublishAndContentHeaderBody(storeContext, messagePublishInfo, contentHeaderBody);
- MessageMetaData mmd = new MessageMetaData(messagePublishInfo, contentHeaderBody, _contentBodies == null ? 0 : _contentBodies.size(), _arrivalTime);
+ MessageMetaData mmd = new MessageMetaData(messagePublishInfo, contentHeaderBody,
+ _contentBodies == null ? 0 : _contentBodies.size(), _arrivalTime);
_transactionLog.storeMessageMetaData(storeContext, _messageId, mmd);
}
@Override
- public void removeMessage(StoreContext storeContext) throws AMQException
- {
- _transactionLog.removeMessage(storeContext, _messageId);
- }
-
- @Override
public boolean isPersistent()
{
return true;
}
- public void recoverFromMessageMetaData(MessageMetaData mmd)
- {
- _arrivalTime = mmd.getArrivalTime();
- _contentHeaderBody = mmd.getContentHeaderBody();
- _messagePublishInfo = mmd.getMessagePublishInfo();
- }
-
+ @Override
public void recoverContentBodyFrame(ContentChunk contentChunk, boolean isLastContentBody) throws AMQException
{
super.addContentBodyFrame(null, contentChunk, isLastContentBody);
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/PriorityQueueEntryList.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/PriorityQueueEntryList.java
new file mode 100644
index 0000000000..d5271295dd
--- /dev/null
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/PriorityQueueEntryList.java
@@ -0,0 +1,466 @@
+/*
+*
+* 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.framing.CommonContentHeaderProperties;
+
+public class PriorityQueueEntryList extends FlowableBaseQueueEntryList implements QueueEntryList
+{
+ private final AMQQueue _queue;
+ private final QueueEntryList[] _priorityLists;
+ private final int _priorities;
+ private final int _priorityOffset;
+
+ public PriorityQueueEntryList(AMQQueue queue, int priorities)
+ {
+ super(queue);
+ _queue = queue;
+ _priorityLists = new QueueEntryList[priorities];
+ _priorities = priorities;
+ _priorityOffset = 5 - ((priorities + 1) / 2);
+ for (int i = 0; i < priorities; i++)
+ {
+ _priorityLists[i] = new SimpleQueueEntryList(queue);
+ }
+
+ showUsage("Created:" + _queue.getName());
+ }
+
+ public int getPriorities()
+ {
+ return _priorities;
+ }
+
+ public AMQQueue getQueue()
+ {
+ return _queue;
+ }
+
+ public QueueEntry add(AMQMessage message)
+ {
+ int index = ((CommonContentHeaderProperties) ((message.getContentHeaderBody().properties))).getPriority() - _priorityOffset;
+ if (index >= _priorities)
+ {
+ index = _priorities - 1;
+ }
+ else if (index < 0)
+ {
+ index = 0;
+ }
+
+ long requriedSize = message.getSize();
+ // Check and see if list would flow on adding message
+ if (!_disabled && !isFlowed() && _priorityLists[index].memoryUsed() + requriedSize > _priorityLists[index].getMemoryUsageMaximum())
+ {
+ if (_log.isDebugEnabled())
+ {
+ _log.debug("Message(" + message.debugIdentity() + ") Add of size ("
+ + requriedSize + ") will cause flow. Searching for space");
+ }
+
+ long reclaimed = 0;
+
+ //work down the priorities looking for memory
+
+ //First: Don't take all the memory. So look for a queue that has more than 50% free
+ long currentMax;
+ int scavangeIndex = 0;
+
+ if (scavangeIndex == index)
+ {
+ scavangeIndex++;
+ }
+
+ while (scavangeIndex < _priorities && reclaimed <= requriedSize)
+ {
+ currentMax = _priorityLists[scavangeIndex].getMemoryUsageMaximum();
+ long used = _priorityLists[scavangeIndex].memoryUsed();
+
+ if (used < currentMax / 2)
+ {
+ long newMax = currentMax / 2;
+
+ _priorityLists[scavangeIndex].setMemoryUsageMaximum(newMax);
+
+ reclaimed += currentMax - newMax;
+ if (_log.isDebugEnabled())
+ {
+ _log.debug("Reclaiming(1) :" + (currentMax - newMax) + "(" + reclaimed + "/" + requriedSize + ") from queue:" + scavangeIndex);
+ }
+ break;
+ }
+ else
+ {
+ scavangeIndex++;
+ if (scavangeIndex == index)
+ {
+ scavangeIndex++;
+ }
+ }
+ }
+
+ //Second: Just take the free memory we need
+ if (scavangeIndex == _priorities)
+ {
+ scavangeIndex = 0;
+ if (scavangeIndex == index)
+ {
+ scavangeIndex++;
+ }
+
+ while (scavangeIndex < _priorities && reclaimed <= requriedSize)
+ {
+ currentMax = _priorityLists[scavangeIndex].getMemoryUsageMaximum();
+ long used = _priorityLists[scavangeIndex].memoryUsed();
+
+ if (used < currentMax)
+ {
+ long newMax = currentMax - used;
+
+ // if there are no messages at this priority just take it all
+ if (newMax == currentMax)
+ {
+ newMax = 0;
+ }
+
+ _priorityLists[scavangeIndex].setMemoryUsageMaximum(newMax);
+
+ reclaimed += currentMax - newMax;
+ if (_log.isDebugEnabled())
+ {
+ _log.debug("Reclaiming(2) :" + (currentMax - newMax) + "(" + reclaimed + "/" + requriedSize + ") from queue:" + scavangeIndex);
+ }
+ break;
+ }
+ else
+ {
+ scavangeIndex++;
+ if (scavangeIndex == index)
+ {
+ scavangeIndex++;
+ }
+ }
+ }
+
+ //Third: Take required memory
+ if (scavangeIndex == _priorities)
+ {
+ scavangeIndex = 0;
+ if (scavangeIndex == index)
+ {
+ scavangeIndex++;
+ }
+ while (scavangeIndex < _priorities && reclaimed <= requriedSize)
+ {
+ currentMax = _priorityLists[scavangeIndex].getMemoryUsageMaximum();
+
+ if (currentMax > 0 )
+ {
+ long newMax = currentMax;
+ // Just take the amount of space required for this message.
+ if (newMax > requriedSize)
+ {
+ newMax = requriedSize;
+ }
+ _priorityLists[scavangeIndex].setMemoryUsageMaximum(newMax);
+
+ reclaimed += currentMax - newMax;
+ if (_log.isDebugEnabled())
+ {
+ _log.debug("Reclaiming(3) :" + (currentMax - newMax) + "(" + reclaimed + "/" + requriedSize + ") from queue:" + scavangeIndex);
+ }
+ break;
+ }
+ else
+ {
+ scavangeIndex++;
+ if (scavangeIndex == index)
+ {
+ scavangeIndex++;
+ }
+ }
+ }
+ }
+ }
+
+ //Increment Maximum
+ if (reclaimed > 0)
+ {
+ if (_log.isDebugEnabled())
+ {
+ _log.debug("Increasing queue(" + index + ") maximum by " + reclaimed
+ + " to " + (_priorityLists[index].getMemoryUsageMaximum() + reclaimed));
+ }
+ _priorityLists[index].setMemoryUsageMaximum(_priorityLists[index].getMemoryUsageMaximum() + reclaimed);
+ }
+ else
+ {
+ _log.debug("No space found.");
+ }
+
+ if (_log.isTraceEnabled())
+ {
+ showUsage("Add");
+ }
+ }
+
+ return _priorityLists[index].add(message);
+ }
+
+ @Override
+ protected void showUsage(String prefix)
+ {
+ if (_log.isDebugEnabled())
+ {
+ if (prefix.length() != 0)
+ {
+ _log.debug(prefix);
+ }
+ for (int index = 0; index < _priorities; index++)
+ {
+ QueueEntryList queueEntryList = _priorityLists[index];
+ _log.debug("Queue (" + _queue.getName() + ")[" + index + "] usage:" + queueEntryList.memoryUsed()
+ + "/" + queueEntryList.getMemoryUsageMaximum()
+ + "/" + queueEntryList.dataSize());
+ }
+ }
+ }
+
+ public QueueEntry next(QueueEntry node)
+ {
+ QueueEntryImpl nodeImpl = (QueueEntryImpl) node;
+ QueueEntry next = nodeImpl.getNext();
+
+ if (next == null)
+ {
+ QueueEntryList nodeEntryList = nodeImpl.getQueueEntryList();
+ int index;
+ for (index = _priorityLists.length - 1; _priorityLists[index] != nodeEntryList; index--)
+ {
+ ;
+ }
+
+ while (next == null && index != 0)
+ {
+ index--;
+ next = ((QueueEntryImpl) _priorityLists[index].getHead()).getNext();
+ }
+
+ }
+ return next;
+ }
+
+ private final class PriorityQueueEntryListIterator implements QueueEntryIterator
+ {
+ private final QueueEntryIterator[] _iterators = new QueueEntryIterator[_priorityLists.length];
+ private QueueEntry _lastNode;
+
+ PriorityQueueEntryListIterator()
+ {
+ for (int i = 0; i < _priorityLists.length; i++)
+ {
+ _iterators[i] = _priorityLists[i].iterator();
+ }
+ _lastNode = _iterators[_iterators.length - 1].getNode();
+ }
+
+ public boolean atTail()
+ {
+ for (int i = 0; i < _iterators.length; i++)
+ {
+ if (!_iterators[i].atTail())
+ {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ public QueueEntry getNode()
+ {
+ return _lastNode;
+ }
+
+ public boolean advance()
+ {
+ for (int i = _iterators.length - 1; i >= 0; i--)
+ {
+ if (_iterators[i].advance())
+ {
+ _lastNode = _iterators[i].getNode();
+ return true;
+ }
+ }
+ return false;
+ }
+ }
+
+ public QueueEntryIterator iterator()
+ {
+ return new PriorityQueueEntryListIterator();
+ }
+
+ public QueueEntry getHead()
+ {
+ return _priorityLists[_priorities - 1].getHead();
+ }
+
+ static class Factory implements QueueEntryListFactory
+ {
+ private final int _priorities;
+
+ Factory(int priorities)
+ {
+ _priorities = priorities;
+ }
+
+ public QueueEntryList createQueueEntryList(AMQQueue queue)
+ {
+ return new PriorityQueueEntryList(queue, _priorities);
+ }
+ }
+
+ @Override
+ public boolean isFlowed()
+ {
+ boolean flowed = false;
+ boolean full = true;
+
+ if (_log.isTraceEnabled())
+ {
+ showUsage("isFlowed");
+ }
+
+ for (QueueEntryList queueEntryList : _priorityLists)
+ {
+ //full = full && queueEntryList.getMemoryUsageMaximum() == queueEntryList.memoryUsed();
+ full = full && queueEntryList.getMemoryUsageMaximum() <= queueEntryList.dataSize();
+ flowed = flowed || (queueEntryList.isFlowed());
+ }
+ return flowed && full;
+ }
+
+ @Override
+ public int size()
+ {
+ int size = 0;
+ for (QueueEntryList queueEntryList : _priorityLists)
+ {
+ size += queueEntryList.size();
+ }
+
+ return size;
+ }
+
+ @Override
+ public long dataSize()
+ {
+ int dataSize = 0;
+ for (QueueEntryList queueEntryList : _priorityLists)
+ {
+ dataSize += queueEntryList.dataSize();
+ }
+
+ return dataSize;
+ }
+
+ @Override
+ public long memoryUsed()
+ {
+ int memoryUsed = 0;
+ for (QueueEntryList queueEntryList : _priorityLists)
+ {
+ memoryUsed += queueEntryList.memoryUsed();
+ }
+
+ return memoryUsed;
+ }
+
+ @Override
+ public void setMemoryUsageMaximum(long maximumMemoryUsage)
+ {
+ _memoryUsageMaximum = maximumMemoryUsage;
+
+ if (maximumMemoryUsage >= 0)
+ {
+ _disabled = false;
+ }
+
+ long share = maximumMemoryUsage / _priorities;
+
+ //Apply a share of the maximum To each prioirty quue
+ for (QueueEntryList queueEntryList : _priorityLists)
+ {
+ queueEntryList.setMemoryUsageMaximum(share);
+ }
+
+ if (maximumMemoryUsage < 0)
+ {
+ if (_log.isInfoEnabled())
+ {
+ _log.info("Disabling Flow to Disk for queue:" + _queue.getName());
+ }
+ _disabled = true;
+ return;
+ }
+
+ //ensure we use the full allocation of memory
+ long remainder = maximumMemoryUsage - (share * _priorities);
+ if (remainder > 0)
+ {
+ _priorityLists[_priorities - 1].setMemoryUsageMaximum(share + remainder);
+ }
+ }
+
+ @Override
+ public long getMemoryUsageMaximum()
+ {
+ return _memoryUsageMaximum;
+ }
+
+ @Override
+ public void setMemoryUsageMinimum(long minimumMemoryUsage)
+ {
+ _memoryUsageMinimum = minimumMemoryUsage;
+
+ //Apply a share of the minimum To each prioirty quue
+ for (QueueEntryList queueEntryList : _priorityLists)
+ {
+ queueEntryList.setMemoryUsageMaximum(minimumMemoryUsage / _priorities);
+ }
+ }
+
+ @Override
+ public long getMemoryUsageMinimum()
+ {
+ return _memoryUsageMinimum;
+ }
+
+ @Override
+ public void stop()
+ {
+ super.stop();
+ for (QueueEntryList queueEntryList : _priorityLists)
+ {
+ queueEntryList.stop();
+ }
+ }
+}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/PriorityQueueList.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/PriorityQueueList.java
deleted file mode 100644
index 7be2827e0f..0000000000
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/PriorityQueueList.java
+++ /dev/null
@@ -1,160 +0,0 @@
-/*
-*
-* Licensed to the Apache Software Foundation (ASF) under one
-* or more contributor license agreements. See the NOTICE file
-* distributed with this work for additional information
-* regarding copyright ownership. The ASF licenses this file
-* to you under the Apache License, Version 2.0 (the
-* "License"); you may not use this file except in compliance
-* with the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing,
-* software distributed under the License is distributed on an
-* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-* KIND, either express or implied. See the License for the
-* specific language governing permissions and limitations
-* under the License.
-*
-*/
-package org.apache.qpid.server.queue;
-
-import org.apache.qpid.framing.CommonContentHeaderProperties;
-import org.apache.qpid.AMQException;
-
-public class PriorityQueueList implements QueueEntryList
-{
- private final AMQQueue _queue;
- private final QueueEntryList[] _priorityLists;
- private final int _priorities;
- private final int _priorityOffset;
-
- public PriorityQueueList(AMQQueue queue, int priorities)
- {
- _queue = queue;
- _priorityLists = new QueueEntryList[priorities];
- _priorities = priorities;
- _priorityOffset = 5-((priorities + 1)/2);
- for(int i = 0; i < priorities; i++)
- {
- _priorityLists[i] = new SimpleQueueEntryList(queue);
- }
- }
-
- public int getPriorities()
- {
- return _priorities;
- }
-
- public AMQQueue getQueue()
- {
- return _queue;
- }
-
- public QueueEntry add(AMQMessage message)
- {
- int index = ((CommonContentHeaderProperties)((message.getContentHeaderBody().properties))).getPriority() - _priorityOffset;
- if(index >= _priorities)
- {
- index = _priorities-1;
- }
- else if(index < 0)
- {
- index = 0;
- }
- return _priorityLists[index].add(message);
- }
-
- public QueueEntry next(QueueEntry node)
- {
- QueueEntryImpl nodeImpl = (QueueEntryImpl)node;
- QueueEntry next = nodeImpl.getNext();
-
- if(next == null)
- {
- QueueEntryList nodeEntryList = nodeImpl.getQueueEntryList();
- int index;
- for(index = _priorityLists.length-1; _priorityLists[index] != nodeEntryList; index--);
-
- while(next == null && index != 0)
- {
- index--;
- next = ((QueueEntryImpl)_priorityLists[index].getHead()).getNext();
- }
-
- }
- return next;
- }
-
- private final class PriorityQueueEntryListIterator implements QueueEntryIterator
- {
- private final QueueEntryIterator[] _iterators = new QueueEntryIterator[ _priorityLists.length ];
- private QueueEntry _lastNode;
-
- PriorityQueueEntryListIterator()
- {
- for(int i = 0; i < _priorityLists.length; i++)
- {
- _iterators[i] = _priorityLists[i].iterator();
- }
- _lastNode = _iterators[_iterators.length - 1].getNode();
- }
-
-
- public boolean atTail()
- {
- for(int i = 0; i < _iterators.length; i++)
- {
- if(!_iterators[i].atTail())
- {
- return false;
- }
- }
- return true;
- }
-
- public QueueEntry getNode()
- {
- return _lastNode;
- }
-
- public boolean advance()
- {
- for(int i = _iterators.length-1; i >= 0; i--)
- {
- if(_iterators[i].advance())
- {
- _lastNode = _iterators[i].getNode();
- return true;
- }
- }
- return false;
- }
- }
-
- public QueueEntryIterator iterator()
- {
- return new PriorityQueueEntryListIterator();
- }
-
- public QueueEntry getHead()
- {
- return _priorityLists[_priorities-1].getHead();
- }
-
- static class Factory implements QueueEntryListFactory
- {
- private final int _priorities;
-
- Factory(int priorities)
- {
- _priorities = priorities;
- }
-
- public QueueEntryList createQueueEntryList(AMQQueue queue)
- {
- return new PriorityQueueList(queue, _priorities);
- }
- }
-}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/QueueBackingStore.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/QueueBackingStore.java
new file mode 100644
index 0000000000..5c65cb6424
--- /dev/null
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/QueueBackingStore.java
@@ -0,0 +1,64 @@
+/*
+ *
+ * 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.server.configuration.VirtualHostConfiguration;
+import org.apache.qpid.server.virtualhost.VirtualHost;
+import org.apache.commons.configuration.ConfigurationException;
+
+public interface QueueBackingStore
+{
+ /**
+ * Retrieve the message with a given ID
+ *
+ * This method must be thread safe.
+ *
+ * Multiple calls to load with a given messageId DO NOT need to return the same object.
+ *
+ * @param messageId the id of the message to retreive.
+ * @return
+ */
+ AMQMessage load(Long messageId);
+
+ /**
+ * Store a message in the BackingStore.
+ *
+ * This method must be thread safe understanding that multiple message objects may be the same data.
+ *
+ * Allowing a thread to return from this method means that it is safe to call load()
+ *
+ * Implementer guide:
+ * Until the message has been loaded the message references will all be the same object.
+ *
+ * One appraoch as taken by the @see FileQueueBackingStore is to block aimulataneous calls to this method
+ * until the message is fully on disk. This can be done by synchronising on message as initially it is always the
+ * same object. Only after a load has taken place will there be a discrepency.
+ *
+ *
+ * @param message the message to unload
+ * @throws UnableToFlowMessageException
+ */
+ void unload(AMQMessage message) throws UnableToFlowMessageException;
+
+ void delete(Long messageId);
+
+ void close();
+}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/QueueBackingStoreFactory.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/QueueBackingStoreFactory.java
new file mode 100644
index 0000000000..3dd23a2f40
--- /dev/null
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/QueueBackingStoreFactory.java
@@ -0,0 +1,32 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.qpid.server.queue;
+
+import org.apache.qpid.server.virtualhost.VirtualHost;
+import org.apache.qpid.server.configuration.VirtualHostConfiguration;
+import org.apache.commons.configuration.ConfigurationException;
+
+public interface QueueBackingStoreFactory
+{
+ void configure(VirtualHost virtualHost, VirtualHostConfiguration config) throws ConfigurationException;
+
+ public QueueBackingStore createBacking(AMQQueue queue);
+}
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 0df976a620..fb23edb3c5 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
@@ -49,7 +49,6 @@ public interface QueueEntry extends Comparable<QueueEntry>, Filterable<AMQExcept
public abstract State getState();
}
-
public final class AvailableState extends EntryState
{
@@ -59,7 +58,6 @@ public interface QueueEntry extends Comparable<QueueEntry>, Filterable<AMQExcept
}
}
-
public final class DequeuedState extends EntryState
{
@@ -69,7 +67,6 @@ public interface QueueEntry extends Comparable<QueueEntry>, Filterable<AMQExcept
}
}
-
public final class DeletedState extends EntryState
{
@@ -88,7 +85,6 @@ public interface QueueEntry extends Comparable<QueueEntry>, Filterable<AMQExcept
}
}
-
public final class NonSubscriptionAcquiredState extends EntryState
{
public State getState()
@@ -106,7 +102,6 @@ public interface QueueEntry extends Comparable<QueueEntry>, Filterable<AMQExcept
_subscription = subscription;
}
-
public State getState()
{
return State.ACQUIRED;
@@ -118,42 +113,83 @@ public interface QueueEntry extends Comparable<QueueEntry>, Filterable<AMQExcept
}
}
-
final static EntryState AVAILABLE_STATE = new AvailableState();
final static EntryState DELETED_STATE = new DeletedState();
final static EntryState DEQUEUED_STATE = new DequeuedState();
final static EntryState EXPIRED_STATE = new ExpiredState();
final static EntryState NON_SUBSCRIPTION_ACQUIRED_STATE = new NonSubscriptionAcquiredState();
+ /** Flag to indicate that this message requires 'immediate' delivery. */
+
+ final static byte IMMEDIATE = 0x01;
+
+ /**
+ * Flag to indicate whether this message has been delivered to a consumer. Used in implementing return functionality
+ * for messages published with the 'immediate' flag.
+ */
+ final static byte DELIVERED_TO_CONSUMER = 0x02;
AMQQueue getQueue();
AMQMessage getMessage();
+ Long getMessageId();
+
long getSize();
+ /**
+ * Called selectors to determin if the message has already been sent
+ *
+ * @return _deliveredToConsumer
+ */
boolean getDeliveredToConsumer();
+ /**
+ * Checks to see if the message has expired. If it has the message is dequeued.
+ *
+ * @return true if the message has expire
+ *
+ * @throws org.apache.qpid.AMQException
+ */
boolean expired() throws AMQException;
+ public void setExpiration(final long expiration);
+
boolean isAcquired();
+ boolean isAvailable();
+
boolean acquire();
+
boolean acquire(Subscription sub);
boolean delete();
+
boolean isDeleted();
boolean acquiredBySubscription();
-
+
+ /**
+ * Called when this message is delivered to a consumer. (used to implement the 'immediate' flag functionality).
+ * And for selector efficiency.
+ *
+ * This is now also used to unload the message if this entry is on a flowed queue. As a result this method should
+ * only be called after the message has been sent.
+ */
void setDeliveredToSubscription();
void release();
String debugIdentity();
+ /**
+ * Called to enforce the 'immediate' flag.
+ *
+ * @returns true if the message is marked for immediate delivery but has not been marked as delivered
+ * to a consumer
+ */
boolean immediateAndNotDelivered();
void setRedelivered(boolean b);
@@ -170,12 +206,28 @@ public interface QueueEntry extends Comparable<QueueEntry>, Filterable<AMQExcept
void dequeue(final StoreContext storeContext) throws FailedDequeueException;
- void dispose(final StoreContext storeContext) throws MessageCleanupException;
-
- void discard(StoreContext storeContext) throws FailedDequeueException, MessageCleanupException;
+ /**
+ * Message has been ack so dequeueAndDelete it.
+ * If the message is persistent and this is the last QueueEntry that uses it then the data will be removed
+ * from the transaciton log
+ *
+ * @param storeContext the transactional Context in which to perform the deletion
+ *
+ * @throws FailedDequeueException
+ * @throws MessageCleanupException
+ */
+ void dequeueAndDelete(StoreContext storeContext) throws FailedDequeueException;
boolean isQueueDeleted();
void addStateChangeListener(StateChangeListener listener);
+
boolean removeStateChangeListener(StateChangeListener listener);
-}
+
+ void unload();
+
+ AMQMessage load();
+
+ boolean isFlowed();
+
+} \ No newline at end of file
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 ba14be5580..b6e6365189 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
@@ -20,30 +20,29 @@
*/
package org.apache.qpid.server.queue;
+import org.apache.log4j.Logger;
import org.apache.qpid.AMQException;
import org.apache.qpid.framing.ContentHeaderBody;
import org.apache.qpid.server.store.StoreContext;
import org.apache.qpid.server.subscription.Subscription;
-import org.apache.log4j.Logger;
-import java.util.Set;
import java.util.HashSet;
-import java.util.concurrent.atomic.AtomicReferenceFieldUpdater;
-import java.util.concurrent.atomic.AtomicLongFieldUpdater;
+import java.util.Set;
import java.util.concurrent.CopyOnWriteArraySet;
-
+import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.concurrent.atomic.AtomicLongFieldUpdater;
+import java.util.concurrent.atomic.AtomicReference;
+import java.util.concurrent.atomic.AtomicReferenceFieldUpdater;
public class QueueEntryImpl implements QueueEntry
{
- /**
- * Used for debugging purposes.
- */
+ /** Used for debugging purposes. */
private static final Logger _log = Logger.getLogger(QueueEntryImpl.class);
private final SimpleQueueEntryList _queueEntryList;
- private AMQMessage _message;
+ private AtomicReference<AMQMessage> _messageRef;
private boolean _redelivered;
@@ -52,44 +51,51 @@ public class QueueEntryImpl implements QueueEntry
private volatile EntryState _state = AVAILABLE_STATE;
private static final
- AtomicReferenceFieldUpdater<QueueEntryImpl, EntryState>
+ AtomicReferenceFieldUpdater<QueueEntryImpl, EntryState>
_stateUpdater =
- AtomicReferenceFieldUpdater.newUpdater
- (QueueEntryImpl.class, EntryState.class, "_state");
-
+ AtomicReferenceFieldUpdater.newUpdater
+ (QueueEntryImpl.class, EntryState.class, "_state");
private volatile Set<StateChangeListener> _stateChangeListeners;
private static final
- AtomicReferenceFieldUpdater<QueueEntryImpl, Set>
- _listenersUpdater =
- AtomicReferenceFieldUpdater.newUpdater
- (QueueEntryImpl.class, Set.class, "_stateChangeListeners");
-
+ AtomicReferenceFieldUpdater<QueueEntryImpl, Set>
+ _listenersUpdater =
+ AtomicReferenceFieldUpdater.newUpdater
+ (QueueEntryImpl.class, Set.class, "_stateChangeListeners");
private static final
- AtomicLongFieldUpdater<QueueEntryImpl>
+ AtomicLongFieldUpdater<QueueEntryImpl>
_entryIdUpdater =
- AtomicLongFieldUpdater.newUpdater
- (QueueEntryImpl.class, "_entryId");
-
+ AtomicLongFieldUpdater.newUpdater
+ (QueueEntryImpl.class, "_entryId");
private volatile long _entryId;
volatile QueueEntryImpl _next;
+ private long _messageSize;
+ private QueueBackingStore _backingStore;
+ private AtomicBoolean _flowed;
+ private Long _messageId;
+
+ private byte _flags = 0;
+
+ private long _expiration;
+
+ private static final byte IMMEDIATE_AND_DELIVERED = (byte) (IMMEDIATE | DELIVERED_TO_CONSUMER);
+ private boolean _persistent;
+ private boolean _hasBeenUnloaded = false;
QueueEntryImpl(SimpleQueueEntryList queueEntryList)
{
- this(queueEntryList,null,Long.MIN_VALUE);
+ this(queueEntryList, null, Long.MIN_VALUE);
_state = DELETED_STATE;
}
-
public QueueEntryImpl(SimpleQueueEntryList queueEntryList, AMQMessage message, final long entryId)
{
- _queueEntryList = queueEntryList;
- _message = message;
+ this(queueEntryList, message);
_entryIdUpdater.set(this, entryId);
}
@@ -97,7 +103,21 @@ public class QueueEntryImpl implements QueueEntry
public QueueEntryImpl(SimpleQueueEntryList queueEntryList, AMQMessage message)
{
_queueEntryList = queueEntryList;
- _message = message;
+ _messageRef = new AtomicReference<AMQMessage>(message);
+ if (message != null)
+ {
+ _messageId = message.getMessageId();
+ _messageSize = message.getSize();
+
+ if (message.isImmediate())
+ {
+ _flags |= IMMEDIATE;
+ }
+ _expiration = message.getExpiration();
+ _persistent = message.isPersistent();
+ }
+ _backingStore = queueEntryList.getBackingStore();
+ _flowed = new AtomicBoolean(false);
}
protected void setEntryId(long entryId)
@@ -117,22 +137,50 @@ public class QueueEntryImpl implements QueueEntry
public AMQMessage getMessage()
{
- return _message;
+ return load();
+ }
+
+ public Long getMessageId()
+ {
+ return _messageId;
}
public long getSize()
{
- return getMessage().getSize();
+ return _messageSize;
}
public boolean getDeliveredToConsumer()
{
- return getMessage().getDeliveredToConsumer();
+ return (_flags & DELIVERED_TO_CONSUMER) != 0;
+ }
+
+ public void setDeliveredToSubscription()
+ {
+ _flags |= DELIVERED_TO_CONSUMER;
+
+ // We have delivered this message so we can unload it if we are flowed.
+ if (_queueEntryList.isFlowed())
+ {
+ unload();
+ }
}
public boolean expired() throws AMQException
{
- return getMessage().expired();
+ if (_expiration != 0L)
+ {
+ long now = System.currentTimeMillis();
+
+ return (now > _expiration);
+ }
+
+ return false;
+ }
+
+ public void setExpiration(final long expiration)
+ {
+ _expiration = expiration;
}
public boolean isAcquired()
@@ -140,6 +188,11 @@ public class QueueEntryImpl implements QueueEntry
return _state.getState() == State.ACQUIRED;
}
+ public boolean isAvailable()
+ {
+ return _state.getState() == State.AVAILABLE;
+ }
+
public boolean acquire()
{
return acquire(NON_SUBSCRIPTION_ACQUIRED_STATE);
@@ -147,8 +200,8 @@ public class QueueEntryImpl implements QueueEntry
private boolean acquire(final EntryState state)
{
- boolean acquired = _stateUpdater.compareAndSet(this,AVAILABLE_STATE, state);
- if(acquired && _stateChangeListeners != null)
+ boolean acquired = _stateUpdater.compareAndSet(this, AVAILABLE_STATE, state);
+ if (acquired && _stateChangeListeners != null)
{
notifyStateChange(State.AVAILABLE, State.ACQUIRED);
}
@@ -167,35 +220,41 @@ public class QueueEntryImpl implements QueueEntry
return (_state instanceof SubscriptionAcquiredState);
}
- public void setDeliveredToSubscription()
- {
- getMessage().setDeliveredToConsumer();
- }
-
public void release()
{
- _stateUpdater.set(this,AVAILABLE_STATE);
+ _stateUpdater.set(this, AVAILABLE_STATE);
}
public String debugIdentity()
{
- return getMessage().debugIdentity();
- }
+ String entry = "[State:" + _state.getState().name() + "]";
+ AMQMessage message = _messageRef.get();
- public boolean immediateAndNotDelivered()
+ if (message == null)
+ {
+ return entry + "(Message Unloaded ID:" + _messageId + ")";
+ }
+ else
+ {
+
+ return entry + message.debugIdentity();
+ }
+ }
+
+ public boolean immediateAndNotDelivered()
{
- return _message.immediateAndNotDelivered();
+ return (_flags & IMMEDIATE_AND_DELIVERED) == IMMEDIATE;
}
public ContentHeaderBody getContentHeaderBody() throws AMQException
{
- return _message.getContentHeaderBody();
+ return getMessage().getContentHeaderBody();
}
public boolean isPersistent() throws AMQException
{
- return _message.isPersistent();
+ return _persistent;
}
public boolean isRedelivered()
@@ -206,21 +265,21 @@ public class QueueEntryImpl implements QueueEntry
public void setRedelivered(boolean redelivered)
{
_redelivered = redelivered;
- // todo - here we could mark this message as redelivered so we don't have to mark
- // all messages on recover as redelivered.
+ // todo - here we could record this message as redelivered on this queue in the transactionLog
+ // so we don't have to mark all messages on recover as redelivered.
}
public Subscription getDeliveredSubscription()
{
- EntryState state = _state;
- if (state instanceof SubscriptionAcquiredState)
- {
- return ((SubscriptionAcquiredState) state).getSubscription();
- }
- else
- {
- return null;
- }
+ EntryState state = _state;
+ if (state instanceof SubscriptionAcquiredState)
+ {
+ return ((SubscriptionAcquiredState) state).getSubscription();
+ }
+ else
+ {
+ return null;
+ }
}
@@ -247,7 +306,7 @@ public class QueueEntryImpl implements QueueEntry
}
public boolean isRejectedBy(Subscription subscription)
- {
+ {
if (_rejectedBy != null) // We have subscriptions that rejected this message
{
@@ -259,11 +318,10 @@ public class QueueEntryImpl implements QueueEntry
}
}
-
public void requeue(final StoreContext storeContext) throws AMQException
{
getQueue().requeue(storeContext, this);
- if(_stateChangeListeners != null)
+ if (_stateChangeListeners != null)
{
notifyStateChange(QueueEntry.State.ACQUIRED, QueueEntry.State.AVAILABLE);
}
@@ -273,7 +331,7 @@ public class QueueEntryImpl implements QueueEntry
{
EntryState state = _state;
- if((state.getState() == State.ACQUIRED) &&_stateUpdater.compareAndSet(this, state, DEQUEUED_STATE))
+ if ((state.getState() == State.ACQUIRED) && _stateUpdater.compareAndSet(this, state, DEQUEUED_STATE))
{
if (state instanceof SubscriptionAcquiredState)
{
@@ -281,41 +339,34 @@ public class QueueEntryImpl implements QueueEntry
s.restoreCredit(this);
}
+ _queueEntryList.dequeued(this);
+
getQueue().dequeue(storeContext, this);
- if(_stateChangeListeners != null)
+
+ if (_stateChangeListeners != null)
{
- notifyStateChange(state.getState() , QueueEntry.State.DEQUEUED);
+ notifyStateChange(state.getState(), QueueEntry.State.DEQUEUED);
}
-
}
-
}
private void notifyStateChange(final State oldState, final State newState)
{
- for(StateChangeListener l : _stateChangeListeners)
+ for (StateChangeListener l : _stateChangeListeners)
{
l.stateChanged(this, oldState, newState);
}
}
- public void dispose(final StoreContext storeContext) throws MessageCleanupException
+ public void dequeueAndDelete(StoreContext storeContext) throws FailedDequeueException
{
- if(delete())
- {
- getMessage().decrementReference(storeContext);
- }
- }
-
- public void discard(StoreContext storeContext) throws FailedDequeueException, MessageCleanupException
- {
- //if the queue is null then the message is waiting to be acked, but has been removed.
+ //if the queue is null (i.e. queue.delete()'d) then the message is waiting to be acked, but has already be delete()'d;
if (getQueue() != null)
{
dequeue(storeContext);
}
- dispose(storeContext);
+ delete();
}
public boolean isQueueDeleted()
@@ -326,7 +377,7 @@ public class QueueEntryImpl implements QueueEntry
public void addStateChangeListener(StateChangeListener listener)
{
Set<StateChangeListener> listeners = _stateChangeListeners;
- if(listeners == null)
+ if (listeners == null)
{
_listenersUpdater.compareAndSet(this, null, new CopyOnWriteArraySet<StateChangeListener>());
listeners = _stateChangeListeners;
@@ -338,7 +389,7 @@ public class QueueEntryImpl implements QueueEntry
public boolean removeStateChangeListener(StateChangeListener listener)
{
Set<StateChangeListener> listeners = _stateChangeListeners;
- if(listeners != null)
+ if (listeners != null)
{
return listeners.remove(listener);
}
@@ -346,10 +397,108 @@ public class QueueEntryImpl implements QueueEntry
return false;
}
+ public void unload()
+ {
+ //Get the currently loaded message
+ AMQMessage message = _messageRef.get();
+
+ // If we have a message in memory and we have a valid backingStore attempt to unload
+ if (message != null && _backingStore != null)
+ {
+ try
+ {
+ // The backingStore will now handle concurrent calls to unload and safely synchronize to ensure
+ // multiple initial unloads are unloads
+ _backingStore.unload(message);
+ _hasBeenUnloaded = true;
+ _messageRef.set(null);
+
+ if (_log.isDebugEnabled())
+ {
+ _log.debug("Unloaded:" + debugIdentity());
+ }
+
+
+ // Clear the message reference if the loaded message is still the one we are processing.
+
+ //Update the memoryState if this load call resulted in the message being purged from memory
+ if (!_flowed.getAndSet(true))
+ {
+ _queueEntryList.entryUnloadedUpdateMemory(this);
+ }
+
+ }
+ catch (UnableToFlowMessageException utfme)
+ {
+ // There is no recovery needed as the memory states remain unchanged.
+ if (_log.isDebugEnabled())
+ {
+ _log.debug("Unable to Flow message:" + debugIdentity() + ", due to:" + utfme.getMessage());
+ }
+ }
+ }
+ }
+
+ public AMQMessage load()
+ {
+ // MessageId and Backing store are null in test scenarios, normally this is not the case.
+ if (_messageId != null && _backingStore != null)
+ {
+ // See if we have the message currently in memory to return
+ AMQMessage message = _messageRef.get();
+ // if we don't then we need to start a load process.
+ if (message == null)
+ {
+ //Synchronize here to ensure only the first thread that attempts to load will perform the load from the
+ // backing store.
+ synchronized (this)
+ {
+ // Check again to see if someone else ahead of us loaded the message
+ message = _messageRef.get();
+ // if we still don't have the message then we need to start a load process.
+ if (message == null)
+ {
+ // Load the message and keep a reference to it
+ message = _backingStore.load(_messageId);
+ // Set the message reference
+ _messageRef.set(message);
+ }
+ else
+ {
+ // If someone else loaded the message then we can jump out here as the Memory Updates will
+ // have been performed by the loading thread
+ return message;
+ }
+ }
+
+ if (_log.isDebugEnabled())
+ {
+ _log.debug("Loaded:" + debugIdentity());
+ }
+
+ //Update the memoryState if this load call resulted in the message comming in to memory
+ if (_flowed.getAndSet(false))
+ {
+ _queueEntryList.entryLoadedUpdateMemory(this);
+ }
+ }
+
+ // Return the message that was either already in memory or the value we just loaded.
+ return message;
+ }
+ // This can be null but only in the case where we have no messageId
+ // in the case where we have no backingStore then we will never have unloaded the message
+ return _messageRef.get();
+ }
+
+ public boolean isFlowed()
+ {
+ return _flowed.get();
+ }
public int compareTo(final QueueEntry o)
{
- QueueEntryImpl other = (QueueEntryImpl)o;
+ QueueEntryImpl other = (QueueEntryImpl) o;
return getEntryId() > other.getEntryId() ? 1 : getEntryId() < other.getEntryId() ? -1 : 0;
}
@@ -357,13 +506,13 @@ public class QueueEntryImpl implements QueueEntry
{
QueueEntryImpl next = nextNode();
- while(next != null && next.isDeleted())
+ while (next != null && next.isDeleted())
{
final QueueEntryImpl newNext = next.nextNode();
- if(newNext != null)
+ if (newNext != null)
{
- SimpleQueueEntryList._nextUpdater.compareAndSet(this,next, newNext);
+ SimpleQueueEntryList._nextUpdater.compareAndSet(this, next, newNext);
next = nextNode();
}
else
@@ -389,9 +538,13 @@ public class QueueEntryImpl implements QueueEntry
{
EntryState state = _state;
- if(state != DELETED_STATE && _stateUpdater.compareAndSet(this,state,DELETED_STATE))
+ if (state != DELETED_STATE && _stateUpdater.compareAndSet(this, state, DELETED_STATE))
{
- _queueEntryList.advanceHead();
+ _queueEntryList.advanceHead();
+ if (_backingStore != null && _hasBeenUnloaded)
+ {
+ _backingStore.delete(_messageId);
+ }
return true;
}
else
@@ -404,4 +557,5 @@ public class QueueEntryImpl implements QueueEntry
{
return _queueEntryList;
}
+
}
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 313e076f61..a58c6eaf7d 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
@@ -1,23 +1,23 @@
/*
-*
-* Licensed to the Apache Software Foundation (ASF) under one
-* or more contributor license agreements. See the NOTICE file
-* distributed with this work for additional information
-* regarding copyright ownership. The ASF licenses this file
-* to you under the Apache License, Version 2.0 (the
-* "License"); you may not use this file except in compliance
-* with the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing,
-* software distributed under the License is distributed on an
-* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-* KIND, either express or implied. See the License for the
-* specific language governing permissions and limitations
-* under the License.
-*
-*/
+ *
+ * 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;
public interface QueueEntryList
@@ -31,4 +31,36 @@ public interface QueueEntryList
QueueEntryIterator iterator();
QueueEntry getHead();
+
+ void setFlowed(boolean flowed);
+
+ boolean isFlowed();
+
+ int size();
+
+ long dataSize();
+
+ long memoryUsed();
+
+ void setMemoryUsageMaximum(long maximumMemoryUsage);
+
+ long getMemoryUsageMaximum();
+
+ void setMemoryUsageMinimum(long minimumMemoryUsage);
+
+ long getMemoryUsageMinimum();
+
+ /**
+ * Immediately update memory usage based on the unload of this queueEntry, potentially start inhaler.
+ * @param queueEntry the entry that has been unloaded
+ */
+ void entryUnloadedUpdateMemory(QueueEntry queueEntry);
+
+ /**
+ * Immediately update memory usage based on the load of this queueEntry
+ * @param queueEntry the entry that has been loaded
+ */
+ void entryLoadedUpdateMemory(QueueEntry queueEntry);
+
+ void stop();
}
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 a08e4e2667..ed9b1eb8d7 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
@@ -1,28 +1,9 @@
package org.apache.qpid.server.queue;
-import org.apache.qpid.framing.AMQShortString;
-import org.apache.qpid.framing.FieldTable;
-import org.apache.qpid.server.virtualhost.VirtualHost;
-import org.apache.qpid.server.configuration.Configurator;
-import org.apache.qpid.server.exchange.Exchange;
-import org.apache.qpid.server.store.StoreContext;
-import org.apache.qpid.server.subscription.Subscription;
-import org.apache.qpid.server.subscription.SubscriptionList;
-import org.apache.qpid.server.output.ProtocolOutputConverter;
-import org.apache.qpid.server.management.ManagedObject;
-import org.apache.qpid.server.transactionlog.TransactionLog;
-import org.apache.qpid.AMQException;
-import org.apache.qpid.pool.ReadWriteRunnable;
-import org.apache.qpid.pool.ReferenceCountingExecutorService;
-import org.apache.qpid.configuration.Configured;
-import org.apache.commons.configuration.Configuration;
-import org.apache.log4j.Logger;
-
-import javax.management.JMException;
-import java.util.List;
-import java.util.Set;
import java.util.ArrayList;
import java.util.EnumSet;
+import java.util.List;
+import java.util.Set;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.Executor;
import java.util.concurrent.atomic.AtomicBoolean;
@@ -30,6 +11,24 @@ import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicLong;
import java.util.concurrent.atomic.AtomicReference;
+import javax.management.JMException;
+
+import org.apache.log4j.Logger;
+import org.apache.qpid.AMQException;
+import org.apache.qpid.framing.AMQShortString;
+import org.apache.qpid.framing.FieldTable;
+import org.apache.qpid.pool.ReadWriteRunnable;
+import org.apache.qpid.pool.ReferenceCountingExecutorService;
+import org.apache.qpid.server.exchange.Exchange;
+import org.apache.qpid.server.management.ManagedObject;
+import org.apache.qpid.server.output.ProtocolOutputConverter;
+import org.apache.qpid.server.registry.ApplicationRegistry;
+import org.apache.qpid.server.store.StoreContext;
+import org.apache.qpid.server.subscription.Subscription;
+import org.apache.qpid.server.subscription.SubscriptionList;
+import org.apache.qpid.server.transactionlog.TransactionLog;
+import org.apache.qpid.server.virtualhost.VirtualHost;
+
/*
*
* Licensed to the Apache Software Foundation (ASF) under one
@@ -73,10 +72,6 @@ public class SimpleAMQQueue implements AMQQueue, Subscription.StateListener
private final List<Task> _deleteTaskList = new CopyOnWriteArrayList<Task>();
- private final AtomicInteger _atomicQueueCount = new AtomicInteger(0);
-
- private final AtomicLong _atomicQueueSize = new AtomicLong(0L);
-
private final AtomicInteger _activeSubscriberCount = new AtomicInteger();
protected final SubscriptionList _subscriptionList = new SubscriptionList(this);
@@ -91,24 +86,20 @@ public class SimpleAMQQueue implements AMQQueue, Subscription.StateListener
private final AtomicLong _totalMessagesReceived = new AtomicLong();
/** max allowed size(KB) of a single message */
- @Configured(path = "maximumMessageSize", defaultValue = "0")
- public long _maximumMessageSize;
+ public long _maximumMessageSize = ApplicationRegistry.getInstance().getConfiguration().getMaximumMessageSize();
/** max allowed number of messages on a queue. */
- @Configured(path = "maximumMessageCount", defaultValue = "0")
- public long _maximumMessageCount;
+ public long _maximumMessageCount = ApplicationRegistry.getInstance().getConfiguration().getMaximumMessageCount();
/** max queue depth for the queue */
- @Configured(path = "maximumQueueDepth", defaultValue = "0")
- public long _maximumQueueDepth;
+ public long _maximumQueueDepth = ApplicationRegistry.getInstance().getConfiguration().getMaximumQueueDepth();
/** maximum message age before alerts occur */
- @Configured(path = "maximumMessageAge", defaultValue = "0")
- public long _maximumMessageAge;
+ public long _maximumMessageAge = ApplicationRegistry.getInstance().getConfiguration().getMaximumMessageAge();
+
+ /** the minimum interval between sending out consecutive alerts of the same type */
+ public long _minimumAlertRepeatGap = ApplicationRegistry.getInstance().getConfiguration().getMinimumAlertRepeatGap();
- /** the minimum interval between sending out consequetive alerts of the same type */
- @Configured(path = "minimumAlertRepeatGap", defaultValue = "0")
- public long _minimumAlertRepeatGap;
private static final int MAX_ASYNC_DELIVERIES = 10;
@@ -164,10 +155,9 @@ public class SimpleAMQQueue implements AMQQueue, Subscription.StateListener
}
resetNotifications();
-
}
- private void resetNotifications()
+ public void resetNotifications()
{
// This ensure that the notification checks for the configured alerts are created.
setMaximumMessageAge(_maximumMessageAge);
@@ -193,6 +183,11 @@ public class SimpleAMQQueue implements AMQQueue, Subscription.StateListener
return _autoDelete;
}
+ public boolean isFlowed()
+ {
+ return _entries.isFlowed();
+ }
+
public AMQShortString getOwner()
{
return _owner;
@@ -326,10 +321,6 @@ public class SimpleAMQQueue implements AMQQueue, Subscription.StateListener
public QueueEntry enqueue(StoreContext storeContext, AMQMessage message) throws AMQException
{
-
- incrementQueueCount();
- incrementQueueSize(message);
-
_totalMessagesReceived.incrementAndGet();
QueueEntry entry;
@@ -413,8 +404,11 @@ public class SimpleAMQQueue implements AMQQueue, Subscription.StateListener
if (entry.immediateAndNotDelivered())
{
- dequeue(storeContext, entry);
- entry.dispose(storeContext);
+ //We acquire the message here to ensure that the dequeueAndDelete will correctly remove the content
+ // from the transactionLog. This saves us from having to have a custom dequeueAndDelete that checks
+ // for the AVAILABLE state of an entry rather than the ACQUIRED state that it currently uses.
+ entry.acquire();
+ entry.dequeueAndDelete(storeContext);
}
else if (!(entry.isAcquired() || entry.isDeleted()))
{
@@ -423,7 +417,7 @@ public class SimpleAMQQueue implements AMQQueue, Subscription.StateListener
deliverAsync();
}
- _managedObject.checkForNotification(entry.getMessage());
+ _managedObject.checkForNotification(entry);
return entry;
}
@@ -467,20 +461,11 @@ public class SimpleAMQQueue implements AMQQueue, Subscription.StateListener
// Simple Queues don't :-)
}
- private void incrementQueueSize(final AMQMessage message)
- {
- getAtomicQueueSize().addAndGet(message.getSize());
- }
-
- private void incrementQueueCount()
- {
- getAtomicQueueCount().incrementAndGet();
- }
-
private void deliverMessage(final Subscription sub, final QueueEntry entry)
throws AMQException
{
_deliveredMessages.incrementAndGet();
+
sub.send(entry);
}
@@ -567,10 +552,14 @@ public class SimpleAMQQueue implements AMQQueue, Subscription.StateListener
}
+ /**
+ * Only call from queue Entry
+ * @param storeContext
+ * @param entry
+ * @throws FailedDequeueException
+ */
public void dequeue(StoreContext storeContext, QueueEntry entry) throws FailedDequeueException
{
- decrementQueueCount();
- decrementQueueSize(entry);
if (entry.acquiredBySubscription())
{
_deliveredMessages.decrementAndGet();
@@ -578,12 +567,10 @@ public class SimpleAMQQueue implements AMQQueue, Subscription.StateListener
try
{
- AMQMessage msg = entry.getMessage();
- if (msg.isPersistent())
+ if (entry.isPersistent())
{
- _virtualHost.getTransactionLog().dequeueMessage(storeContext, this, msg.getMessageId());
+ _virtualHost.getTransactionLog().dequeueMessage(storeContext, this, entry.getMessageId());
}
- //entry.dispose(storeContext);
}
catch (MessageCleanupException e)
@@ -601,15 +588,6 @@ public class SimpleAMQQueue implements AMQQueue, Subscription.StateListener
}
- private void decrementQueueSize(final QueueEntry entry)
- {
- getAtomicQueueSize().addAndGet(-entry.getMessage().getSize());
- }
-
- void decrementQueueCount()
- {
- getAtomicQueueCount().decrementAndGet();
- }
public boolean resend(final QueueEntry entry, final Subscription subscription) throws AMQException
{
@@ -655,14 +633,19 @@ public class SimpleAMQQueue implements AMQQueue, Subscription.StateListener
return getMessageCount() == 0;
}
+ public long getMemoryUsageCurrent()
+ {
+ return getQueueInMemory();
+ }
+
public int getMessageCount()
{
- return getAtomicQueueCount().get();
+ return getQueueCount();
}
public long getQueueDepth()
{
- return getAtomicQueueSize().get();
+ return getQueueSize();
}
public int getUndeliveredMessageCount()
@@ -738,14 +721,19 @@ public class SimpleAMQQueue implements AMQQueue, Subscription.StateListener
return _name.compareTo(o.getName());
}
- public AtomicInteger getAtomicQueueCount()
+ public int getQueueCount()
{
- return _atomicQueueCount;
+ return _entries.size();
}
- public AtomicLong getAtomicQueueSize()
+ public long getQueueSize()
{
- return _atomicQueueSize;
+ return _entries.dataSize();
+ }
+
+ public long getQueueInMemory()
+ {
+ return _entries.memoryUsed();
}
private boolean isExclusiveSubscriber()
@@ -772,7 +760,7 @@ public class SimpleAMQQueue implements AMQQueue, Subscription.StateListener
public boolean accept(QueueEntry entry)
{
- final long messageId = entry.getMessage().getMessageId();
+ final long messageId = entry.getMessageId();
return messageId >= fromMessageId && messageId <= toMessageId;
}
@@ -791,7 +779,7 @@ public class SimpleAMQQueue implements AMQQueue, Subscription.StateListener
public boolean accept(QueueEntry entry)
{
- _complete = entry.getMessage().getMessageId() == messageId;
+ _complete = entry.getMessageId() == messageId;
return _complete;
}
@@ -819,11 +807,18 @@ public class SimpleAMQQueue implements AMQQueue, Subscription.StateListener
}
+
public void moveMessagesToAnotherQueue(final long fromMessageId,
final long toMessageId,
String queueName,
StoreContext storeContext)
{
+ // The move is a two step process. First the messages are moved in the _transactionLog.
+ // That is persistent messages are moved queues on disk for recovery and the QueueEntries removed from the
+ // existing queue.
+ // This is done as Queue.enqueue() does not write the data to the transactionLog. In normal message delivery
+ // this is done as the message is recieved.
+ // So The final step is to enqueue the messages on the new queue.
AMQQueue toQueue = getVirtualHost().getQueueRegistry().getQueue(new AMQShortString(queueName));
TransactionLog transactionLog = getVirtualHost().getTransactionLog();
@@ -833,7 +828,7 @@ public class SimpleAMQQueue implements AMQQueue, Subscription.StateListener
public boolean accept(QueueEntry entry)
{
- final long messageId = entry.getMessage().getMessageId();
+ final long messageId = entry.getMessageId();
return (messageId >= fromMessageId)
&& (messageId <= toMessageId)
&& entry.acquire();
@@ -849,16 +844,14 @@ public class SimpleAMQQueue implements AMQQueue, Subscription.StateListener
{
transactionLog.beginTran(storeContext);
- // Move the messages in on the transaction log.
+ // Move the messages in the transaction log.
for (QueueEntry entry : entries)
{
- AMQMessage message = entry.getMessage();
-
- if (message.isPersistent() && toQueue.isDurable())
+ if (entry.isPersistent() && toQueue.isDurable())
{
- transactionLog.enqueueMessage(storeContext, toQueue, message.getMessageId());
+ transactionLog.enqueueMessage(storeContext, toQueue, entry.getMessageId());
}
- // dequeue does not decrement the refence count
+ // dequeue will remove the messages from the queue
entry.dequeue(storeContext);
}
@@ -887,10 +880,13 @@ public class SimpleAMQQueue implements AMQQueue, Subscription.StateListener
try
{
+ // Add messages to new queue
for (QueueEntry entry : entries)
{
toQueue.enqueue(storeContext, entry.getMessage());
-
+ // As we only did a dequeue above now that we have moved the message we should perform a delete.
+ // We cannot do this earlier as the message will be lost if flowed.
+ //entry.delete();
}
}
catch (MessageCleanupException e)
@@ -917,13 +913,13 @@ public class SimpleAMQQueue implements AMQQueue, Subscription.StateListener
public boolean accept(QueueEntry entry)
{
- final long messageId = entry.getMessage().getMessageId();
+ final long messageId = entry.getMessageId();
if ((messageId >= fromMessageId)
&& (messageId <= toMessageId))
{
if (!entry.isDeleted())
{
- return entry.getMessage().incrementReference();
+ return true;
}
}
@@ -943,11 +939,9 @@ public class SimpleAMQQueue implements AMQQueue, Subscription.StateListener
// Move the messages in on the transaction log.
for (QueueEntry entry : entries)
{
- AMQMessage message = entry.getMessage();
-
- if (message.isReferenced() && message.isPersistent() && toQueue.isDurable())
+ if (!entry.isDeleted() && entry.isPersistent() && toQueue.isDurable())
{
- transactionLog.enqueueMessage(storeContext, toQueue, message.getMessageId());
+ transactionLog.enqueueMessage(storeContext, toQueue, entry.getMessageId());
}
}
@@ -978,7 +972,7 @@ public class SimpleAMQQueue implements AMQQueue, Subscription.StateListener
{
for (QueueEntry entry : entries)
{
- if (entry.getMessage().isReferenced())
+ if (!entry.isDeleted())
{
toQueue.enqueue(storeContext, entry.getMessage());
}
@@ -1006,14 +1000,14 @@ public class SimpleAMQQueue implements AMQQueue, Subscription.StateListener
{
QueueEntry node = queueListIterator.getNode();
- final long messageId = node.getMessage().getMessageId();
+ final long messageId = node.getMessageId();
if ((messageId >= fromMessageId)
&& (messageId <= toMessageId)
&& !node.isDeleted()
&& node.acquire())
{
- node.discard(storeContext);
+ node.dequeueAndDelete(storeContext);
}
}
@@ -1037,7 +1031,7 @@ public class SimpleAMQQueue implements AMQQueue, Subscription.StateListener
QueueEntry node = queueListIterator.getNode();
if (!node.isDeleted() && node.acquire())
{
- node.discard(storeContext);
+ node.dequeueAndDelete(storeContext);
noDeletes = false;
}
@@ -1055,7 +1049,7 @@ public class SimpleAMQQueue implements AMQQueue, Subscription.StateListener
QueueEntry node = queueListIterator.getNode();
if (!node.isDeleted() && node.acquire())
{
- node.discard(storeContext);
+ node.dequeueAndDelete(storeContext);
count++;
}
@@ -1106,6 +1100,7 @@ public class SimpleAMQQueue implements AMQQueue, Subscription.StateListener
if (!_stopped.getAndSet(true))
{
ReferenceCountingExecutorService.getInstance().releaseExecutorService();
+ _entries.stop();
}
}
@@ -1320,8 +1315,9 @@ public class SimpleAMQQueue implements AMQQueue, Subscription.StateListener
{
if (node.acquire())
{
+ // creating a new final store context per message seems wasteful.
final StoreContext reapingStoreContext = new StoreContext();
- node.discard(reapingStoreContext);
+ node.dequeueAndDelete(reapingStoreContext);
}
}
QueueEntry newNode = _entries.next(node);
@@ -1423,7 +1419,7 @@ public class SimpleAMQQueue implements AMQQueue, Subscription.StateListener
}
}
- @Override
+
public void checkMessageStatus() throws AMQException
{
@@ -1436,16 +1432,37 @@ public class SimpleAMQQueue implements AMQQueue, Subscription.StateListener
QueueEntry node = queueListIterator.getNode();
if (!node.isDeleted() && node.expired() && node.acquire())
{
- node.discard(storeContext);
+ node.dequeueAndDelete(storeContext);
}
else
{
- _managedObject.checkForNotification(node.getMessage());
+ _managedObject.checkForNotification(node);
}
}
}
+
+ public long getMemoryUsageMaximum()
+ {
+ return _entries.getMemoryUsageMaximum();
+ }
+
+ public void setMemoryUsageMaximum(long maximumMemoryUsage)
+ {
+ _entries.setMemoryUsageMaximum(maximumMemoryUsage);
+ }
+
+ public long getMemoryUsageMinimum()
+ {
+ return _entries.getMemoryUsageMinimum();
+ }
+
+ public void setMemoryUsageMinimum(long minimumMemoryUsage)
+ {
+ _entries.setMemoryUsageMinimum(minimumMemoryUsage);
+ }
+
public long getMinimumAlertRepeatGap()
{
return _minimumAlertRepeatGap;
@@ -1586,14 +1603,19 @@ public class SimpleAMQQueue implements AMQQueue, Subscription.StateListener
for (int i = 0; i < num && !it.atTail(); i++)
{
it.advance();
- ids.add(it.getNode().getMessage().getMessageId());
+ ids.add(it.getNode().getMessageId());
}
return ids;
}
- public void configure(Configuration queueConfiguration)
+
+ public String getType()
{
- Configurator.configure(this, queueConfiguration);
- resetNotifications();
+ return getClass().getSimpleName() + "[" + getName() +"]";
+ }
+
+ public String toString()
+ {
+ return getType() + "[Owner:" + _owner + "][Durable:" + _durable + "]";
}
-} \ No newline at end of file
+}
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 a46c5ae2e8..a10e332ef5 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
@@ -22,8 +22,9 @@ import java.util.concurrent.atomic.AtomicReferenceFieldUpdater;
* under the License.
*
*/
-public class SimpleQueueEntryList implements QueueEntryList
+public class SimpleQueueEntryList extends FlowableBaseQueueEntryList
{
+
private final QueueEntryImpl _head;
private volatile QueueEntryImpl _tail;
@@ -41,12 +42,9 @@ public class SimpleQueueEntryList implements QueueEntryList
AtomicReferenceFieldUpdater.newUpdater
(QueueEntryImpl.class, QueueEntryImpl.class, "_next");
-
-
-
-
public SimpleQueueEntryList(AMQQueue queue)
{
+ super(queue);
_queue = queue;
_head = new QueueEntryImpl(this);
_tail = _head;
@@ -77,6 +75,9 @@ public class SimpleQueueEntryList implements QueueEntryList
public QueueEntry add(AMQMessage message)
{
QueueEntryImpl node = new QueueEntryImpl(this, message);
+
+ incrementCounters(node);
+
for (;;)
{
QueueEntryImpl tail = _tail;
@@ -101,12 +102,12 @@ public class SimpleQueueEntryList implements QueueEntryList
}
}
+
public QueueEntry next(QueueEntry node)
{
return ((QueueEntryImpl)node).getNext();
}
-
public class QueueEntryIteratorImpl implements QueueEntryIterator
{
@@ -172,7 +173,9 @@ public class SimpleQueueEntryList implements QueueEntryList
{
return new SimpleQueueEntryList(queue);
}
+
}
-
+
+
}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/TransientAMQMessage.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/TransientAMQMessage.java
index 8c62e046f8..4c9fe81439 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/TransientAMQMessage.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/TransientAMQMessage.java
@@ -32,21 +32,17 @@ import org.apache.qpid.framing.abstraction.ProtocolVersionMethodConverter;
import org.apache.qpid.server.protocol.AMQProtocolSession;
import org.apache.qpid.server.store.StoreContext;
+import java.util.ArrayList;
+import java.util.Collections;
import java.util.Iterator;
import java.util.List;
-import java.util.Collections;
-import java.util.ArrayList;
import java.util.concurrent.atomic.AtomicInteger;
-/**
- * A deliverable message.
- */
+/** A deliverable message. */
public class TransientAMQMessage implements AMQMessage
{
/** Used for debugging purposes. */
- private static final Logger _log = Logger.getLogger(AMQMessage.class);
-
- private final AtomicInteger _referenceCount = new AtomicInteger(1);
+ protected static final Logger _log = Logger.getLogger(AMQMessage.class);
protected ContentHeaderBody _contentHeaderBody;
@@ -59,24 +55,10 @@ public class TransientAMQMessage implements AMQMessage
protected final Long _messageId;
-
- /** Flag to indicate that this message requires 'immediate' delivery. */
-
- private static final byte IMMEDIATE = 0x01;
-
- /**
- * Flag to indicate whether this message has been delivered to a consumer. Used in implementing return functionality
- * for messages published with the 'immediate' flag.
- */
-
- private static final byte DELIVERED_TO_CONSUMER = 0x02;
-
private byte _flags = 0;
- private long _expiration;
-
private AMQProtocolSession.ProtocolSessionIdentifier _sessionIdentifier;
- private static final byte IMMEDIATE_AND_DELIVERED = (byte) (IMMEDIATE | DELIVERED_TO_CONSUMER);
+ private long _expiration;
/**
* Used to iterate through all the body frames associated with this message. Will not keep all the data in memory
@@ -143,23 +125,23 @@ public class TransientAMQMessage implements AMQMessage
/**
* Used by SimpleAMQQueueTest, TxAckTest.TestMessage, AbstractHeaderExchangeTestBase.Message
* These all need refactoring to some sort of MockAMQMessageFactory.
- */
+ */
@Deprecated
protected TransientAMQMessage(AMQMessage message) throws AMQException
{
_messageId = message.getMessageId();
- _flags = ((TransientAMQMessage)message)._flags;
+ _flags = ((TransientAMQMessage) message)._flags;
_contentHeaderBody = message.getContentHeaderBody();
_messagePublishInfo = message.getMessagePublishInfo();
}
-
/**
* Normal message creation via the MessageFactory uses this constructor
* Package scope limited as MessageFactory should be used
- * @see MessageFactory
*
* @param messageId
+ *
+ * @see MessageFactory
*/
TransientAMQMessage(Long messageId)
{
@@ -168,17 +150,17 @@ public class TransientAMQMessage implements AMQMessage
public String debugIdentity()
{
- return "(HC:" + System.identityHashCode(this) + " ID:" + getMessageId() + " Ref:" + _referenceCount.get() + ")";
+ return "(HC:" + System.identityHashCode(this) + " ID:" + getMessageId() +")";
}
- public void setExpiration(final long expiration)
+ public void setExpiration(long expiration)
{
_expiration = expiration;
}
- public boolean isReferenced()
+ public long getExpiration()
{
- return _referenceCount.get() > 0;
+ return _expiration;
}
public Iterator<AMQDataBlock> getBodyFrameIterator(AMQProtocolSession protocolSession, int channel)
@@ -191,7 +173,6 @@ public class TransientAMQMessage implements AMQMessage
return new BodyContentIterator();
}
-
public ContentHeaderBody getContentHeaderBody()
{
return _contentHeaderBody;
@@ -202,139 +183,6 @@ public class TransientAMQMessage implements AMQMessage
return _messageId;
}
- /**
- * Creates a long-lived reference to this message, and increments the count of such references, as an atomic
- * operation.
- */
- public AMQMessage takeReference()
- {
- incrementReference(); // _referenceCount.incrementAndGet();
-
- return this;
- }
-
- public boolean incrementReference()
- {
- return incrementReference(1);
- }
-
- /* Threadsafe. Increment the reference count on the message. */
- public boolean incrementReference(int count)
- {
- if(_referenceCount.addAndGet(count) <= 1)
- {
- _referenceCount.addAndGet(-count);
- return false;
- }
- else
- {
- return true;
- }
-
- }
-
- /**
- * Threadsafe. This will decrement the reference count and when it reaches zero will remove the message from the
- * message store.
- *
- * @param storeContext
- *
- * @throws MessageCleanupException when an attempt was made to remove the message from the message store and that
- * failed
- */
- public void decrementReference(StoreContext storeContext) throws MessageCleanupException
- {
-
- int count = _referenceCount.decrementAndGet();
-
- // 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
- // the message has been passed to all queues. i.e. we are
- // not relying on the all the increments having taken place before the delivery manager decrements.
- if (count == 0)
- {
- // 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);
-
- try
- {
- // 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
- // no need to perform persistent check anymore as TransientAMQM.removeMessage() is a no-op
- removeMessage(storeContext);
- }
- catch (AMQException e)
- {
- // to maintain consistency, we revert the count
- incrementReference();
- throw new MessageCleanupException(getMessageId(), e);
- }
- }
- else
- {
- if (count < 0)
- {
- throw new MessageCleanupException("Reference count for message id " + debugIdentity()
- + " has gone below 0.");
- }
- }
- }
-
-
- /**
- * Called selectors to determin if the message has already been sent
- *
- * @return _deliveredToConsumer
- */
- public boolean getDeliveredToConsumer()
- {
- return (_flags & DELIVERED_TO_CONSUMER) != 0;
- }
-
- /**
- * Called to enforce the 'immediate' flag.
- *
- * @returns true if the message is marked for immediate delivery but has not been marked as delivered
- * to a consumer
- */
- public boolean immediateAndNotDelivered()
- {
-
- return (_flags & IMMEDIATE_AND_DELIVERED) == IMMEDIATE;
-
- }
-
- /**
- * Checks to see if the message has expired. If it has the message is dequeued.
- *
- * @return true if the message has expire
- *
- * @throws AMQException
- */
- public boolean expired() throws AMQException
- {
-
- if (_expiration != 0L)
- {
- long now = System.currentTimeMillis();
-
- return (now > _expiration);
- }
-
- return false;
- }
-
- /**
- * Called when this message is delivered to a consumer. (used to implement the 'immediate' flag functionality).
- * And for selector efficiency.
- */
- public void setDeliveredToConsumer()
- {
- _flags |= DELIVERED_TO_CONSUMER;
- }
-
public long getSize()
{
@@ -345,7 +193,7 @@ public class TransientAMQMessage implements AMQMessage
{
return _sessionIdentifier.getSessionInstance();
}
-
+
public Object getPublisherIdentifier()
{
return _sessionIdentifier.getSessionIdentifier();
@@ -356,7 +204,7 @@ public class TransientAMQMessage implements AMQMessage
_sessionIdentifier = sessionIdentifier;
}
- /** From AMQMessageHandle **/
+ /** From AMQMessageHandle * */
public int getBodyCount()
{
@@ -365,7 +213,7 @@ public class TransientAMQMessage implements AMQMessage
public ContentChunk getContentChunk(int index)
{
- if(_contentBodies == null)
+ if (_contentBodies == null)
{
throw new RuntimeException("No ContentBody has been set");
}
@@ -381,9 +229,9 @@ public class TransientAMQMessage implements AMQMessage
public void addContentBodyFrame(StoreContext storeContext, ContentChunk contentChunk, boolean isLastContentBody)
throws AMQException
{
- if(_contentBodies == null)
+ if (_contentBodies == null)
{
- if(isLastContentBody)
+ if (isLastContentBody)
{
_contentBodies = Collections.singletonList(contentChunk);
}
@@ -409,11 +257,17 @@ public class TransientAMQMessage implements AMQMessage
return false;
}
+ public boolean isImmediate()
+ {
+ return _messagePublishInfo.isImmediate();
+ }
+
/**
* This is called when all the content has been received.
+ *
* @param storeContext
- *@param messagePublishInfo
- * @param contentHeaderBody @throws AMQException
+ * @param messagePublishInfo
+ * @param contentHeaderBody @throws AMQException
*/
public void setPublishAndContentHeaderBody(StoreContext storeContext, MessagePublishInfo messagePublishInfo,
ContentHeaderBody contentHeaderBody)
@@ -425,26 +279,18 @@ public class TransientAMQMessage implements AMQMessage
throw new NullPointerException("HeaderBody cannot be null");
}
- if( messagePublishInfo == null)
+ if (messagePublishInfo == null)
{
throw new NullPointerException("PublishInfo cannot be null");
}
- _messagePublishInfo = messagePublishInfo;
- _contentHeaderBody = contentHeaderBody;
-
+ _arrivalTime = System.currentTimeMillis();
- if( contentHeaderBody.bodySize == 0)
- {
- _contentBodies = Collections.EMPTY_LIST;
- }
- _arrivalTime = System.currentTimeMillis();
+ _contentHeaderBody = contentHeaderBody;
+ _messagePublishInfo = messagePublishInfo;
- if(messagePublishInfo.isImmediate())
- {
- _flags |= IMMEDIATE;
- }
+ updateHeaderAndFlags();
}
public long getArrivalTime()
@@ -452,9 +298,26 @@ public class TransientAMQMessage implements AMQMessage
return _arrivalTime;
}
- public void removeMessage(StoreContext storeContext) throws AMQException
+ public void recoverFromMessageMetaData(MessageMetaData mmd)
+ {
+ _arrivalTime = mmd.getArrivalTime();
+ _contentHeaderBody = mmd.getContentHeaderBody();
+ _messagePublishInfo = mmd.getMessagePublishInfo();
+
+ updateHeaderAndFlags();
+ }
+
+ private void updateHeaderAndFlags()
+ {
+ if (_contentHeaderBody.bodySize == 0)
+ {
+ _contentBodies = Collections.EMPTY_LIST;
+ }
+ }
+
+ public void recoverContentBodyFrame(ContentChunk contentChunk, boolean isLastContentBody) throws AMQException
{
- //no-op
+ addContentBodyFrame(null, contentChunk, isLastContentBody);
}
@@ -463,7 +326,7 @@ public class TransientAMQMessage implements AMQMessage
// return "Message[" + debugIdentity() + "]: " + _messageId + "; ref count: " + _referenceCount + "; taken : " +
// _taken + " by :" + _takenBySubcription;
- return "Message[" + debugIdentity() + "]: " + getMessageId() + "; ref count: " + _referenceCount;
+ return "Message[" + debugIdentity() + "]: " + getMessageId() ;
}
}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/UnableToFlowMessageException.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/UnableToFlowMessageException.java
new file mode 100644
index 0000000000..03cfed8533
--- /dev/null
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/UnableToFlowMessageException.java
@@ -0,0 +1,29 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.qpid.server.queue;
+
+public class UnableToFlowMessageException extends Exception
+{
+ public UnableToFlowMessageException(long messageId, Exception error)
+ {
+ super("Unable to Flow Message:"+messageId, error);
+ }
+}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/UnableToRecoverMessageException.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/UnableToRecoverMessageException.java
new file mode 100644
index 0000000000..cae5bc6327
--- /dev/null
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/UnableToRecoverMessageException.java
@@ -0,0 +1,29 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.qpid.server.queue;
+
+public class UnableToRecoverMessageException extends RuntimeException
+{
+ public UnableToRecoverMessageException(Exception error)
+ {
+ super(error);
+ }
+}
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 02124a3737..22b4623ae1 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
@@ -20,24 +20,21 @@
*/
package org.apache.qpid.server.registry;
-import org.apache.commons.configuration.Configuration;
+import java.net.InetSocketAddress;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.commons.configuration.ConfigurationException;
import org.apache.log4j.Logger;
-import org.apache.qpid.server.configuration.Configurator;
-import org.apache.qpid.server.virtualhost.VirtualHost;
-import org.apache.qpid.server.virtualhost.VirtualHostRegistry;
+import org.apache.mina.common.IoAcceptor;
+import org.apache.qpid.server.configuration.ServerConfiguration;
import org.apache.qpid.server.management.ManagedObjectRegistry;
-import org.apache.qpid.server.security.auth.manager.AuthenticationManager;
-import org.apache.qpid.server.security.auth.manager.PrincipalDatabaseAuthenticationManager;
-import org.apache.qpid.server.security.auth.database.PrincipalDatabaseManager;
-import org.apache.qpid.server.security.auth.database.ConfigurationFilePrincipalDatabaseManager;
-import org.apache.qpid.server.security.access.ACLPlugin;
-import org.apache.qpid.server.security.access.ACLManager;
import org.apache.qpid.server.plugins.PluginManager;
-import org.apache.mina.common.IoAcceptor;
-
-import java.util.HashMap;
-import java.util.Map;
-import java.net.InetSocketAddress;
+import org.apache.qpid.server.security.access.ACLManager;
+import org.apache.qpid.server.security.auth.database.PrincipalDatabaseManager;
+import org.apache.qpid.server.security.auth.manager.AuthenticationManager;
+import org.apache.qpid.server.virtualhost.VirtualHost;
+import org.apache.qpid.server.virtualhost.VirtualHostRegistry;
/**
* An abstract application registry that provides access to configuration information and handles the
@@ -53,7 +50,7 @@ public abstract class ApplicationRegistry implements IApplicationRegistry
private final Map<Class<?>, Object> _configuredObjects = new HashMap<Class<?>, Object>();
- protected final Configuration _configuration;
+ protected final ServerConfiguration _configuration;
public static final int DEFAULT_INSTANCE = 1;
public static final String DEFAULT_APPLICATION_REGISTRY = "org.apache.qpid.server.util.NullApplicationRegistry";
@@ -154,7 +151,7 @@ public abstract class ApplicationRegistry implements IApplicationRegistry
}
}
- protected ApplicationRegistry(Configuration configuration)
+ protected ApplicationRegistry(ServerConfiguration configuration)
{
_configuration = configuration;
}
@@ -242,7 +239,7 @@ public abstract class ApplicationRegistry implements IApplicationRegistry
}
}
- public Configuration getConfiguration()
+ public ServerConfiguration getConfiguration()
{
return _configuration;
}
@@ -255,26 +252,6 @@ public abstract class ApplicationRegistry implements IApplicationRegistry
}
}
- public <T> T getConfiguredObject(Class<T> instanceType)
- {
- T instance = (T) _configuredObjects.get(instanceType);
- if (instance == null)
- {
- try
- {
- instance = instanceType.newInstance();
- }
- catch (Exception e)
- {
- _logger.error("Unable to instantiate configuration class " + instanceType + " - ensure it has a public default constructor");
- throw new IllegalArgumentException("Unable to instantiate configuration class " + instanceType + " - ensure it has a public default constructor", e);
- }
- Configurator.configure(instance);
- _configuredObjects.put(instanceType, instance);
- }
- return instance;
- }
-
public static void setDefaultApplicationRegistry(String clazz)
{
_APPLICATION_REGISTRY = clazz;
@@ -285,9 +262,9 @@ public abstract class ApplicationRegistry implements IApplicationRegistry
return _virtualHostRegistry;
}
- public ACLManager getAccessManager()
+ public ACLManager getAccessManager() throws ConfigurationException
{
- return new ACLManager(_configuration, _pluginManager);
+ return new ACLManager(_configuration.getSecurityConfiguration(), _pluginManager);
}
public ManagedObjectRegistry getManagedObjectRegistry()
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/registry/ConfigurationFileApplicationRegistry.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/registry/ConfigurationFileApplicationRegistry.java
index c34c4bf80a..39164883f9 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/registry/ConfigurationFileApplicationRegistry.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/registry/ConfigurationFileApplicationRegistry.java
@@ -21,71 +21,25 @@
package org.apache.qpid.server.registry;
import java.io.File;
-import java.util.Collection;
-import java.util.Map;
-import java.util.concurrent.ConcurrentHashMap;
-import org.apache.commons.configuration.CompositeConfiguration;
-import org.apache.commons.configuration.Configuration;
import org.apache.commons.configuration.ConfigurationException;
-import org.apache.commons.configuration.SystemConfiguration;
-import org.apache.commons.configuration.XMLConfiguration;
+import org.apache.qpid.AMQException;
+import org.apache.qpid.server.configuration.ServerConfiguration;
import org.apache.qpid.server.management.JMXManagedObjectRegistry;
-import org.apache.qpid.server.management.ManagedObjectRegistry;
-import org.apache.qpid.server.management.ManagementConfiguration;
import org.apache.qpid.server.management.NoopManagedObjectRegistry;
import org.apache.qpid.server.plugins.PluginManager;
-import org.apache.qpid.server.security.auth.manager.AuthenticationManager;
+import org.apache.qpid.server.security.access.ACLManager;
import org.apache.qpid.server.security.auth.database.ConfigurationFilePrincipalDatabaseManager;
-import org.apache.qpid.server.security.auth.database.PrincipalDatabaseManager;
import org.apache.qpid.server.security.auth.manager.PrincipalDatabaseAuthenticationManager;
-import org.apache.qpid.server.security.access.ACLPlugin;
-import org.apache.qpid.server.security.access.ACLManager;
import org.apache.qpid.server.virtualhost.VirtualHost;
import org.apache.qpid.server.virtualhost.VirtualHostRegistry;
-import org.apache.qpid.AMQException;
public class ConfigurationFileApplicationRegistry extends ApplicationRegistry
{
public ConfigurationFileApplicationRegistry(File configurationURL) throws ConfigurationException
{
- super(config(configurationURL));
- }
-
- // Our configuration class needs to make the interpolate method
- // public so it can be called below from the config method.
- private static class MyConfiguration extends CompositeConfiguration
- {
- public String interpolate(String obj)
- {
- return super.interpolate(obj);
- }
- }
-
- private static final Configuration config(File url) throws ConfigurationException
- {
- // We have to override the interpolate methods so that
- // interpolation takes place accross the entirety of the
- // composite configuration. Without doing this each
- // configuration object only interpolates variables defined
- // inside itself.
- final MyConfiguration conf = new MyConfiguration();
- conf.addConfiguration(new SystemConfiguration()
- {
- protected String interpolate(String o)
- {
- return conf.interpolate(o);
- }
- });
- conf.addConfiguration(new XMLConfiguration(url)
- {
- protected String interpolate(String o)
- {
- return conf.interpolate(o);
- }
- });
- return conf;
+ super(new ServerConfiguration(configurationURL));
}
public void initialise() throws Exception
@@ -94,9 +48,9 @@ public class ConfigurationFileApplicationRegistry extends ApplicationRegistry
_virtualHostRegistry = new VirtualHostRegistry();
- _pluginManager = new PluginManager(_configuration.getString("plugin-directory"));
+ _pluginManager = new PluginManager(_configuration.getPluginDirectory());
- _accessManager = new ACLManager(_configuration, _pluginManager);
+ _accessManager = new ACLManager(_configuration.getSecurityConfiguration(), _pluginManager);
_databaseManager = new ConfigurationFilePrincipalDatabaseManager(_configuration);
@@ -111,18 +65,17 @@ public class ConfigurationFileApplicationRegistry extends ApplicationRegistry
}
private void initialiseVirtualHosts() throws Exception
- {
- for (String name : getVirtualHostNames())
+ {
+ for (String name : _configuration.getVirtualHosts())
{
-
- _virtualHostRegistry.registerVirtualHost(new VirtualHost(name, getConfiguration().subset("virtualhosts.virtualhost." + name)));
+ _virtualHostRegistry.registerVirtualHost(new VirtualHost(_configuration.getVirtualHostConfig(name)));
}
+ getVirtualHostRegistry().setDefaultVirtualHostName(_configuration.getDefaultVirtualHost());
}
private void initialiseManagedObjectRegistry() throws AMQException
{
- ManagementConfiguration config = getConfiguredObject(ManagementConfiguration.class);
- if (config.enabled)
+ if (_configuration.getManagementEnabled())
{
_managedObjectRegistry = new JMXManagedObjectRegistry();
}
@@ -131,10 +84,4 @@ public class ConfigurationFileApplicationRegistry extends ApplicationRegistry
_managedObjectRegistry = new NoopManagedObjectRegistry();
}
}
-
- public Collection<String> getVirtualHostNames()
- {
- return getConfiguration().getList("virtualhosts.virtualhost.name");
- }
-
}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/registry/IApplicationRegistry.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/registry/IApplicationRegistry.java
index e68dca285c..bbfda3addc 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/registry/IApplicationRegistry.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/registry/IApplicationRegistry.java
@@ -24,6 +24,8 @@ import java.util.Collection;
import java.net.InetSocketAddress;
import org.apache.commons.configuration.Configuration;
+import org.apache.commons.configuration.ConfigurationException;
+import org.apache.qpid.server.configuration.ServerConfiguration;
import org.apache.qpid.server.management.ManagedObjectRegistry;
import org.apache.qpid.server.plugins.PluginManager;
import org.apache.qpid.server.security.auth.manager.AuthenticationManager;
@@ -49,21 +51,11 @@ public interface IApplicationRegistry
void close() throws Exception;
/**
- * This gets access to a "configured object". A configured object has fields populated from a the configuration
- * object (Commons Configuration) automatically, where it has the appropriate attributes defined on fields.
- * Application registry implementations can choose the refresh strategy or caching approach.
- * @param instanceType the type of object you want initialised. This must be unique - i.e. you can only
- * have a single object of this type in the system.
- * @return the configured object
- */
- <T> T getConfiguredObject(Class<T> instanceType);
-
- /**
* Get the low level configuration. For use cases where the configured object approach is not required
* you can get the complete configuration information.
* @return a Commons Configuration instance
*/
- Configuration getConfiguration();
+ ServerConfiguration getConfiguration();
ManagedObjectRegistry getManagedObjectRegistry();
@@ -71,11 +63,9 @@ public interface IApplicationRegistry
AuthenticationManager getAuthenticationManager();
- Collection<String> getVirtualHostNames();
-
VirtualHostRegistry getVirtualHostRegistry();
- ACLManager getAccessManager();
+ ACLManager getAccessManager() throws ConfigurationException;
PluginManager getPluginManager();
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/routing/RoutingTable.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/routing/RoutingTable.java
index 6344127b24..0c62638710 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/routing/RoutingTable.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/routing/RoutingTable.java
@@ -23,6 +23,7 @@ package org.apache.qpid.server.routing;
import org.apache.qpid.AMQException;
import org.apache.qpid.framing.AMQShortString;
import org.apache.qpid.framing.FieldTable;
+import org.apache.qpid.server.configuration.VirtualHostConfiguration;
import org.apache.qpid.server.exchange.Exchange;
import org.apache.qpid.server.queue.AMQQueue;
import org.apache.qpid.server.virtualhost.VirtualHost;
@@ -41,7 +42,7 @@ public interface RoutingTable
*
* @throws Exception If any error occurs that means the store is unable to configure itself.
*/
- void configure(VirtualHost virtualHost, String base, Configuration config) throws Exception;
+ void configure(VirtualHost virtualHost, String base, VirtualHostConfiguration config) throws Exception;
/**
* Called to close and cleanup any resources used by the message store.
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/access/ACLManager.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/access/ACLManager.java
index 356ee815dd..6f7f66fad2 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/access/ACLManager.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/access/ACLManager.java
@@ -28,8 +28,12 @@ import java.util.Map;
import java.util.Map.Entry;
import org.apache.commons.configuration.Configuration;
+import org.apache.commons.configuration.ConfigurationException;
import org.apache.log4j.Logger;
import org.apache.qpid.framing.AMQShortString;
+import org.apache.qpid.server.configuration.SecurityConfiguration;
+import org.apache.qpid.server.configuration.ServerConfiguration;
+import org.apache.qpid.server.configuration.VirtualHostConfiguration;
import org.apache.qpid.server.exchange.Exchange;
import org.apache.qpid.server.plugins.PluginManager;
import org.apache.qpid.server.protocol.AMQProtocolSession;
@@ -46,12 +50,12 @@ public class ACLManager
private Map<String, ACLPlugin> _globalPlugins = new HashMap<String, ACLPlugin>();
private Map<String, ACLPlugin> _hostPlugins = new HashMap<String, ACLPlugin>();
- public ACLManager(Configuration configuration, PluginManager manager)
+ public ACLManager(SecurityConfiguration configuration, PluginManager manager) throws ConfigurationException
{
this(configuration, manager, null);
}
- public ACLManager(Configuration configuration, PluginManager manager, ACLPluginFactory securityPlugin)
+ public ACLManager(SecurityConfiguration configuration, PluginManager manager, ACLPluginFactory securityPlugin) throws ConfigurationException
{
_pluginManager = manager;
@@ -70,14 +74,14 @@ public class ACLManager
}
- public void configureHostPlugins(Configuration hostConfig)
+ public void configureHostPlugins(SecurityConfiguration hostConfig) throws ConfigurationException
{
_hostPlugins = configurePlugins(hostConfig);
}
- public Map<String, ACLPlugin> configurePlugins(Configuration configuration)
+ public Map<String, ACLPlugin> configurePlugins(SecurityConfiguration hostConfig) throws ConfigurationException
{
- Configuration securityConfig = configuration.subset("security");
+ Configuration securityConfig = hostConfig.getConfiguration();
Map<String, ACLPlugin> plugins = new HashMap<String, ACLPlugin>();
Iterator keys = securityConfig.getKeys();
Collection<String> handledTags = new HashSet();
@@ -86,7 +90,6 @@ public class ACLManager
// Splitting the string is necessary here because of the way that getKeys() returns only
// bottom level children
String tag = ((String) keys.next()).split("\\.", 2)[0];
-
if (!handledTags.contains(tag))
{
for (ACLPluginFactory plugin : _allSecurityPlugins.values())
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/access/ACLPlugin.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/access/ACLPlugin.java
index ca760f3360..032184ec39 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/access/ACLPlugin.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/access/ACLPlugin.java
@@ -21,6 +21,7 @@
package org.apache.qpid.server.security.access;
import org.apache.commons.configuration.Configuration;
+import org.apache.commons.configuration.ConfigurationException;
import org.apache.qpid.framing.AMQShortString;
import org.apache.qpid.server.exchange.Exchange;
import org.apache.qpid.server.protocol.AMQProtocolSession;
@@ -36,7 +37,7 @@ public interface ACLPlugin
ABSTAIN
}
- void setConfiguration(Configuration config);
+ void setConfiguration(Configuration config) throws ConfigurationException;
// These return true if the plugin thinks the action should be allowed, and false if not.
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/access/ACLPluginFactory.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/access/ACLPluginFactory.java
index aee6af93d0..256f093477 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/access/ACLPluginFactory.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/access/ACLPluginFactory.java
@@ -21,12 +21,13 @@
package org.apache.qpid.server.security.access;
import org.apache.commons.configuration.Configuration;
+import org.apache.commons.configuration.ConfigurationException;
public interface ACLPluginFactory
{
public boolean supportsTag(String name);
- public ACLPlugin newInstance(Configuration config);
+ public ACLPlugin newInstance(Configuration config) throws ConfigurationException;
}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/access/management/AMQUserManagementMBean.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/access/management/AMQUserManagementMBean.java
index f04aecd0a5..121f571abe 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/access/management/AMQUserManagementMBean.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/access/management/AMQUserManagementMBean.java
@@ -64,9 +64,9 @@ public class AMQUserManagementMBean extends AMQManagedObject implements UserMana
private static final Logger _logger = Logger.getLogger(AMQUserManagementMBean.class);
private PrincipalDatabase _principalDatabase;
- private String _accessFileName;
private Properties _accessRights;
- // private File _accessFile;
+ private File _accessFile;
+
private ReentrantLock _accessRightsUpdate = new ReentrantLock();
// Setup for the TabularType
@@ -104,7 +104,7 @@ public class AMQUserManagementMBean extends AMQManagedObject implements UserMana
public AMQUserManagementMBean() throws JMException
{
- super(UserManagement.class, UserManagement.TYPE);
+ super(UserManagement.class, UserManagement.TYPE, UserManagement.VERSION);
}
public String getObjectInstanceName()
@@ -129,9 +129,10 @@ public class AMQUserManagementMBean extends AMQManagedObject implements UserMana
public boolean setRights(String username, boolean read, boolean write, boolean admin)
{
- if (_accessRights.get(username) == null)
+ Object oldRights = null;
+ if ((oldRights =_accessRights.get(username)) == null)
{
- // If the user doesn't exist in the user rights file check that they at least have an account.
+ // If the user doesn't exist in the access rights file check that they at least have an account.
if (_principalDatabase.getUser(username) == null)
{
return false;
@@ -140,7 +141,6 @@ public class AMQUserManagementMBean extends AMQManagedObject implements UserMana
try
{
-
_accessRightsUpdate.lock();
// Update the access rights
@@ -166,8 +166,29 @@ public class AMQUserManagementMBean extends AMQManagedObject implements UserMana
_accessRights.remove(username);
}
}
+
+ //save the rights file
+ try
+ {
+ saveAccessFile();
+ }
+ catch (IOException e)
+ {
+ _logger.warn("Problem occured saving '" + _accessFile + "', the access right changes will not be preserved: " + e);
- saveAccessFile();
+ //the rights file was not successfully saved, restore user rights to previous value
+ _logger.warn("Reverting attempted rights update for user'" + username + "'");
+ if (oldRights != null)
+ {
+ _accessRights.put(username, oldRights);
+ }
+ else
+ {
+ _accessRights.remove(username);
+ }
+
+ return false;
+ }
}
finally
{
@@ -184,9 +205,23 @@ public class AMQUserManagementMBean extends AMQManagedObject implements UserMana
{
if (_principalDatabase.createPrincipal(new UsernamePrincipal(username), password))
{
- _accessRights.put(username, "");
-
- return setRights(username, read, write, admin);
+ if (!setRights(username, read, write, admin))
+ {
+ //unable to set rights for user, remove account
+ try
+ {
+ _principalDatabase.deletePrincipal(new UsernamePrincipal(username));
+ }
+ catch (AccountNotFoundException e)
+ {
+ //ignore
+ }
+ return false;
+ }
+ else
+ {
+ return true;
+ }
}
return false;
@@ -194,7 +229,6 @@ public class AMQUserManagementMBean extends AMQManagedObject implements UserMana
public boolean deleteUser(String username)
{
-
try
{
if (_principalDatabase.deletePrincipal(new UsernamePrincipal(username)))
@@ -204,7 +238,16 @@ public class AMQUserManagementMBean extends AMQManagedObject implements UserMana
_accessRightsUpdate.lock();
_accessRights.remove(username);
- saveAccessFile();
+
+ try
+ {
+ saveAccessFile();
+ }
+ catch (IOException e)
+ {
+ _logger.warn("Problem occured saving '" + _accessFile + "', the access right changes will not be preserved: " + e);
+ return false;
+ }
}
finally
{
@@ -213,15 +256,15 @@ public class AMQUserManagementMBean extends AMQManagedObject implements UserMana
_accessRightsUpdate.unlock();
}
}
- return true;
}
}
catch (AccountNotFoundException e)
{
_logger.warn("Attempt to delete user (" + username + ") that doesn't exist");
+ return false;
}
- return false;
+ return true;
}
public boolean reloadData()
@@ -233,12 +276,12 @@ public class AMQUserManagementMBean extends AMQManagedObject implements UserMana
}
catch (ConfigurationException e)
{
- _logger.info("Reload failed due to:" + e);
+ _logger.warn("Reload failed due to:" + e);
return false;
}
catch (IOException e)
{
- _logger.info("Reload failed due to:" + e);
+ _logger.warn("Reload failed due to:" + e);
return false;
}
// Reload successful
@@ -320,10 +363,24 @@ public class AMQUserManagementMBean extends AMQManagedObject implements UserMana
*/
public void setAccessFile(String accessFile) throws IOException, ConfigurationException
{
- _accessFileName = accessFile;
-
- if (_accessFileName != null)
+ if (accessFile != null)
{
+ _accessFile = new File(accessFile);
+ if (!_accessFile.exists())
+ {
+ throw new ConfigurationException("'" + _accessFile + "' does not exist");
+ }
+
+ if (!_accessFile.canRead())
+ {
+ throw new ConfigurationException("Cannot read '" + _accessFile + "'.");
+ }
+
+ if (!_accessFile.canWrite())
+ {
+ _logger.warn("Unable to write to access rights file '" + _accessFile + "', changes will not be preserved.");
+ }
+
loadAccessFile();
}
else
@@ -334,39 +391,34 @@ public class AMQUserManagementMBean extends AMQManagedObject implements UserMana
private void loadAccessFile() throws IOException, ConfigurationException
{
- try
+ if(_accessFile == null)
{
- _accessRightsUpdate.lock();
-
- Properties accessRights = new Properties();
-
- File accessFile = new File(_accessFileName);
-
- if (!accessFile.exists())
+ _logger.error("No jmx access rights file has been specified.");
+ return;
+ }
+
+ if(_accessFile.exists())
+ {
+ try
{
- throw new ConfigurationException("'" + _accessFileName + "' does not exist");
- }
+ _accessRightsUpdate.lock();
- if (!accessFile.canRead())
- {
- throw new ConfigurationException("Cannot read '" + _accessFileName + "'.");
+ Properties accessRights = new Properties();
+ accessRights.load(new FileInputStream(_accessFile));
+ checkAccessRights(accessRights);
+ setAccessRights(accessRights);
}
-
- if (!accessFile.canWrite())
+ finally
{
- _logger.warn("Unable to write to access file '" + _accessFileName + "' changes will not be preserved.");
+ if (_accessRightsUpdate.isHeldByCurrentThread())
+ {
+ _accessRightsUpdate.unlock();
+ }
}
-
- accessRights.load(new FileInputStream(accessFile));
- checkAccessRights(accessRights);
- setAccessRights(accessRights);
}
- finally
+ else
{
- if (_accessRightsUpdate.isHeldByCurrentThread())
- {
- _accessRightsUpdate.unlock();
- }
+ _logger.error("Specified jmxaccess rights file '" + _accessFile + "' does not exist.");
}
}
@@ -385,33 +437,24 @@ public class AMQUserManagementMBean extends AMQManagedObject implements UserMana
}
}
- private void saveAccessFile()
+ private void saveAccessFile() throws IOException
{
try
{
_accessRightsUpdate.lock();
- try
- {
- // Create temporary file
- File tmp = File.createTempFile(_accessFileName, ".tmp");
- // Rename current file
- File rights = new File(_accessFileName);
+ // Create temporary file
+ File tmp = File.createTempFile(_accessFile.getName(), ".tmp");
- FileOutputStream output = new FileOutputStream(tmp);
- _accessRights.store(output, "Generated by AMQUserManagementMBean Console : Last edited by user:" + getCurrentJMXUser());
- output.close();
+ FileOutputStream output = new FileOutputStream(tmp);
+ _accessRights.store(output, "Generated by AMQUserManagementMBean Console : Last edited by user:" + getCurrentJMXUser());
+ output.close();
- // Rename new file to main file
- tmp.renameTo(rights);
+ // Rename new file to main file
+ tmp.renameTo(_accessFile);
- // delete tmp
- tmp.delete();
- }
- catch (IOException e)
- {
- _logger.warn("Problem occured saving '" + _accessFileName + "' changes may not be preserved. :" + e);
- }
+ // delete tmp
+ tmp.delete();
}
finally
{
@@ -420,6 +463,7 @@ public class AMQUserManagementMBean extends AMQManagedObject implements UserMana
_accessRightsUpdate.unlock();
}
}
+
}
private String getCurrentJMXUser()
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/access/management/UserManagement.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/access/management/UserManagement.java
index 658d7ebbd3..9fcdd4cd17 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/access/management/UserManagement.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/access/management/UserManagement.java
@@ -33,7 +33,9 @@ import java.io.IOException;
public interface UserManagement
{
+
String TYPE = "UserManagement";
+ int VERSION = 2;
//********** Operations *****************//
/**
@@ -115,4 +117,5 @@ public interface UserManagement
impact = MBeanOperationInfo.INFO)
TabularData viewUsers();
+
}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/access/plugins/LegacyAccessPlugin.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/access/plugins/LegacyAccessPlugin.java
new file mode 100644
index 0000000000..fc1bc048d4
--- /dev/null
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/access/plugins/LegacyAccessPlugin.java
@@ -0,0 +1,71 @@
+/*
+ * 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.security.access.plugins;
+
+import java.util.Collection;
+import java.util.HashSet;
+
+import org.apache.commons.configuration.Configuration;
+import org.apache.qpid.server.security.access.ACLPlugin;
+import org.apache.qpid.server.security.access.ACLPluginFactory;
+
+/**
+ *
+ * Used to suppress warnings in legacy config files that have things in <security> which aren't handled by a plugin directly.
+ *
+ */
+public class LegacyAccessPlugin extends BasicACLPlugin
+{
+ public static final ACLPluginFactory FACTORY = new ACLPluginFactory()
+ {
+ private Collection maskedTags = new HashSet<String>();
+ {
+ maskedTags.add("principal-databases");
+ maskedTags.add("access");
+ maskedTags.add("msg-auth");
+ maskedTags.add("false");
+ maskedTags.add("jmx");
+ }
+
+ public boolean supportsTag(String name)
+ {
+ return maskedTags .contains(name);
+ }
+
+ public ACLPlugin newInstance(Configuration config)
+ {
+ return new LegacyAccessPlugin();
+ }
+ };
+
+ public String getPluginName()
+ {
+ return getClass().getSimpleName();
+ }
+
+ @Override
+ protected AuthzResult getResult()
+ {
+ // Always abstain
+ return AuthzResult.ABSTAIN;
+ }
+
+}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/access/plugins/network/FirewallFactory.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/access/plugins/network/FirewallFactory.java
index 7fcf4a0494..a1a399e5bf 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/access/plugins/network/FirewallFactory.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/access/plugins/network/FirewallFactory.java
@@ -21,6 +21,7 @@
package org.apache.qpid.server.security.access.plugins.network;
import org.apache.commons.configuration.Configuration;
+import org.apache.commons.configuration.ConfigurationException;
import org.apache.qpid.server.security.access.ACLPlugin;
import org.apache.qpid.server.security.access.ACLPluginFactory;
@@ -28,7 +29,7 @@ public class FirewallFactory implements ACLPluginFactory
{
@Override
- public ACLPlugin newInstance(Configuration config)
+ public ACLPlugin newInstance(Configuration config) throws ConfigurationException
{
FirewallPlugin plugin = new FirewallPlugin();
plugin.setConfiguration(config);
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/access/plugins/network/FirewallPlugin.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/access/plugins/network/FirewallPlugin.java
index cb8b6f6fed..85026121ab 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/access/plugins/network/FirewallPlugin.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/access/plugins/network/FirewallPlugin.java
@@ -23,12 +23,19 @@ package org.apache.qpid.server.security.access.plugins.network;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.SocketAddress;
+import java.util.Iterator;
import java.util.List;
+import java.util.concurrent.atomic.AtomicBoolean;
import java.util.regex.Pattern;
+import org.apache.commons.configuration.CompositeConfiguration;
import org.apache.commons.configuration.Configuration;
+import org.apache.commons.configuration.ConfigurationException;
+import org.apache.commons.configuration.XMLConfiguration;
import org.apache.qpid.server.protocol.AMQMinaProtocolSession;
import org.apache.qpid.server.protocol.AMQProtocolSession;
+import org.apache.qpid.server.security.access.ACLPlugin;
+import org.apache.qpid.server.security.access.ACLPluginFactory;
import org.apache.qpid.server.security.access.plugins.AbstractACLPlugin;
import org.apache.qpid.server.virtualhost.VirtualHost;
import org.apache.qpid.util.NetMatcher;
@@ -36,9 +43,27 @@ import org.apache.qpid.util.NetMatcher;
public class FirewallPlugin extends AbstractACLPlugin
{
+ public class FirewallPluginException extends Exception {}
+
+ public static final ACLPluginFactory FACTORY = new ACLPluginFactory()
+ {
+ public boolean supportsTag(String name)
+ {
+ return name.startsWith("firewall");
+ }
+
+ public ACLPlugin newInstance(Configuration config) throws ConfigurationException
+ {
+ FirewallPlugin plugin = new FirewallPlugin();
+ plugin.setConfiguration(config);
+ return plugin;
+ }
+ };
+
public class FirewallRule
{
+ private static final long DNS_TIMEOUT = 30000;
private AuthzResult _access;
private NetMatcher _network;
private Pattern[] _hostnamePatterns;
@@ -76,11 +101,15 @@ public class FirewallPlugin extends AbstractACLPlugin
return networkStrings;
}
- public boolean match(InetAddress remote)
+ public boolean match(InetAddress remote) throws FirewallPluginException
{
if (_hostnamePatterns != null)
{
- String hostname = remote.getCanonicalHostName();
+ String hostname = getHostname(remote);
+ if (hostname == null)
+ {
+ throw new FirewallPluginException();
+ }
for (Pattern pattern : _hostnamePatterns)
{
if (pattern.matcher(hostname).matches())
@@ -96,6 +125,48 @@ public class FirewallPlugin extends AbstractACLPlugin
}
}
+ /**
+ * @param remote the InetAddress to look up
+ * @return the hostname, null if not found or takes longer than 30s to find
+ */
+ private String getHostname(final InetAddress remote)
+ {
+ final String[] hostname = new String[]{null};
+ final AtomicBoolean done = new AtomicBoolean(false);
+ // Spawn thread
+ Thread thread = new Thread(new Runnable()
+ {
+ public void run()
+ {
+ hostname[0] = remote.getCanonicalHostName();
+ done.getAndSet(true);
+ synchronized (done)
+ {
+ done.notifyAll();
+ }
+ }
+ });
+
+ thread.run();
+ long endTime = System.currentTimeMillis() + DNS_TIMEOUT;
+
+ while (System.currentTimeMillis() < endTime && !done.get())
+ {
+ try
+ {
+ synchronized (done)
+ {
+ done.wait(endTime - System.currentTimeMillis());
+ }
+ }
+ catch (InterruptedException e)
+ {
+ // Check the time and if necessary sleep for a bit longer
+ }
+ }
+ return hostname[0];
+ }
+
public AuthzResult getAccess()
{
return _access;
@@ -125,7 +196,14 @@ public class FirewallPlugin extends AbstractACLPlugin
boolean match = false;
for (FirewallRule rule : _rules)
{
- match = rule.match(addr);
+ try
+ {
+ match = rule.match(addr);
+ }
+ catch (FirewallPluginException e)
+ {
+ return AuthzResult.DENIED;
+ }
if (match)
{
return rule.getAccess();
@@ -149,7 +227,7 @@ public class FirewallPlugin extends AbstractACLPlugin
}
@Override
- public void setConfiguration(Configuration config)
+ public void setConfiguration(Configuration config) throws ConfigurationException
{
// Get default action
String defaultAction = config.getString("[@default-action]");
@@ -165,15 +243,21 @@ public class FirewallPlugin extends AbstractACLPlugin
{
_default = AuthzResult.DENIED;
}
+ CompositeConfiguration finalConfig = new CompositeConfiguration(config);
+
+ List subFiles = config.getList("firewall.xml[@fileName]");
+ for (Object subFile : subFiles)
+ {
+ finalConfig.addConfiguration(new XMLConfiguration((String) subFile));
+ }
- int numRules = config.getList("rule[@access]").size(); // all rules must
- // have an access
- // attribute
+ // all rules must have an access attribute
+ int numRules = finalConfig.getList("rule[@access]").size();
_rules = new FirewallRule[numRules];
for (int i = 0; i < numRules; i++)
{
- FirewallRule rule = new FirewallRule(config.getString("rule(" + i + ")[@access]"), config.getList("rule("
- + i + ")[@network]"), config.getList("rule(" + i + ")[@hostname]"));
+ FirewallRule rule = new FirewallRule(finalConfig.getString("rule(" + i + ")[@access]"), finalConfig.getList("rule("
+ + i + ")[@network]"), finalConfig.getList("rule(" + i + ")[@hostname]"));
_rules[i] = rule;
}
}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/Base64MD5PasswordFilePrincipalDatabase.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/Base64MD5PasswordFilePrincipalDatabase.java
index 69ad9014db..3c211746e3 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/Base64MD5PasswordFilePrincipalDatabase.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/Base64MD5PasswordFilePrincipalDatabase.java
@@ -152,8 +152,39 @@ public class Base64MD5PasswordFilePrincipalDatabase implements PrincipalDatabase
public boolean verifyPassword(String principal, char[] password) throws AccountNotFoundException
{
char[] pwd = lookupPassword(principal);
+
+ if (pwd == null)
+ {
+ throw new AccountNotFoundException("Unable to lookup the specfied users password");
+ }
+
+ byte[] byteArray = new byte[password.length];
+ int index = 0;
+ for (char c : password)
+ {
+ byteArray[index++] = (byte) c;
+ }
+
+ byte[] MD5byteArray;
+ try
+ {
+ MD5byteArray = HashedUser.getMD5(byteArray);
+ }
+ catch (Exception e1)
+ {
+ _logger.warn("Unable to hash password for user '" + principal + "' for comparison");
+ return false;
+ }
+
+ char[] hashedPassword = new char[MD5byteArray.length];
- return compareCharArray(pwd, password);
+ index = 0;
+ for (byte c : MD5byteArray)
+ {
+ hashedPassword[index++] = (char) c;
+ }
+
+ return compareCharArray(pwd, hashedPassword);
}
private boolean compareCharArray(char[] a, char[] b)
@@ -193,7 +224,7 @@ public class Base64MD5PasswordFilePrincipalDatabase implements PrincipalDatabase
{
_userUpdate.lock();
char[] orig = user.getPassword();
- user.setPassword(password);
+ user.setPassword(password,false);
try
{
@@ -204,7 +235,7 @@ public class Base64MD5PasswordFilePrincipalDatabase implements PrincipalDatabase
_logger.error("Unable to save password file, password change for user'"
+ principal + "' will revert at restart");
//revert the password change
- user.setPassword(orig);
+ user.setPassword(orig,true);
return false;
}
return true;
@@ -230,7 +261,17 @@ public class Base64MD5PasswordFilePrincipalDatabase implements PrincipalDatabase
return false;
}
- HashedUser user = new HashedUser(principal.getName(), password);
+ HashedUser user;
+ try
+ {
+ user = new HashedUser(principal.getName(), password);
+ }
+ catch (Exception e1)
+ {
+ _logger.warn("Unable to create new user '" + principal.getName() + "'");
+ return false;
+ }
+
try
{
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/ConfigurationFilePrincipalDatabaseManager.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/ConfigurationFilePrincipalDatabaseManager.java
index fc96776a3a..e0d4c49af1 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/ConfigurationFilePrincipalDatabaseManager.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/ConfigurationFilePrincipalDatabaseManager.java
@@ -34,6 +34,7 @@ import org.apache.log4j.Logger;
import org.apache.qpid.configuration.PropertyUtils;
import org.apache.qpid.configuration.PropertyException;
+import org.apache.qpid.server.configuration.ServerConfiguration;
import org.apache.qpid.server.registry.ApplicationRegistry;
import org.apache.qpid.server.security.auth.database.PrincipalDatabase;
import org.apache.qpid.server.security.auth.database.PrincipalDatabaseManager;
@@ -46,20 +47,18 @@ public class ConfigurationFilePrincipalDatabaseManager implements PrincipalDatab
{
private static final Logger _logger = Logger.getLogger(ConfigurationFilePrincipalDatabaseManager.class);
- private static final String _base = "security.principal-databases.principal-database";
-
Map<String, PrincipalDatabase> _databases;
- public ConfigurationFilePrincipalDatabaseManager(Configuration configuration) throws Exception
+ public ConfigurationFilePrincipalDatabaseManager(ServerConfiguration _configuration) throws Exception
{
_logger.info("Initialising PrincipleDatabase authentication manager");
- _databases = initialisePrincipalDatabases(configuration);
+ _databases = initialisePrincipalDatabases(_configuration);
}
- private Map<String, PrincipalDatabase> initialisePrincipalDatabases(Configuration configuration) throws Exception
+ private Map<String, PrincipalDatabase> initialisePrincipalDatabases(ServerConfiguration _configuration) throws Exception
{
- List<String> databaseNames = configuration.getList(_base + ".name");
- List<String> databaseClasses = configuration.getList(_base + ".class");
+ List<String> databaseNames = _configuration.getPrincipalDatabaseNames();
+ List<String> databaseClasses = _configuration.getPrincipalDatabaseClass();
Map<String, PrincipalDatabase> databases = new HashMap<String, PrincipalDatabase>();
if (databaseNames.size() == 0)
@@ -84,7 +83,7 @@ public class ConfigurationFilePrincipalDatabaseManager implements PrincipalDatab
throw new Exception("Principal databases must implement the PrincipalDatabase interface");
}
- initialisePrincipalDatabase((PrincipalDatabase) o, configuration, i);
+ initialisePrincipalDatabase((PrincipalDatabase) o, _configuration, i);
String name = databaseNames.get(i);
if ((name == null) || (name.length() == 0))
@@ -105,12 +104,11 @@ public class ConfigurationFilePrincipalDatabaseManager implements PrincipalDatab
return databases;
}
- private void initialisePrincipalDatabase(PrincipalDatabase principalDatabase, Configuration config, int index)
+ private void initialisePrincipalDatabase(PrincipalDatabase principalDatabase, ServerConfiguration _configuration, int index)
throws FileNotFoundException, ConfigurationException
{
- String baseName = _base + "(" + index + ").attributes.attribute.";
- List<String> argumentNames = config.getList(baseName + "name");
- List<String> argumentValues = config.getList(baseName + "value");
+ List<String> argumentNames = _configuration.getPrincipalDatabaseAttributeNames(index);
+ List<String> argumentValues = _configuration.getPrincipalDatabaseAttributeValues(index);
for (int i = 0; i < argumentNames.size(); i++)
{
String argName = argumentNames.get(i);
@@ -166,18 +164,17 @@ public class ConfigurationFilePrincipalDatabaseManager implements PrincipalDatab
return _databases;
}
- public void initialiseManagement(Configuration config) throws ConfigurationException
+ public void initialiseManagement(ServerConfiguration config) throws ConfigurationException
{
try
{
AMQUserManagementMBean _mbean = new AMQUserManagementMBean();
- String baseSecurity = "security.jmx";
- List<String> principalDBs = config.getList(baseSecurity + ".principal-database");
+ List<String> principalDBs = config.getManagementPrincipalDBs();
if (principalDBs.size() == 0)
{
- throw new ConfigurationException("No principal-database specified for jmx security(" + baseSecurity + ".principal-database)");
+ throw new ConfigurationException("No principal-database specified for jmx security");
}
String databaseName = principalDBs.get(0);
@@ -191,11 +188,11 @@ public class ConfigurationFilePrincipalDatabaseManager implements PrincipalDatab
_mbean.setPrincipalDatabase(database);
- List<String> jmxaccesslist = config.getList(baseSecurity + ".access");
+ List<String> jmxaccesslist = config.getManagementAccessList();
if (jmxaccesslist.size() == 0)
{
- throw new ConfigurationException("No access control files specified for jmx security(" + baseSecurity + ".access)");
+ throw new ConfigurationException("No access control files specified for jmx security");
}
String jmxaccesssFile = null;
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/HashedUser.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/HashedUser.java
index 4d92e3fb4c..3690e7f92a 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/HashedUser.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/HashedUser.java
@@ -25,6 +25,7 @@ import org.apache.commons.codec.binary.Base64;
import org.apache.log4j.Logger;
import java.io.UnsupportedEncodingException;
+import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.Principal;
@@ -63,10 +64,22 @@ public class HashedUser implements Principal
}
}
- public HashedUser(String name, char[] password)
+ public HashedUser(String name, char[] password) throws UnsupportedEncodingException, NoSuchAlgorithmException
{
_name = name;
- setPassword(password);
+ setPassword(password,false);
+ }
+
+ public static byte[] getMD5(byte[] data) throws NoSuchAlgorithmException, UnsupportedEncodingException
+ {
+ MessageDigest md = MessageDigest.getInstance("MD5");
+
+ for (byte b : data)
+ {
+ md.update(b);
+ }
+
+ return md.digest();
}
public String getName()
@@ -84,9 +97,31 @@ public class HashedUser implements Principal
return _password;
}
- void setPassword(char[] password)
+ void setPassword(char[] password, boolean alreadyHashed) throws UnsupportedEncodingException, NoSuchAlgorithmException
{
- _password = password;
+ if(alreadyHashed){
+ _password = password;
+ }
+ else
+ {
+ byte[] byteArray = new byte[password.length];
+ int index = 0;
+ for (char c : password)
+ {
+ byteArray[index++] = (byte) c;
+ }
+
+ byte[] MD5byteArray = getMD5(byteArray);
+
+ _password = new char[MD5byteArray.length];
+
+ index = 0;
+ for (byte c : MD5byteArray)
+ {
+ _password[index++] = (char) c;
+ }
+ }
+
_modified = true;
_encodedPassword = null;
}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/PlainPasswordFilePrincipalDatabase.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/PlainPasswordFilePrincipalDatabase.java
index 9da954d74f..5e4678a63b 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/PlainPasswordFilePrincipalDatabase.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/PlainPasswordFilePrincipalDatabase.java
@@ -34,11 +34,13 @@ import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
+import java.io.PrintStream;
import java.security.Principal;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
+import java.util.concurrent.locks.ReentrantLock;
import java.util.regex.Pattern;
/**
@@ -50,13 +52,18 @@ import java.util.regex.Pattern;
*/
public class PlainPasswordFilePrincipalDatabase implements PrincipalDatabase
{
+ public static final String DEFAULT_ENCODING = "utf-8";
+
private static final Logger _logger = Logger.getLogger(PlainPasswordFilePrincipalDatabase.class);
- protected File _passwordFile;
+ private File _passwordFile;
- protected Pattern _regexp = Pattern.compile(":");
+ private Pattern _regexp = Pattern.compile(":");
- protected Map<String, AuthenticationProviderInitialiser> _saslServers;
+ private Map<String, AuthenticationProviderInitialiser> _saslServers;
+
+ private Map<String, PlainUser> _users = new HashMap<String, PlainUser>();
+ private ReentrantLock _userUpdate = new ReentrantLock();
public PlainPasswordFilePrincipalDatabase()
{
@@ -83,7 +90,7 @@ public class PlainPasswordFilePrincipalDatabase implements PrincipalDatabase
_saslServers.put(cram.getMechanismName(), cram);
}
- public void setPasswordFile(String passwordFile) throws FileNotFoundException
+ public void setPasswordFile(String passwordFile) throws IOException
{
File f = new File(passwordFile);
_logger.info("PlainPasswordFile using file " + f.getAbsolutePath());
@@ -97,10 +104,20 @@ public class PlainPasswordFilePrincipalDatabase implements PrincipalDatabase
throw new FileNotFoundException("Cannot read password file " + f +
". Check permissions.");
}
+
+ loadPasswordFile();
}
- public void setPassword(Principal principal, PasswordCallback callback) throws IOException,
- AccountNotFoundException
+ /**
+ * SASL Callback Mechanism - sets the Password in the PasswordCallback based on the value in the PasswordFile
+ * If you want to change the password for a user, use updatePassword instead.
+ *
+ * @param principal The Principal to set the password for
+ * @param callback The PasswordCallback to call setPassword on
+ *
+ * @throws AccountNotFoundException If the Principal cannot be found in this Database
+ */
+ public void setPassword(Principal principal, PasswordCallback callback) throws AccountNotFoundException
{
if (_passwordFile == null)
{
@@ -111,6 +128,7 @@ public class PlainPasswordFilePrincipalDatabase implements PrincipalDatabase
throw new IllegalArgumentException("principal must not be null");
}
char[] pwd = lookupPassword(principal.getName());
+
if (pwd != null)
{
callback.setPassword(pwd);
@@ -121,33 +139,151 @@ public class PlainPasswordFilePrincipalDatabase implements PrincipalDatabase
}
}
+ /**
+ * Used to verify that the presented Password is correct. Currently only used by Management Console
+ *
+ * @param principal The principal to authenticate
+ * @param password The plaintext password to check
+ *
+ * @return true if password is correct
+ *
+ * @throws AccountNotFoundException if the principal cannot be found
+ */
public boolean verifyPassword(String principal, char[] password) throws AccountNotFoundException
{
- try
- {
- char[] pwd = lookupPassword(principal);
- return compareCharArray(pwd, password);
- }
- catch (IOException e)
+ char[] pwd = lookupPassword(principal);
+
+ if (pwd == null)
{
- return false;
+ throw new AccountNotFoundException("Unable to lookup the specfied users password");
}
+
+ return compareCharArray(pwd, password);
+
}
+ /**
+ * Changes the password for the specified user
+ *
+ * @param principal to change the password for
+ * @param password plaintext password to set the password too
+ */
public boolean updatePassword(Principal principal, char[] password) throws AccountNotFoundException
{
- return false; // updates denied
+ PlainUser user = _users.get(principal.getName());
+
+ if (user == null)
+ {
+ throw new AccountNotFoundException(principal.getName());
+ }
+
+ try
+ {
+ try
+ {
+ _userUpdate.lock();
+ char[] orig = user.getPassword();
+ user.setPassword(password);
+
+ try
+ {
+ savePasswordFile();
+ }
+ catch (IOException e)
+ {
+ _logger.error("Unable to save password file, password change for user '" + principal + "' discarded");
+ //revert the password change
+ user.setPassword(orig);
+ return false;
+ }
+ return true;
+ }
+ finally
+ {
+ if (_userUpdate.isHeldByCurrentThread())
+ {
+ _userUpdate.unlock();
+ }
+ }
+ }
+ catch (Exception e)
+ {
+ return false;
+ }
}
public boolean createPrincipal(Principal principal, char[] password)
{
- return false; // updates denied
+ if (_users.get(principal.getName()) != null)
+ {
+ return false;
+ }
+
+ PlainUser user = new PlainUser(principal.getName(), password);
+
+ try
+ {
+ _userUpdate.lock();
+ _users.put(user.getName(), user);
+
+ try
+ {
+ savePasswordFile();
+ return true;
+ }
+ catch (IOException e)
+ {
+ //remove the use on failure.
+ _users.remove(user.getName());
+ _logger.warn("Unable to create user '" + user.getName());
+ return false;
+ }
+ }
+ finally
+ {
+ if (_userUpdate.isHeldByCurrentThread())
+ {
+ _userUpdate.unlock();
+ }
+ }
}
public boolean deletePrincipal(Principal principal) throws AccountNotFoundException
{
- return false; // updates denied
+ PlainUser user = _users.get(principal.getName());
+
+ if (user == null)
+ {
+ throw new AccountNotFoundException(principal.getName());
+ }
+
+ try
+ {
+ _userUpdate.lock();
+ user.delete();
+
+ try
+ {
+ savePasswordFile();
+ }
+ catch (IOException e)
+ {
+ _logger.error("Unable to remove user '" + user.getName() + "' from password file.");
+ return false;
+ }
+
+ _users.remove(user.getName());
+ }
+ finally
+ {
+ if (_userUpdate.isHeldByCurrentThread())
+ {
+ _userUpdate.unlock();
+ }
+ }
+
+ return true;
}
public Map<String, AuthenticationProviderInitialiser> getMechanisms()
@@ -157,21 +293,14 @@ public class PlainPasswordFilePrincipalDatabase implements PrincipalDatabase
public List<Principal> getUsers()
{
- return new LinkedList<Principal>(); //todo
+ return new LinkedList<Principal>(_users.values());
}
public Principal getUser(String username)
{
- try
- {
- if (lookupPassword(username) != null)
- {
- return new UsernamePrincipal(username);
- }
- }
- catch (IOException e)
+ if (_users.containsKey(username))
{
- //fall through to null return
+ return new UsernamePrincipal(username);
}
return null;
}
@@ -197,49 +326,166 @@ public class PlainPasswordFilePrincipalDatabase implements PrincipalDatabase
* Looks up the password for a specified user in the password file. Note this code is <b>not</b> secure since it
* creates strings of passwords. It should be modified to create only char arrays which get nulled out.
*
- * @param name the name of the principal to lookup
- *
- * @return char[] of the password
+ * @param name The principal name to lookup
*
- * @throws java.io.IOException whilst accessing the file
+ * @return a char[] for use in SASL.
*/
- private char[] lookupPassword(String name) throws IOException
+ private char[] lookupPassword(String name)
+ {
+ PlainUser user = _users.get(name);
+ if (user == null)
+ {
+ return null;
+ }
+ else
+ {
+ return user.getPassword();
+ }
+ }
+
+ private void loadPasswordFile() throws IOException
+ {
+ try
+ {
+ _userUpdate.lock();
+ _users.clear();
+
+ BufferedReader reader = null;
+ try
+ {
+ reader = new BufferedReader(new FileReader(_passwordFile));
+ String line;
+
+ while ((line = reader.readLine()) != null)
+ {
+ String[] result = _regexp.split(line);
+ if (result == null || result.length < 2 || result[0].startsWith("#"))
+ {
+ continue;
+ }
+
+ PlainUser user = new PlainUser(result);
+ _logger.info("Created user:" + user);
+ _users.put(user.getName(), user);
+ }
+ }
+ finally
+ {
+ if (reader != null)
+ {
+ reader.close();
+ }
+ }
+ }
+ finally
+ {
+ if (_userUpdate.isHeldByCurrentThread())
+ {
+ _userUpdate.unlock();
+ }
+ }
+ }
+
+ private void savePasswordFile() throws IOException
{
- BufferedReader reader = null;
try
{
- reader = new BufferedReader(new FileReader(_passwordFile));
- String line;
+ _userUpdate.lock();
+
+ BufferedReader reader = null;
+ PrintStream writer = null;
+ File tmp = File.createTempFile(_passwordFile.getName(), ".tmp");
- while ((line = reader.readLine()) != null)
+ try
{
- if (!line.startsWith("#"))
+ writer = new PrintStream(tmp);
+ reader = new BufferedReader(new FileReader(_passwordFile));
+ String line;
+
+ while ((line = reader.readLine()) != null)
{
String[] result = _regexp.split(line);
- if (result == null || result.length < 2)
+ if (result == null || result.length < 2 || result[0].startsWith("#"))
{
+ writer.write(line.getBytes(DEFAULT_ENCODING));
+ writer.println();
continue;
}
- if (name.equals(result[0]))
+ PlainUser user = _users.get(result[0]);
+
+ if (user == null)
{
- return result[1].toCharArray();
+ writer.write(line.getBytes(DEFAULT_ENCODING));
+ writer.println();
+ }
+ else if (!user.isDeleted())
+ {
+ if (!user.isModified())
+ {
+ writer.write(line.getBytes(DEFAULT_ENCODING));
+ writer.println();
+ }
+ else
+ {
+ byte[] password = user.getPasswordBytes();
+
+ writer.write((user.getName() + ":").getBytes(DEFAULT_ENCODING));
+ writer.write(password);
+ writer.println();
+
+ user.saved();
+ }
+ }
+ }
+
+ for (PlainUser user : _users.values())
+ {
+ if (user.isModified())
+ {
+ byte[] password;
+ password = user.getPasswordBytes();
+ writer.write((user.getName() + ":").getBytes(DEFAULT_ENCODING));
+ writer.write(password);
+ writer.println();
+ user.saved();
}
}
}
- return null;
+ finally
+ {
+ if (reader != null)
+ {
+ reader.close();
+ }
+
+ if (writer != null)
+ {
+ writer.close();
+ }
+
+ // Swap temp file to main password file.
+ File old = new File(_passwordFile.getAbsoluteFile() + ".old");
+ if (old.exists())
+ {
+ old.delete();
+ }
+ _passwordFile.renameTo(old);
+ tmp.renameTo(_passwordFile);
+ tmp.delete();
+ }
}
finally
{
- if (reader != null)
+ if (_userUpdate.isHeldByCurrentThread())
{
- reader.close();
+ _userUpdate.unlock();
}
}
}
-
+
public void reload() throws IOException
{
- //This PD is not cached, so do nothing.
+ loadPasswordFile();
}
}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/PlainUser.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/PlainUser.java
new file mode 100644
index 0000000000..46a78a55aa
--- /dev/null
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/PlainUser.java
@@ -0,0 +1,106 @@
+/*
+*
+ * 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.security.auth.database;
+
+import org.apache.log4j.Logger;
+
+import java.security.Principal;
+
+public class PlainUser implements Principal
+{
+ private String _name;
+ private char[] _password;
+ private boolean _modified = false;
+ private boolean _deleted = false;
+
+ PlainUser(String[] data)
+ {
+ if (data.length != 2)
+ {
+ throw new IllegalArgumentException("User Data should be length 2, username, password");
+ }
+
+ _name = data[0];
+
+ _password = data[1].toCharArray();
+
+ }
+
+ public PlainUser(String name, char[] password)
+ {
+ _name = name;
+ _password = password;
+ _modified = true;
+ }
+
+ public String getName()
+ {
+ return _name;
+ }
+
+ public String toString()
+ {
+ return _name;
+ }
+
+ char[] getPassword()
+ {
+ return _password;
+ }
+
+ byte[] getPasswordBytes()
+ {
+ byte[] byteArray = new byte[_password.length];
+ int index = 0;
+ for (char c : _password)
+ {
+ byteArray[index++] = (byte) c;
+ }
+ return byteArray;
+ }
+
+ void setPassword(char[] password)
+ {
+ _password = password;
+ _modified = true;
+ }
+
+ public boolean isModified()
+ {
+ return _modified;
+ }
+
+ public boolean isDeleted()
+ {
+ return _deleted;
+ }
+
+ public void delete()
+ {
+ _deleted = true;
+ }
+
+ public void saved()
+ {
+ _modified = false;
+ }
+
+}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/PrincipalDatabaseManager.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/PrincipalDatabaseManager.java
index 2c553ae76a..f9882f8810 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/PrincipalDatabaseManager.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/PrincipalDatabaseManager.java
@@ -20,6 +20,7 @@
*/
package org.apache.qpid.server.security.auth.database;
+import org.apache.qpid.server.configuration.ServerConfiguration;
import org.apache.qpid.server.security.auth.database.PrincipalDatabase;
import org.apache.commons.configuration.Configuration;
import org.apache.commons.configuration.ConfigurationException;
@@ -30,5 +31,5 @@ public interface PrincipalDatabaseManager
{
public Map<String, PrincipalDatabase> getDatabases();
- public void initialiseManagement(Configuration config) throws ConfigurationException;
+ public void initialiseManagement(ServerConfiguration _configuration) throws ConfigurationException;
}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/PropertiesPrincipalDatabaseManager.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/PropertiesPrincipalDatabaseManager.java
index 6b86a46bd2..4efe381a8b 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/PropertiesPrincipalDatabaseManager.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/PropertiesPrincipalDatabaseManager.java
@@ -20,7 +20,8 @@
*/
package org.apache.qpid.server.security.auth.database;
-import org.apache.commons.configuration.Configuration;
+import org.apache.commons.configuration.ConfigurationException;
+import org.apache.qpid.server.configuration.ServerConfiguration;
import java.util.Map;
import java.util.Properties;
@@ -41,7 +42,8 @@ public class PropertiesPrincipalDatabaseManager implements PrincipalDatabaseMana
return _databases;
}
- public void initialiseManagement(Configuration config)
+ @Override
+ public void initialiseManagement(ServerConfiguration _configuration) throws ConfigurationException
{
//todo
}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/PrincipalDatabaseAuthenticationManager.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/PrincipalDatabaseAuthenticationManager.java
index 2cbbdc85ff..98c060599a 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/PrincipalDatabaseAuthenticationManager.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/PrincipalDatabaseAuthenticationManager.java
@@ -23,6 +23,7 @@ package org.apache.qpid.server.security.auth.manager;
import org.apache.log4j.Logger;
import org.apache.commons.configuration.Configuration;
import org.apache.commons.configuration.ConfigurationException;
+import org.apache.qpid.server.configuration.VirtualHostConfiguration;
import org.apache.qpid.server.registry.ApplicationRegistry;
import org.apache.qpid.server.security.auth.manager.AuthenticationManager;
import org.apache.qpid.server.security.auth.database.PrincipalDatabase;
@@ -60,7 +61,7 @@ public class PrincipalDatabaseAuthenticationManager implements AuthenticationMan
/** The name for the required SASL Server mechanisms */
public static final String PROVIDER_NAME= "AMQSASLProvider-Server";
- public PrincipalDatabaseAuthenticationManager(String name, Configuration hostConfig) throws Exception
+ public PrincipalDatabaseAuthenticationManager(String name, VirtualHostConfiguration hostConfig) throws Exception
{
_logger.info("Initialising " + (name == null ? "Default" : "'" + name + "'")
+ " PrincipleDatabase authentication manager.");
@@ -77,7 +78,7 @@ public class PrincipalDatabaseAuthenticationManager implements AuthenticationMan
}
else
{
- String databaseName = hostConfig.getString("security.authentication.name");
+ String databaseName = hostConfig.getAuthenticationDatabase();
if (databaseName == null)
{
@@ -121,14 +122,6 @@ public class PrincipalDatabaseAuthenticationManager implements AuthenticationMan
private void initialiseAuthenticationMechanisms(Map<String, Class<? extends SaslServerFactory>> providerMap, Map<String, PrincipalDatabase> databases) throws Exception
{
-// Configuration config = ApplicationRegistry.getInstance().getConfiguration();
-// List<String> mechanisms = config.getList("security.sasl.mechanisms.mechanism.initialiser.class");
-//
-// // Maps from the mechanism to the properties used to initialise the server. See the method
-// // Sasl.createSaslServer for details of the use of these properties. This map is populated during initialisation
-// // of each provider.
-
-
if (databases.size() > 1)
{
_logger.warn("More than one principle database provided currently authentication mechanism will override each other.");
@@ -136,13 +129,11 @@ public class PrincipalDatabaseAuthenticationManager implements AuthenticationMan
for (Map.Entry<String, PrincipalDatabase> entry : databases.entrySet())
{
-
// fixme As the database now provide the mechanisms they support, they will ...
// overwrite each other in the map. There should only be one database per vhost.
// But currently we must have authentication before vhost definition.
initialiseAuthenticationMechanisms(providerMap, entry.getValue());
}
-
}
private void initialiseAuthenticationMechanisms(Map<String, Class<? extends SaslServerFactory>> providerMap, PrincipalDatabase database) throws Exception
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/rmi/RMIPasswordAuthenticator.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/rmi/RMIPasswordAuthenticator.java
index 378b17e733..77040e896c 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/rmi/RMIPasswordAuthenticator.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/rmi/RMIPasswordAuthenticator.java
@@ -20,23 +20,14 @@
*/
package org.apache.qpid.server.security.auth.rmi;
-import java.io.IOException;
-import java.io.UnsupportedEncodingException;
-import java.security.MessageDigest;
-import java.security.NoSuchAlgorithmException;
-import java.util.Arrays;
import java.util.Collections;
import javax.management.remote.JMXAuthenticator;
import javax.management.remote.JMXPrincipal;
import javax.security.auth.Subject;
-import javax.security.auth.callback.PasswordCallback;
import javax.security.auth.login.AccountNotFoundException;
-import org.apache.qpid.server.security.auth.database.Base64MD5PasswordFilePrincipalDatabase;
-import org.apache.qpid.server.security.auth.database.PlainPasswordFilePrincipalDatabase;
import org.apache.qpid.server.security.auth.database.PrincipalDatabase;
-import org.apache.qpid.server.security.auth.sasl.UsernamePrincipal;
public class RMIPasswordAuthenticator implements JMXAuthenticator
{
@@ -48,7 +39,6 @@ public class RMIPasswordAuthenticator implements JMXAuthenticator
static final String CREDENTIALS_REQUIRED = "User details are required. " +
"Please ensure you are using an up to date management console to connect.";
- public static final String DEFAULT_ENCODING = "utf-8";
private PrincipalDatabase _db = null;
public RMIPasswordAuthenticator()
@@ -91,56 +81,26 @@ public class RMIPasswordAuthenticator implements JMXAuthenticator
throw new SecurityException(SHOULD_BE_NON_NULL);
}
+ // Verify that a PD has been set.
+ if (_db == null)
+ {
+ throw new SecurityException(UNABLE_TO_LOOKUP);
+ }
+
boolean authenticated = false;
// Perform authentication
try
{
- PasswordCallback pwCallback = new PasswordCallback("prompt",false);
- UsernamePrincipal uname = new UsernamePrincipal(username);
-
- if (_db instanceof Base64MD5PasswordFilePrincipalDatabase)
- {
- //retrieve the stored password for the given user
- _db.setPassword(uname, pwCallback);
-
- //compare the MD5Hash of the given password with the stored value
- if (Arrays.equals(getMD5Hash(password), pwCallback.getPassword()))
- {
- authenticated = true;
- }
- }
- else if (_db instanceof PlainPasswordFilePrincipalDatabase)
- {
- //retrieve the users stored password and compare with given value
- _db.setPassword(uname, pwCallback);
-
- if (password.equals(new String(pwCallback.getPassword())))
- {
- authenticated = true;
- }
- }
- else
- {
- throw new SecurityException(UNABLE_TO_LOOKUP);
+ if (_db.verifyPassword(username, password.toCharArray()))
+ {
+ authenticated = true;
}
}
catch (AccountNotFoundException e)
{
throw new SecurityException(INVALID_CREDENTIALS);
}
- catch (UnsupportedEncodingException e)
- {
- throw new SecurityException(UNABLE_TO_LOOKUP);
- }
- catch (NoSuchAlgorithmException e)
- {
- throw new SecurityException(UNABLE_TO_LOOKUP);
- }
- catch (IOException e)
- {
- throw new SecurityException(UNABLE_TO_LOOKUP);
- }
if (authenticated)
{
@@ -155,28 +115,5 @@ public class RMIPasswordAuthenticator implements JMXAuthenticator
throw new SecurityException(INVALID_CREDENTIALS);
}
}
-
- public static char[] getMD5Hash(String text) throws NoSuchAlgorithmException, UnsupportedEncodingException
- {
- byte[] data = text.getBytes(DEFAULT_ENCODING);
- MessageDigest md = MessageDigest.getInstance("MD5");
-
- for (byte b : data)
- {
- md.update(b);
- }
-
- byte[] digest = md.digest();
-
- char[] hash = new char[digest.length ];
-
- int index = 0;
- for (byte b : digest)
- {
- hash[index++] = (char) b;
- }
-
- return hash;
- }
} \ No newline at end of file
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 500fd4c7bf..33b3d8608e 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,6 +21,7 @@
package org.apache.qpid.server.store;
import org.apache.qpid.server.virtualhost.VirtualHost;
+import org.apache.qpid.server.configuration.VirtualHostConfiguration;
import org.apache.qpid.server.exchange.Exchange;
import org.apache.qpid.server.queue.AMQQueue;
import org.apache.qpid.server.queue.AMQQueueFactory;
@@ -142,7 +143,7 @@ public class DerbyMessageStore implements TransactionLog, RoutingTable
private State _state = State.INITIAL;
- public void configure(VirtualHost virtualHost, String base, Configuration config) throws Exception
+ public void configure(VirtualHost virtualHost, String base, VirtualHostConfiguration config) throws Exception
{
//Only initialise when loaded with the old 'store' confing ignore the new 'RoutingTable' config
if (base.equals("store"))
@@ -156,7 +157,7 @@ public class DerbyMessageStore implements TransactionLog, RoutingTable
_logger.info("Configuring Derby message store for virtual host " + virtualHost.getName());
QueueRegistry queueRegistry = virtualHost.getQueueRegistry();
- final String databasePath = config.getString(base + "." + ENVIRONMENT_PATH_PROPERTY, "derbyDB");
+ final String databasePath = config.getStoreConfiguration().getString(base + "." + ENVIRONMENT_PATH_PROPERTY, "derbyDB");
File environmentPath = new File(databasePath);
if (!environmentPath.exists())
@@ -1356,7 +1357,8 @@ public class DerbyMessageStore implements TransactionLog, RoutingTable
if(message != null)
{
- message.incrementReference();
+ //todo must enqueue message to build reference table
+// message.incrementReference(1);
}
else
{
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 eee7be7ef6..3754b41a3e 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
@@ -27,26 +27,31 @@ import org.apache.qpid.framing.AMQShortString;
import org.apache.qpid.framing.FieldTable;
import org.apache.qpid.framing.abstraction.ContentChunk;
import org.apache.qpid.server.queue.MessageMetaData;
+import org.apache.qpid.server.configuration.VirtualHostConfiguration;
import org.apache.qpid.server.exchange.Exchange;
import org.apache.qpid.server.queue.AMQQueue;
-import org.apache.qpid.server.virtualhost.VirtualHost;
-import org.apache.qpid.server.transactionlog.TransactionLog;
+import org.apache.qpid.server.queue.MessageMetaData;
import org.apache.qpid.server.routing.RoutingTable;
+import org.apache.qpid.server.transactionlog.TransactionLog;
+import org.apache.qpid.server.virtualhost.VirtualHost;
import java.util.ArrayList;
import java.util.Collections;
+import java.util.LinkedList;
import java.util.List;
+import java.util.Map;
+import java.util.HashMap;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicLong;
-/** A simple message store that stores the messages in a threadsafe structure in memory.
+/**
+ * A simple message store that stores the messages in a threadsafe structure in memory.
*
* NOTE: Now that we have removed the MessageStore interface and are using a TransactionLog
*
* This class really should have no storage unless we want to do inMemory Recovery.
- *
*/
public class MemoryMessageStore implements TransactionLog, RoutingTable
{
@@ -62,6 +67,7 @@ public class MemoryMessageStore implements TransactionLog, RoutingTable
private final AtomicLong _messageId = new AtomicLong(1);
private AtomicBoolean _closed = new AtomicBoolean(false);
+ protected final Map<Long, List<AMQQueue>> _messageEnqueueMap = new HashMap<Long, List<AMQQueue>>();
public void configure()
{
@@ -70,19 +76,19 @@ public class MemoryMessageStore implements TransactionLog, RoutingTable
_contentBodyMap = new ConcurrentHashMap<Long, List<ContentChunk>>(DEFAULT_HASHTABLE_CAPACITY);
}
- public void configure(String base, Configuration config)
+ public void configure(String base, VirtualHostConfiguration config)
{
//Only initialise when called with current 'store' configs i.e. don't reinit when used as a 'RoutingTable'
if (base.equals("store"))
{
- int hashtableCapacity = config.getInt(base + "." + HASHTABLE_CAPACITY_CONFIG, DEFAULT_HASHTABLE_CAPACITY);
+ int hashtableCapacity = config.getStoreConfiguration().getInt(base + "." + HASHTABLE_CAPACITY_CONFIG, DEFAULT_HASHTABLE_CAPACITY);
_log.info("Using capacity " + hashtableCapacity + " for hash tables");
_metaDataMap = new ConcurrentHashMap<Long, MessageMetaData>(hashtableCapacity);
_contentBodyMap = new ConcurrentHashMap<Long, List<ContentChunk>>(hashtableCapacity);
}
}
- public void configure(VirtualHost virtualHost, String base, Configuration config) throws Exception
+ public void configure(VirtualHost virtualHost, String base, VirtualHostConfiguration config) throws Exception
{
configure(base, config);
}
@@ -102,7 +108,7 @@ public class MemoryMessageStore implements TransactionLog, RoutingTable
}
}
- public void removeMessage(StoreContext context, Long messageId) throws AMQException
+ private void removeMessage(StoreContext context, Long messageId) throws AMQException
{
checkNotClosed();
if (_log.isDebugEnabled())
@@ -111,6 +117,7 @@ public class MemoryMessageStore implements TransactionLog, RoutingTable
}
_metaDataMap.remove(messageId);
_contentBodyMap.remove(messageId);
+ _messageEnqueueMap.remove(messageId);
}
public void createExchange(Exchange exchange) throws AMQException
@@ -133,7 +140,6 @@ public class MemoryMessageStore implements TransactionLog, RoutingTable
}
-
public void createQueue(AMQQueue queue) throws AMQException
{
// Not requred to do anything
@@ -151,12 +157,39 @@ public class MemoryMessageStore implements TransactionLog, RoutingTable
public void enqueueMessage(StoreContext context, final AMQQueue queue, Long messageId) throws AMQException
{
- // Not required to do anything
+ synchronized (_messageEnqueueMap)
+ {
+ List<AMQQueue> queues = _messageEnqueueMap.get(messageId);
+ if (queues == null)
+ {
+ queues = new LinkedList<AMQQueue>();
+ _messageEnqueueMap.put(messageId, queues);
+ }
+
+ queues.add(queue);
+ }
}
public void dequeueMessage(StoreContext context, final AMQQueue queue, Long messageId) throws AMQException
{
- // Not required to do anything
+ synchronized (_messageEnqueueMap)
+ {
+ List<AMQQueue> queues = _messageEnqueueMap.get(messageId);
+ if (queues == null || !queues.contains(queue))
+ {
+ throw new RuntimeException("Attempt to dequeue messageID:" + messageId + " from queue:" + queue.getName()
+ + " but it is not enqueued on that queue.");
+ }
+ else
+ {
+ queues.remove(queue);
+ if (queues.isEmpty())
+ {
+ removeMessage(context,messageId);
+ }
+ }
+ }
+
}
public void beginTran(StoreContext context) throws AMQException
@@ -237,7 +270,7 @@ public class MemoryMessageStore implements TransactionLog, RoutingTable
}
private void checkNotClosed() throws MessageStoreClosedException
- {
+ {
if (_closed.get())
{
throw new MessageStoreClosedException();
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/subscription/SubscriptionImpl.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/subscription/SubscriptionImpl.java
index be11eb7b84..bc1f56fee1 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/subscription/SubscriptionImpl.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/subscription/SubscriptionImpl.java
@@ -144,7 +144,8 @@ public abstract class SubscriptionImpl implements Subscription, FlowCreditManage
StoreContext storeContext = getChannel().getStoreContext();
try
- { // if we do not need to wait for client acknowledgements
+ {
+ // if we do not need to wait for client acknowledgements
// we can decrement the reference count immediately.
// By doing this _before_ the send we ensure that it
@@ -153,7 +154,7 @@ public abstract class SubscriptionImpl implements Subscription, FlowCreditManage
// The send may of course still fail, in which case, as
// the message is unacked, it will be lost.
- entry.dequeue(storeContext);
+ entry.dequeueAndDelete(storeContext);
synchronized (getChannel())
@@ -163,7 +164,6 @@ public abstract class SubscriptionImpl implements Subscription, FlowCreditManage
sendToClient(entry, deliveryTag);
}
- entry.dispose(storeContext);
}
finally
{
@@ -316,7 +316,7 @@ public abstract class SubscriptionImpl implements Subscription, FlowCreditManage
_autoClose = false;
}
-
+ _logger.info(debugIdentity()+" Created subscription:");
}
@@ -387,6 +387,7 @@ public abstract class SubscriptionImpl implements Subscription, FlowCreditManage
//todo - client id should be recoreded and this test removed but handled below
if (_noLocal)
{
+ //todo getPublisherClientInstance should be moved to QueueEntryImpl
final Object publisherId = entry.getMessage().getPublisherClientInstance();
// We don't want local messages so check to see if message is one we sent
@@ -407,6 +408,7 @@ public abstract class SubscriptionImpl implements Subscription, FlowCreditManage
//todo - client id should be recoreded and this test removed but handled here
+ //todo getPublisherIdentifier should be moved to QueueEntryImpl
if (localInstance != null && localInstance.equals(entry.getMessage().getPublisherIdentifier()))
{
return false;
@@ -498,9 +500,9 @@ public abstract class SubscriptionImpl implements Subscription, FlowCreditManage
}
- public boolean wouldSuspend(QueueEntry msg)
+ public boolean wouldSuspend(QueueEntry queueEntry)
{
- return !_creditManager.useCreditForMessage(msg.getMessage());//_channel.wouldSuspend(msg.getMessage());
+ return !_creditManager.useCreditForMessage(queueEntry);
}
public void getSendLock()
@@ -594,6 +596,7 @@ public abstract class SubscriptionImpl implements Subscription, FlowCreditManage
protected void sendToClient(final QueueEntry entry, final long deliveryTag)
throws AMQException
{
+ _logger.info("Sending Message(" + entry + ") DTag:" + deliveryTag + " to subscription:" + debugIdentity());
_deliveryMethod.deliverToClient(this,entry,deliveryTag);
}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/transactionlog/TransactionLog.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/transactionlog/TransactionLog.java
index c927bb3272..97a1ecb38c 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/transactionlog/TransactionLog.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/transactionlog/TransactionLog.java
@@ -26,6 +26,7 @@ import org.apache.qpid.AMQException;
import org.apache.qpid.framing.AMQShortString;
import org.apache.qpid.framing.FieldTable;
import org.apache.qpid.framing.abstraction.ContentChunk;
+import org.apache.qpid.server.configuration.VirtualHostConfiguration;
import org.apache.qpid.server.exchange.Exchange;
import org.apache.qpid.server.queue.MessageMetaData;
import org.apache.qpid.server.queue.AMQQueue;
@@ -67,7 +68,7 @@ public interface TransactionLog
*
* @throws Exception If any error occurs that means the store is unable to configure itself.
*/
- void configure(VirtualHost virtualHost, String base, Configuration config) throws Exception;
+ void configure(VirtualHost virtualHost, String base, VirtualHostConfiguration config) throws Exception;
/**
* Called to close and cleanup any resources used by the message store.
@@ -77,18 +78,6 @@ public interface TransactionLog
void close() throws Exception;
/**
- * Removes the specified message from the store in the given transactional store context.
- *
- * @param storeContext The transactional context to remove the message in.
- * @param messageId Identifies the message to remove.
- *
- * @throws AMQException If the operation fails for any reason.
- */
- void removeMessage(StoreContext storeContext, Long messageId) throws AMQException;
-
-
-
- /**
* Places a message onto a specified queue, in a given transactional context.
*
* @param context The transactional context for the operation.
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/transport/ConnectorConfiguration.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/transport/ConnectorConfiguration.java
deleted file mode 100644
index b67bb98e28..0000000000
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/transport/ConnectorConfiguration.java
+++ /dev/null
@@ -1,118 +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.server.transport;
-
-import org.apache.mina.common.IoAcceptor;
-import org.apache.mina.util.NewThreadExecutor;
-import org.apache.qpid.configuration.Configured;
-import org.apache.log4j.Logger;
-
-public class ConnectorConfiguration
-{
- private static final Logger _logger = Logger.getLogger(ConnectorConfiguration.class);
-
- public static final String DEFAULT_PORT = "5672";
-
- public static final String SSL_PORT = "8672";
-
- @Configured(path = "connector.processors",
- defaultValue = "4")
- public int processors;
-
- @Configured(path = "connector.port",
- defaultValue = DEFAULT_PORT)
- public int port;
-
- @Configured(path = "connector.bind",
- defaultValue = "wildcard")
- public String bindAddress;
-
- @Configured(path = "connector.socketReceiveBuffer",
- defaultValue = "32767")
- public int socketReceiveBufferSize;
-
- @Configured(path = "connector.socketWriteBuffer",
- defaultValue = "32767")
- public int socketWriteBuferSize;
-
- @Configured(path = "connector.tcpNoDelay",
- defaultValue = "true")
- public boolean tcpNoDelay;
-
- @Configured(path = "advanced.filterchain[@enableExecutorPool]",
- defaultValue = "false")
- public boolean enableExecutorPool;
-
- @Configured(path = "advanced.enablePooledAllocator",
- defaultValue = "false")
- public boolean enablePooledAllocator;
-
- @Configured(path = "advanced.enableDirectBuffers",
- defaultValue = "false")
- public boolean enableDirectBuffers;
-
- @Configured(path = "connector.ssl.enabled",
- defaultValue = "false")
- public boolean enableSSL;
-
- @Configured(path = "connector.ssl.sslOnly",
- defaultValue = "true")
- public boolean sslOnly;
-
- @Configured(path = "connector.ssl.port",
- defaultValue = SSL_PORT)
- public int sslPort;
-
- @Configured(path = "connector.ssl.keystorePath",
- defaultValue = "none")
- public String keystorePath;
-
- @Configured(path = "connector.ssl.keystorePassword",
- defaultValue = "none")
- public String keystorePassword;
-
- @Configured(path = "connector.ssl.certType",
- defaultValue = "SunX509")
- public String certType;
-
- @Configured(path = "connector.qpidnio",
- defaultValue = "false")
- public boolean _multiThreadNIO;
-
- @Configured(path = "advanced.useWriteBiasedPool",
- defaultValue = "false")
- public boolean useBiasedWrites;
-
-
- public IoAcceptor createAcceptor()
- {
- if (_multiThreadNIO)
- {
- _logger.warn("Using Qpid Multithreaded IO Processing");
- return new org.apache.mina.transport.socket.nio.MultiThreadSocketAcceptor(processors, new NewThreadExecutor());
- }
- else
- {
- _logger.warn("Using Mina IO Processing");
- return new org.apache.mina.transport.socket.nio.SocketAcceptor(processors, new NewThreadExecutor());
- }
- }
-}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/txn/LocalTransactionalContext.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/txn/LocalTransactionalContext.java
index 9bc2e98fe9..abfb60c5bf 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/txn/LocalTransactionalContext.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/txn/LocalTransactionalContext.java
@@ -92,20 +92,12 @@ public class LocalTransactionalContext implements TransactionalContext
public void process() throws AMQException
{
- _message.incrementReference();
- try
- {
QueueEntry entry = _queue.enqueue(getStoreContext(),_message);
if(entry.immediateAndNotDelivered())
{
getReturnMessages().add(new NoConsumersException(_message));
}
- }
- finally
- {
- _message.decrementReference(getStoreContext());
- }
}
}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/txn/NonTransactionalContext.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/txn/NonTransactionalContext.java
index 145d7f8b13..2f27e1405a 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/txn/NonTransactionalContext.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/txn/NonTransactionalContext.java
@@ -123,18 +123,18 @@ public class NonTransactionalContext implements TransactionalContext
unacknowledgedMessageMap.size());
unacknowledgedMessageMap.visit(new UnacknowledgedMessageMap.Visitor()
{
- public boolean callback(final long deliveryTag, QueueEntry message) throws AMQException
+ public boolean callback(final long deliveryTag, QueueEntry queueEntry) throws AMQException
{
if (debug)
{
- _log.debug("Discarding message: " + message.getMessage().getMessageId());
+ _log.debug("Discarding message: " + queueEntry.getMessageId());
}
- if(message.getMessage().isPersistent())
+ if(queueEntry.isPersistent())
{
beginTranIfNecessary();
}
- //Message has been ack so discard it. This will dequeue and decrement the reference.
- message.discard(_storeContext);
+ //Message has been ack so dequeueAndDelete it.
+ queueEntry.dequeueAndDelete(_storeContext);
return false;
}
@@ -157,10 +157,15 @@ public class NonTransactionalContext implements TransactionalContext
}
else
{
- QueueEntry msg;
- msg = unacknowledgedMessageMap.get(deliveryTag);
+ QueueEntry queueEntry;
+ queueEntry = unacknowledgedMessageMap.get(deliveryTag);
- if (msg == null)
+ if (debug)
+ {
+ _log.debug("Received non-multiple ack for messaging with delivery tag " + deliveryTag);
+ }
+
+ if (queueEntry == null)
{
_log.info("Single ack on delivery tag " + deliveryTag + " not known for channel:" +
_channel.getChannelId());
@@ -170,24 +175,21 @@ public class NonTransactionalContext implements TransactionalContext
if (debug)
{
- _log.debug("Discarding message: " + msg.getMessage().getMessageId());
+ _log.debug("Discarding message: " + queueEntry.getMessageId());
}
- if(msg.getMessage().isPersistent())
+ if(queueEntry.isPersistent())
{
beginTranIfNecessary();
}
- //Message has been ack so discard it. This will dequeue and decrement the reference.
- msg.discard(_storeContext);
+ //Message has been ack so dequeueAndDelete it.
+ // If the message is persistent and this is the last QueueEntry that uses it then the data will be removed
+ // from the transaciton log
+ queueEntry.dequeueAndDelete(_storeContext);
unacknowledgedMessageMap.remove(deliveryTag);
- if (debug)
- {
- _log.debug("Received non-multiple ack for messaging with delivery tag " + deliveryTag + " msg id " +
- msg.getMessage().getMessageId());
- }
}
if(_inTran)
{
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/util/NullApplicationRegistry.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/util/NullApplicationRegistry.java
index 88ad87b9c1..eda2d3a94e 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/util/NullApplicationRegistry.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/util/NullApplicationRegistry.java
@@ -26,7 +26,11 @@ import java.util.HashMap;
import java.util.Properties;
import org.apache.commons.configuration.Configuration;
+import org.apache.commons.configuration.ConfigurationException;
import org.apache.commons.configuration.MapConfiguration;
+import org.apache.commons.configuration.PropertiesConfiguration;
+import org.apache.qpid.server.configuration.ServerConfiguration;
+import org.apache.qpid.server.configuration.VirtualHostConfiguration;
import org.apache.qpid.server.management.NoopManagedObjectRegistry;
import org.apache.qpid.server.plugins.PluginManager;
import org.apache.qpid.server.registry.ApplicationRegistry;
@@ -39,17 +43,16 @@ import org.apache.qpid.server.virtualhost.VirtualHostRegistry;
public class NullApplicationRegistry extends ApplicationRegistry
{
- public NullApplicationRegistry()
+ public NullApplicationRegistry() throws ConfigurationException
{
- super(new MapConfiguration(new HashMap()));
+ super(new ServerConfiguration(new PropertiesConfiguration()));
}
public void initialise() throws Exception
{
_logger.info("Initialising NullApplicationRegistry");
- _configuration.addProperty("store.class", "org.apache.qpid.server.store.MemoryMessageStore");
- _configuration.addProperty("housekeeping.expiredMessageCheckPeriod", "200");
+ _configuration.setHousekeepingExpiredMessageCheckPeriod(200);
Properties users = new Properties();
@@ -57,17 +60,18 @@ public class NullApplicationRegistry extends ApplicationRegistry
_databaseManager = new PropertiesPrincipalDatabaseManager("default", users);
- _accessManager = new ACLManager(_configuration, _pluginManager, AllowAll.FACTORY);
+ _accessManager = new ACLManager(_configuration.getSecurityConfiguration(), _pluginManager, AllowAll.FACTORY);
_authenticationManager = new PrincipalDatabaseAuthenticationManager(null, null);
_managedObjectRegistry = new NoopManagedObjectRegistry();
_virtualHostRegistry = new VirtualHostRegistry();
- VirtualHost dummyHost = new VirtualHost("test", _configuration);
+ PropertiesConfiguration vhostProps = new PropertiesConfiguration();
+ VirtualHostConfiguration hostConfig = new VirtualHostConfiguration("test", vhostProps);
+ VirtualHost dummyHost = new VirtualHost(hostConfig);
_virtualHostRegistry.registerVirtualHost(dummyHost);
_virtualHostRegistry.setDefaultVirtualHostName("test");
_pluginManager = new PluginManager("");
- _configuration.addProperty("heartbeat.delay", 10 * 60); // 10 minutes
}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/virtualhost/ManagedVirtualHost.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/virtualhost/ManagedVirtualHost.java
index 85d804457e..f4c81fbbb8 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/virtualhost/ManagedVirtualHost.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/virtualhost/ManagedVirtualHost.java
@@ -31,6 +31,7 @@ import org.apache.qpid.server.management.MBeanAttribute;
public interface ManagedVirtualHost
{
static final String TYPE = "VirtualHost";
+ static final int VERSION = 1;
/**
* Returns the name of the managed virtualHost.
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 1497b4adb8..8a8cbd23cf 100644
--- 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,41 +20,49 @@
*/
package org.apache.qpid.server.virtualhost;
-import java.util.Timer;
-import java.util.TimerTask;
-
-import javax.management.NotCompliantMBeanException;
-
-import org.apache.commons.configuration.Configuration;
-import org.apache.commons.configuration.PropertiesConfiguration;
+import org.apache.commons.configuration.ConfigurationException;
import org.apache.log4j.Logger;
import org.apache.qpid.AMQException;
+import org.apache.qpid.framing.AMQShortString;
+import org.apache.qpid.framing.FieldTable;
import org.apache.qpid.server.AMQBrokerManagerMBean;
-import org.apache.qpid.server.routing.RoutingTable;
-import org.apache.qpid.server.transactionlog.TransactionLog;
-import org.apache.qpid.server.configuration.Configurator;
+import org.apache.qpid.server.configuration.ExchangeConfiguration;
+import org.apache.qpid.server.configuration.QueueConfiguration;
+import org.apache.qpid.server.configuration.VirtualHostConfiguration;
import org.apache.qpid.server.connection.ConnectionRegistry;
import org.apache.qpid.server.connection.IConnectionRegistry;
import org.apache.qpid.server.exchange.DefaultExchangeFactory;
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.management.AMQManagedObject;
import org.apache.qpid.server.management.ManagedObject;
import org.apache.qpid.server.queue.AMQQueue;
+import org.apache.qpid.server.queue.AMQQueueFactory;
import org.apache.qpid.server.queue.DefaultQueueRegistry;
+import org.apache.qpid.server.queue.FileQueueBackingStoreFactory;
+import org.apache.qpid.server.queue.QueueBackingStoreFactory;
import org.apache.qpid.server.queue.QueueRegistry;
import org.apache.qpid.server.registry.ApplicationRegistry;
+import org.apache.qpid.server.routing.RoutingTable;
import org.apache.qpid.server.security.access.ACLManager;
import org.apache.qpid.server.security.access.Accessable;
import org.apache.qpid.server.security.auth.manager.AuthenticationManager;
import org.apache.qpid.server.security.auth.manager.PrincipalDatabaseAuthenticationManager;
+import org.apache.qpid.server.transactionlog.TransactionLog;
+
+import javax.management.NotCompliantMBeanException;
+import java.util.Collections;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Timer;
+import java.util.TimerTask;
public class VirtualHost implements Accessable
{
private static final Logger _logger = Logger.getLogger(VirtualHost.class);
-
private final String _name;
private ConnectionRegistry _connectionRegistry;
@@ -78,9 +86,9 @@ public class VirtualHost implements Accessable
private ACLManager _accessManager;
private final Timer _houseKeepingTimer;
-
- private static final long DEFAULT_HOUSEKEEPING_PERIOD = 30000L;
+ private VirtualHostConfiguration _configuration;
+ private QueueBackingStoreFactory _queueBackingStoreFactory;
public void setAccessableName(String name)
{
@@ -103,6 +111,16 @@ public class VirtualHost implements Accessable
return _routingTable;
}
+ public VirtualHostConfiguration getConfiguration()
+ {
+ return _configuration;
+ }
+
+ public QueueBackingStoreFactory getQueueBackingStoreFactory()
+ {
+ return _queueBackingStoreFactory;
+ }
+
/**
* Abstract MBean class. This has some of the methods implemented from management intrerface for exchanges. Any
* implementaion of an Exchange MBean should extend this class.
@@ -111,7 +129,7 @@ public class VirtualHost implements Accessable
{
public VirtualHostMBean() throws NotCompliantMBeanException
{
- super(ManagedVirtualHost.class, "VirtualHost");
+ super(ManagedVirtualHost.class, ManagedVirtualHost.TYPE, ManagedVirtualHost.VERSION);
}
public String getObjectInstanceName()
@@ -129,50 +147,58 @@ public class VirtualHost implements Accessable
return VirtualHost.this;
}
-
} // End of MBean class
/**
- * Used for testing only
- * @param name
- * @param transactionLog
- * @throws Exception
- */
- public VirtualHost(String name, TransactionLog transactionLog) throws Exception
- {
- this(name, new PropertiesConfiguration(), transactionLog);
- }
-
- /**
* Normal Constructor
- * @param name
+ *
* @param hostConfig
+ *
* @throws Exception
*/
- public VirtualHost(String name, Configuration hostConfig) throws Exception
+ public VirtualHost(VirtualHostConfiguration hostConfig) throws Exception
{
- this(name, hostConfig, null);
+ this(hostConfig, null);
}
- public VirtualHost(String name, Configuration hostConfig, TransactionLog transactionLog) throws Exception
+ public VirtualHost(VirtualHostConfiguration hostConfig, TransactionLog transactionLog) throws Exception
{
- if (name == null || name.length() == 0)
+ _configuration = hostConfig;
+ _name = hostConfig.getName();
+
+ if (_name == null || _name.length() == 0)
{
- throw new IllegalArgumentException("Illegal name (" + name + ") for virtualhost.");
+ throw new IllegalArgumentException("Illegal name (" + _name + ") for virtualhost.");
}
- _name = name;
-
_virtualHostMBean = new VirtualHostMBean();
_connectionRegistry = new ConnectionRegistry(this);
- _houseKeepingTimer = new Timer("Queue-housekeeping-"+name, true);
+ _houseKeepingTimer = new Timer("Queue-housekeeping-" + _name, true);
+
_queueRegistry = new DefaultQueueRegistry(this);
+
_exchangeFactory = new DefaultExchangeFactory(this);
_exchangeFactory.initialise(hostConfig);
+
_exchangeRegistry = new DefaultExchangeRegistry(this);
+ _queueBackingStoreFactory = new FileQueueBackingStoreFactory();
+ _queueBackingStoreFactory.configure(this, hostConfig);
+
+ //Create a temporary RT to store the durable entries from the config file
+ // so we can replay them in to the real _RT after it has been loaded.
+ /// This should be removed after the _RT has been fully split from the the TL
+
+ StartupRoutingTable configFileRT = new StartupRoutingTable();
+
+ _routingTable = configFileRT;
+
+ // This needs to be after the RT has been defined as it creates the default durable exchanges.
+ _exchangeRegistry.initialise();
+ initialiseModel(hostConfig);
+
if (transactionLog != null)
{
_transactionLog = transactionLog;
@@ -183,41 +209,47 @@ public class VirtualHost implements Accessable
}
else
{
- if (hostConfig == null)
- {
- throw new IllegalAccessException("HostConfig and TransactionLog cannot be null");
- }
initialiseTransactionLog(hostConfig);
initialiseRoutingTable(hostConfig);
}
+ //Now that the RT has been initialised loop through the persistent queues/exchanges created from the config
+ // file and write them in to the new routing Table.
+ for (StartupRoutingTable.CreateQueueTuple cqt : configFileRT.queue)
+ {
+ _routingTable.createQueue(cqt.queue, cqt.arguments);
+ }
+ for (Exchange exchange : configFileRT.exchange)
+ {
+ _routingTable.createExchange(exchange);
+ }
- _exchangeRegistry.initialise();
+ for (StartupRoutingTable.CreateBindingTuple cbt : configFileRT.bindings)
+ {
+ _routingTable.bindQueue(cbt.exchange, cbt.routingKey, cbt.queue, cbt.arguments);
+ }
- _authenticationManager = new PrincipalDatabaseAuthenticationManager(name, hostConfig);
+ _authenticationManager = new PrincipalDatabaseAuthenticationManager(_name, hostConfig);
_accessManager = ApplicationRegistry.getInstance().getAccessManager();
- _accessManager.configureHostPlugins(hostConfig);
-
+ _accessManager.configureHostPlugins(hostConfig.getSecurityConfiguration());
+
_brokerMBean = new AMQBrokerManagerMBean(_virtualHostMBean);
_brokerMBean.register();
- initialiseHouseKeeping(hostConfig);
+ initialiseHouseKeeping(hostConfig.getHousekeepingExpiredMessageCheckPeriod());
}
- private void initialiseHouseKeeping(final Configuration hostConfig)
+ private void initialiseHouseKeeping(long period)
{
-
- long period = hostConfig.getLong("housekeeping.expiredMessageCheckPeriod", DEFAULT_HOUSEKEEPING_PERIOD);
-
/* add a timer task to iterate over queues, cleaning expired messages from queues with no consumers */
- if(period != 0L)
+ if (period != 0L)
{
class RemoveExpiredMessagesTask extends TimerTask
{
public void run()
{
- for(AMQQueue q : _queueRegistry.getQueues())
+ for (AMQQueue q : _queueRegistry.getQueues())
{
try
@@ -226,7 +258,7 @@ public class VirtualHost implements Accessable
}
catch (AMQException e)
{
- _logger.error("Exception in housekeeping for queue: " + q.getName().toString(),e);
+ _logger.error("Exception in housekeeping for queue: " + q.getName().toString(), e);
throw new RuntimeException(e);
}
}
@@ -234,15 +266,15 @@ public class VirtualHost implements Accessable
}
_houseKeepingTimer.scheduleAtFixedRate(new RemoveExpiredMessagesTask(),
- period/2,
- period);
+ period / 2,
+ period);
}
}
//todo we need to move from store.class to transactionlog.class
- private void initialiseTransactionLog(Configuration config) throws Exception
+ private void initialiseTransactionLog(VirtualHostConfiguration config) throws Exception
{
- String transactionLogClass = config.getString("store.class");
+ String transactionLogClass = config.getTransactionLogClass();
Class clazz = Class.forName(transactionLogClass);
Object o = clazz.newInstance();
@@ -253,13 +285,20 @@ public class VirtualHost implements Accessable
" does not.");
}
_transactionLog = (TransactionLog) o;
+
+ //Assign RoutingTable as old MessageStores converted to TransactionLog will require the _routingTable.
+ if (_transactionLog instanceof RoutingTable)
+ {
+ _routingTable = (RoutingTable) _transactionLog;
+ }
+
_transactionLog.configure(this, "store", config);
}
//todo we need to move from store.class to transactionlog.class
- private void initialiseRoutingTable(Configuration config) throws Exception
+ private void initialiseRoutingTable(VirtualHostConfiguration hostConfig) throws Exception
{
- String transactionLogClass = config.getString("routingtable.class");
+ String transactionLogClass = hostConfig.getRoutingTableClass();
if (transactionLogClass != null)
{
@@ -272,34 +311,99 @@ public class VirtualHost implements Accessable
" does not.");
}
_routingTable = (RoutingTable) o;
- _routingTable.configure(this, "routingtable", config);
+ _routingTable.configure(this, "routingtable", hostConfig);
}
else
{
- if (_transactionLog instanceof RoutingTable)
+ if (_routingTable == null)
{
- _routingTable = (RoutingTable)_transactionLog;
+ throw new RuntimeException("No Routing Table configured unable to startup.");
}
}
}
+ private void initialiseModel(VirtualHostConfiguration config) throws ConfigurationException, AMQException
+ {
+ _logger.debug("Loading configuration for virtualhost: " + config.getName());
+
+ List exchangeNames = config.getExchanges();
+ for (Object exchangeNameObj : exchangeNames)
+ {
+ String exchangeName = String.valueOf(exchangeNameObj);
+ configureExchange(config.getExchangeConfiguration(exchangeName));
+ }
- public <T> T getConfiguredObject(Class<T> instanceType, Configuration config)
+ String[] queueNames = config.getQueueNames();
+
+ for (Object queueNameObj : queueNames)
+ {
+ String queueName = String.valueOf(queueNameObj);
+ configureQueue(config.getQueueConfiguration(queueName));
+ }
+ }
+
+ private void configureExchange(ExchangeConfiguration exchangeConfiguration) throws AMQException
+ {
+ AMQShortString exchangeName = new AMQShortString(exchangeConfiguration.getName());
+
+ Exchange exchange;
+ exchange = _exchangeRegistry.getExchange(exchangeName);
+ if (exchange == null)
+ {
+
+ AMQShortString type = new AMQShortString(exchangeConfiguration.getType());
+ boolean durable = exchangeConfiguration.getDurable();
+ boolean autodelete = exchangeConfiguration.getAutoDelete();
+
+ Exchange newExchange = _exchangeFactory.createExchange(exchangeName, type, durable, autodelete, 0);
+ _exchangeRegistry.registerExchange(newExchange);
+ }
+ }
+
+ private void configureQueue(QueueConfiguration queueConfiguration) throws AMQException, ConfigurationException
{
- T instance;
- try
+ AMQQueue queue = AMQQueueFactory.createAMQQueueImpl(queueConfiguration, this);
+
+ if (queue.isDurable())
+ {
+ _routingTable.createQueue(queue);
+ }
+
+ String exchangeName = queueConfiguration.getExchange();
+
+ Exchange exchange = _exchangeRegistry.getExchange(exchangeName == null ? null : new AMQShortString(exchangeName));
+
+ if (exchange == null)
+ {
+ exchange = _exchangeRegistry.getDefaultExchange();
+ }
+
+ if (exchange == null)
+ {
+ throw new ConfigurationException("Attempt to bind queue to unknown exchange:" + exchangeName);
+ }
+
+ List routingKeys = queueConfiguration.getRoutingKeys();
+ if (routingKeys == null || routingKeys.isEmpty())
{
- instance = instanceType.newInstance();
+ routingKeys = Collections.singletonList(queue.getName());
}
- catch (Exception e)
+
+ for (Object routingKeyNameObj : routingKeys)
{
- _logger.error("Unable to instantiate configuration class " + instanceType + " - ensure it has a public default constructor");
- throw new IllegalArgumentException("Unable to instantiate configuration class " + instanceType + " - ensure it has a public default constructor", e);
+ AMQShortString routingKey = new AMQShortString(String.valueOf(routingKeyNameObj));
+ if (_logger.isInfoEnabled())
+ {
+ _logger.info("Binding queue:" + queue + " with routing key '" + routingKey + "' to exchange:" + this);
+ }
+ queue.bind(exchange, routingKey, null);
}
- Configurator.configure(instance);
- return instance;
+ if (exchange != _exchangeRegistry.getDefaultExchange())
+ {
+ queue.bind(_exchangeRegistry.getDefaultExchange(), queue.getName(), null);
+ }
}
public String getName()
@@ -340,7 +444,7 @@ public class VirtualHost implements Accessable
public ACLManager getAccessManager()
{
return _accessManager;
- }
+ }
public void close() throws Exception
{
@@ -348,6 +452,12 @@ public class VirtualHost implements Accessable
//Stop Connections
_connectionRegistry.close();
+ //Stop Housekeeping
+ if (_houseKeepingTimer != null)
+ {
+ _houseKeepingTimer.cancel();
+ }
+
//Stop the Queues processing
if (_queueRegistry != null)
{
@@ -355,13 +465,7 @@ public class VirtualHost implements Accessable
{
queue.stop();
}
- }
-
- //Stop Housekeeping
- if (_houseKeepingTimer != null)
- {
- _houseKeepingTimer.cancel();
- }
+ }
//Close TransactionLog
if (_transactionLog != null)
@@ -379,4 +483,95 @@ public class VirtualHost implements Accessable
{
return _virtualHostMBean;
}
+
+ /**
+ * Temporary Startup RT class to record the creation of persistent queues / exchanges.
+ *
+ *
+ * This is so we can replay the creation of queues/exchanges in to the real _RT after it has been loaded.
+ * This should be removed after the _RT has been fully split from the the TL
+ */
+ private class StartupRoutingTable implements RoutingTable
+ {
+ public List<Exchange> exchange = new LinkedList<Exchange>();
+ public List<CreateQueueTuple> queue = new LinkedList<CreateQueueTuple>();
+ public List<CreateBindingTuple> bindings = new LinkedList<CreateBindingTuple>();
+
+ public void configure(VirtualHost virtualHost, String base, VirtualHostConfiguration config) throws Exception
+ {
+ }
+
+ public void close() throws Exception
+ {
+ }
+
+ public void createExchange(Exchange exchange) throws AMQException
+ {
+ if (exchange.isDurable())
+ {
+ this.exchange.add(exchange);
+ }
+ }
+
+ public void removeExchange(Exchange exchange) throws AMQException
+ {
+ }
+
+ public void bindQueue(Exchange exchange, AMQShortString routingKey, AMQQueue queue, FieldTable args) throws AMQException
+ {
+ if (exchange.isDurable() && queue.isDurable())
+ {
+ bindings.add(new CreateBindingTuple(exchange, routingKey, queue, args));
+ }
+ }
+
+ public void unbindQueue(Exchange exchange, AMQShortString routingKey, AMQQueue queue, FieldTable args) throws AMQException
+ {
+ }
+
+ public void createQueue(AMQQueue queue) throws AMQException
+ {
+ createQueue(queue, null);
+ }
+
+ public void createQueue(AMQQueue queue, FieldTable arguments) throws AMQException
+ {
+ if (queue.isDurable())
+ {
+ this.queue.add(new CreateQueueTuple(queue, arguments));
+ }
+ }
+
+ public void removeQueue(AMQQueue queue) throws AMQException
+ {
+ }
+
+ private class CreateQueueTuple
+ {
+ public AMQQueue queue;
+ public FieldTable arguments;
+
+ public CreateQueueTuple(AMQQueue queue, FieldTable arguments)
+ {
+ this.queue = queue;
+ this.arguments = arguments;
+ }
+ }
+
+ private class CreateBindingTuple
+ {
+ public AMQQueue queue;
+ public FieldTable arguments;
+ public Exchange exchange;
+ public AMQShortString routingKey;
+
+ public CreateBindingTuple(Exchange exchange, AMQShortString routingKey, AMQQueue queue, FieldTable args)
+ {
+ this.exchange = exchange;
+ this.routingKey = routingKey;
+ this.queue = queue;
+ arguments = args;
+ }
+ }
+ }
}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/tools/messagestore/commands/Move.java b/qpid/java/broker/src/main/java/org/apache/qpid/tools/messagestore/commands/Move.java
index a8dd58ca83..7fe16062fc 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/tools/messagestore/commands/Move.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/tools/messagestore/commands/Move.java
@@ -172,7 +172,7 @@ public class Move extends AbstractCommand
{
for (QueueEntry msg : messages)
{
- ids.add(msg.getMessage().getMessageId());
+ ids.add(msg.getMessageId());
}
}
}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/tools/messagestore/commands/Show.java b/qpid/java/broker/src/main/java/org/apache/qpid/tools/messagestore/commands/Show.java
index d46ba85069..49afcb1340 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/tools/messagestore/commands/Show.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/tools/messagestore/commands/Show.java
@@ -352,7 +352,7 @@ public class Show extends AbstractCommand
isredelivered.add(entry.isRedelivered() ? "true" : "false");
- isdelivered.add(msg.getDeliveredToConsumer() ? "true" : "false");
+ isdelivered.add(entry.getDeliveredToConsumer() ? "true" : "false");
BasicContentHeaderProperties headers = null;
diff --git a/qpid/java/broker/src/test/java/org/apache/qpid/server/ExtractResendAndRequeueTest.java b/qpid/java/broker/src/test/java/org/apache/qpid/server/ExtractResendAndRequeueTest.java
index 2a97db6066..c370fd9867 100644
--- a/qpid/java/broker/src/test/java/org/apache/qpid/server/ExtractResendAndRequeueTest.java
+++ b/qpid/java/broker/src/test/java/org/apache/qpid/server/ExtractResendAndRequeueTest.java
@@ -32,6 +32,7 @@ import org.apache.qpid.server.queue.AMQMessage;
import org.apache.qpid.server.store.StoreContext;
import org.apache.qpid.server.subscription.Subscription;
import org.apache.qpid.server.subscription.MockSubscription;
+import org.apache.qpid.server.registry.ApplicationRegistry;
import org.apache.qpid.AMQException;
import java.util.Map;
@@ -87,7 +88,7 @@ public class ExtractResendAndRequeueTest extends TestCase
while(queueEntries.advance())
{
QueueEntry entry = queueEntries.getNode();
- _unacknowledgedMessageMap.add(entry.getMessage().getMessageId(), entry);
+ _unacknowledgedMessageMap.add(entry.getMessageId(), entry);
// Store the entry for future inspection
_referenceList.add(entry);
@@ -96,6 +97,12 @@ public class ExtractResendAndRequeueTest extends TestCase
assertEquals("Map does not contain correct setup data", INITIAL_MSG_COUNT, _unacknowledgedMessageMap.size());
}
+ public void tearDown() throws Exception
+ {
+ //Ensure we close the registry that the MockAMQQueue will create
+ ApplicationRegistry.getInstance().close();
+ }
+
/**
* Helper method to create a new subscription and aquire the given messages.
*
diff --git a/qpid/java/broker/src/test/java/org/apache/qpid/server/ack/TxAckTest.java b/qpid/java/broker/src/test/java/org/apache/qpid/server/ack/TxAckTest.java
index 01533d6509..52b8b0ad19 100644
--- a/qpid/java/broker/src/test/java/org/apache/qpid/server/ack/TxAckTest.java
+++ b/qpid/java/broker/src/test/java/org/apache/qpid/server/ack/TxAckTest.java
@@ -21,12 +21,16 @@
package org.apache.qpid.server.ack;
import junit.framework.TestCase;
+
+import org.apache.commons.configuration.PropertiesConfiguration;
import org.apache.qpid.AMQException;
import org.apache.qpid.framing.AMQShortString;
import org.apache.qpid.framing.ContentHeaderBody;
import org.apache.qpid.framing.abstraction.MessagePublishInfo;
import org.apache.qpid.server.RequiredDeliveryException;
+import org.apache.qpid.server.transactionlog.TransactionLog;
import org.apache.qpid.server.virtualhost.VirtualHost;
+import org.apache.qpid.server.configuration.VirtualHostConfiguration;
import org.apache.qpid.server.queue.AMQMessage;
import org.apache.qpid.server.queue.MessageFactory;
import org.apache.qpid.server.queue.QueueEntry;
@@ -34,9 +38,10 @@ import org.apache.qpid.server.queue.AMQQueueFactory;
import org.apache.qpid.server.queue.AMQQueue;
import org.apache.qpid.server.queue.TransientAMQMessage;
import org.apache.qpid.framing.abstraction.MessagePublishInfoImpl;
-import org.apache.qpid.server.store.TestMemoryMessageStore;
import org.apache.qpid.server.store.StoreContext;
import org.apache.qpid.server.store.MemoryMessageStore;
+import org.apache.qpid.server.store.TestTransactionLog;
+import org.apache.qpid.server.store.TestableMemoryMessageStore;
import org.apache.qpid.server.txn.NonTransactionalContext;
import org.apache.qpid.server.txn.TransactionalContext;
@@ -78,20 +83,6 @@ public class TxAckTest extends TestCase
combined.stop();
}
- public void testPrepare() throws AMQException
- {
- individual.prepare();
- multiple.prepare();
- combined.prepare();
- }
-
- public void testUndoPrepare() throws AMQException
- {
- individual.undoPrepare();
- multiple.undoPrepare();
- combined.undoPrepare();
- }
-
public void testCommit() throws AMQException
{
individual.commit();
@@ -112,17 +103,23 @@ public class TxAckTest extends TestCase
private final List<Long> _unacked;
private StoreContext _storeContext = new StoreContext();
private AMQQueue _queue;
+ private TransactionLog _transactionLog = new TestableMemoryMessageStore();
private static final int MESSAGE_SIZE=100;
Scenario(int messageCount, List<Long> acked, List<Long> unacked) throws Exception
{
- TransactionalContext txnContext = new NonTransactionalContext(new TestMemoryMessageStore(),
+ TransactionalContext txnContext = new NonTransactionalContext(_transactionLog,
_storeContext, null,
new LinkedList<RequiredDeliveryException>()
);
- _queue = AMQQueueFactory.createAMQQueueImpl(new AMQShortString("test"), false, null, false, new VirtualHost("test", new MemoryMessageStore()),
- null);
+
+ PropertiesConfiguration env = new PropertiesConfiguration();
+ env.setProperty("name", "test");
+ VirtualHost virtualHost = new VirtualHost(new VirtualHostConfiguration("test", env));
+
+ _queue = AMQQueueFactory.createAMQQueueImpl(new AMQShortString("test"), false, null, false,
+ virtualHost, null);
for (int i = 0; i < messageCount; i++)
{
@@ -130,12 +127,15 @@ public class TxAckTest extends TestCase
MessagePublishInfo info = new MessagePublishInfoImpl();
- AMQMessage message = new TestMessage(deliveryTag, info);
+ AMQMessage message = new TestMessage(deliveryTag, info, (TestTransactionLog) _transactionLog);
ContentHeaderBody header = new ContentHeaderBody();
header.bodySize = MESSAGE_SIZE;
message.setPublishAndContentHeaderBody(_storeContext, info, header);
+
+
+
_map.add(deliveryTag, _queue.enqueue(new StoreContext(), message));
}
_acked = acked;
@@ -157,25 +157,6 @@ public class TxAckTest extends TestCase
}
}
- void prepare() throws AMQException
- {
- _op.consolidate();
- _op.prepare(_storeContext);
-
- assertCount(_acked, -1);
- assertCount(_unacked, 0);
-
- }
-
- void undoPrepare()
- {
- _op.consolidate();
- _op.undoPrepare();
-
- assertCount(_acked, 1);
- assertCount(_unacked, 0);
- }
-
void commit()
{
_op.consolidate();
@@ -224,30 +205,22 @@ public class TxAckTest extends TestCase
private class TestMessage extends TransientAMQMessage
{
private final long _tag;
- private int _count;
+ private TestTransactionLog _transactionLog;
- TestMessage(long tag, MessagePublishInfo publishBody)
+ public TestMessage(long tag, MessagePublishInfo publishBody, TestTransactionLog transactionLog)
throws AMQException
{
super(createMessage( publishBody));
_tag = tag;
+ _transactionLog = transactionLog;
}
- public boolean incrementReference()
- {
- _count++;
- return true;
- }
-
- public void decrementReference(StoreContext context)
- {
- _count--;
- }
-
void assertCountEquals(int expected)
{
- assertEquals("Wrong count for message with tag " + _tag, expected, _count);
+ List<AMQQueue> list = _transactionLog.getMessageReferenceMap(_messageId);
+ int actual = (list == null ? 0 : list.size());
+ assertEquals("Wrong count for message with tag " + _tag, expected, actual);
}
}
}
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
new file mode 100644
index 0000000000..ad1df1c777
--- /dev/null
+++ b/qpid/java/broker/src/test/java/org/apache/qpid/server/configuration/ServerConfigurationTest.java
@@ -0,0 +1,849 @@
+/*
+ *
+ * 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.configuration;
+
+import java.io.File;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.io.RandomAccessFile;
+import java.util.List;
+
+import org.apache.commons.configuration.ConfigurationException;
+import org.apache.commons.configuration.PropertiesConfiguration;
+import org.apache.commons.configuration.SystemConfiguration;
+import org.apache.commons.configuration.XMLConfiguration;
+import org.apache.qpid.AMQException;
+import org.apache.qpid.codec.AMQCodecFactory;
+import org.apache.qpid.server.protocol.AMQMinaProtocolSession;
+import org.apache.qpid.server.protocol.AMQProtocolSession;
+import org.apache.qpid.server.protocol.TestIoSession;
+import org.apache.qpid.server.queue.MockProtocolSession;
+import org.apache.qpid.server.registry.ApplicationRegistry;
+import org.apache.qpid.server.registry.ConfigurationFileApplicationRegistry;
+import org.apache.qpid.server.security.access.ACLManager;
+import org.apache.qpid.server.virtualhost.VirtualHost;
+import org.apache.qpid.server.virtualhost.VirtualHostRegistry;
+
+import junit.framework.TestCase;
+
+public class ServerConfigurationTest extends TestCase
+{
+
+ private XMLConfiguration _config;
+
+ @Override
+ public void setUp()
+ {
+ _config = new XMLConfiguration();
+ }
+
+ @Override
+ public void tearDown()
+ {
+ ApplicationRegistry.removeAll();
+ }
+
+ public void testSetJMXManagementPort() throws ConfigurationException
+ {
+ ServerConfiguration serverConfig = new ServerConfiguration(_config);
+ serverConfig.setJMXManagementPort(23);
+ assertEquals(23, serverConfig.getJMXManagementPort());
+ }
+
+ public void testGetJMXManagementPort() throws ConfigurationException
+ {
+ _config.setProperty("management.jmxport", 42);
+ ServerConfiguration serverConfig = new ServerConfiguration(_config);
+ assertEquals(42, serverConfig.getJMXManagementPort());
+ }
+
+ public void testGetPlatformMbeanserver() throws ConfigurationException
+ {
+ // Check default
+ ServerConfiguration serverConfig = new ServerConfiguration(_config);
+ assertEquals(true, serverConfig.getPlatformMbeanserver());
+
+ // Check value we set
+ _config.setProperty("management.platform-mbeanserver", false);
+ serverConfig = new ServerConfiguration(_config);
+ assertEquals(false, serverConfig.getPlatformMbeanserver());
+ }
+
+ public void testGetPluginDirectory() throws ConfigurationException
+ {
+ // Check default
+ ServerConfiguration serverConfig = new ServerConfiguration(_config);
+ assertEquals(null, serverConfig.getPluginDirectory());
+
+ // Check value we set
+ _config.setProperty("plugin-directory", "/path/to/plugins");
+ serverConfig = new ServerConfiguration(_config);
+ assertEquals("/path/to/plugins", serverConfig.getPluginDirectory());
+ }
+
+ public void testGetPrincipalDatabaseNames() throws ConfigurationException
+ {
+ // Check default
+ ServerConfiguration serverConfig = new ServerConfiguration(_config);
+ assertEquals(0, serverConfig.getPrincipalDatabaseNames().size());
+
+ // Check value we set
+ _config.setProperty("security.principal-databases.principal-database(0).name", "a");
+ _config.setProperty("security.principal-databases.principal-database(1).name", "b");
+ serverConfig = new ServerConfiguration(_config);
+ List<String> dbs = serverConfig.getPrincipalDatabaseNames();
+ assertEquals(2, dbs.size());
+ assertEquals("a", dbs.get(0));
+ assertEquals("b", dbs.get(1));
+ }
+
+ public void testGetPrincipalDatabaseClass() throws ConfigurationException
+ {
+ // Check default
+ ServerConfiguration serverConfig = new ServerConfiguration(_config);
+ assertEquals(0, serverConfig.getPrincipalDatabaseClass().size());
+
+ // Check value we set
+ _config.setProperty("security.principal-databases.principal-database(0).class", "a");
+ _config.setProperty("security.principal-databases.principal-database(1).class", "b");
+ serverConfig = new ServerConfiguration(_config);
+ List<String> dbs = serverConfig.getPrincipalDatabaseClass();
+ assertEquals(2, dbs.size());
+ assertEquals("a", dbs.get(0));
+ assertEquals("b", dbs.get(1));
+ }
+
+ public void testGetPrincipalDatabaseAttributeNames() throws ConfigurationException
+ {
+ // Check default
+ ServerConfiguration serverConfig = new ServerConfiguration(_config);
+ assertEquals(0, serverConfig.getPrincipalDatabaseAttributeNames(1).size());
+
+ // Check value we set
+ _config.setProperty("security.principal-databases.principal-database(0).attributes(0).attribute.name", "a");
+ _config.setProperty("security.principal-databases.principal-database(0).attributes(1).attribute.name", "b");
+ serverConfig = new ServerConfiguration(_config);
+ List<String> dbs = serverConfig.getPrincipalDatabaseAttributeNames(0);
+ assertEquals(2, dbs.size());
+ assertEquals("a", dbs.get(0));
+ assertEquals("b", dbs.get(1));
+ }
+
+ public void testGetPrincipalDatabaseAttributeValues() throws ConfigurationException
+ {
+ // Check default
+ ServerConfiguration serverConfig = new ServerConfiguration(_config);
+ assertEquals(0, serverConfig.getPrincipalDatabaseAttributeValues(1).size());
+
+ // Check value we set
+ _config.setProperty("security.principal-databases.principal-database(0).attributes(0).attribute.value", "a");
+ _config.setProperty("security.principal-databases.principal-database(0).attributes(1).attribute.value", "b");
+ serverConfig = new ServerConfiguration(_config);
+ List<String> dbs = serverConfig.getPrincipalDatabaseAttributeValues(0);
+ assertEquals(2, dbs.size());
+ assertEquals("a", dbs.get(0));
+ assertEquals("b", dbs.get(1));
+ }
+
+ public void testGetManagementAccessList() throws ConfigurationException
+ {
+ // Check default
+ ServerConfiguration serverConfig = new ServerConfiguration(_config);
+ assertEquals(0, serverConfig.getManagementAccessList().size());
+
+ // Check value we set
+ _config.setProperty("security.jmx.access(0)", "a");
+ _config.setProperty("security.jmx.access(1)", "b");
+ serverConfig = new ServerConfiguration(_config);
+ List<String> dbs = serverConfig.getManagementAccessList();
+ assertEquals(2, dbs.size());
+ assertEquals("a", dbs.get(0));
+ assertEquals("b", dbs.get(1));
+ }
+
+ public void testGetFrameSize() throws ConfigurationException
+ {
+ // Check default
+ ServerConfiguration serverConfig = new ServerConfiguration(_config);
+ assertEquals(65536, serverConfig.getFrameSize());
+
+ // Check value we set
+ _config.setProperty("advanced.framesize", "23");
+ serverConfig = new ServerConfiguration(_config);
+ assertEquals(23, serverConfig.getFrameSize());
+ }
+
+ public void testGetProtectIOEnabled() throws ConfigurationException
+ {
+ // Check default
+ ServerConfiguration serverConfig = new ServerConfiguration(_config);
+ assertEquals(false, serverConfig.getProtectIOEnabled());
+
+ // Check value we set
+ _config.setProperty("broker.connector.protectio.enabled", true);
+ serverConfig = new ServerConfiguration(_config);
+ assertEquals(true, serverConfig.getProtectIOEnabled());
+ }
+
+ public void testGetBufferReadLimit() throws ConfigurationException
+ {
+ // Check default
+ ServerConfiguration serverConfig = new ServerConfiguration(_config);
+ assertEquals(262144, serverConfig.getBufferReadLimit());
+
+ // Check value we set
+ _config.setProperty("broker.connector.protectio.readBufferLimitSize", 23);
+ serverConfig = new ServerConfiguration(_config);
+ assertEquals(23, serverConfig.getBufferReadLimit());
+ }
+
+ public void testGetBufferWriteLimit() throws ConfigurationException
+ {
+ // Check default
+ ServerConfiguration serverConfig = new ServerConfiguration(_config);
+ assertEquals(262144, serverConfig.getBufferWriteLimit());
+
+ // Check value we set
+ _config.setProperty("broker.connector.protectio.writeBufferLimitSize", 23);
+ serverConfig = new ServerConfiguration(_config);
+ assertEquals(23, serverConfig.getBufferWriteLimit());
+ }
+
+ public void testGetSynchedClocks() throws ConfigurationException
+ {
+ // Check default
+ ServerConfiguration serverConfig = new ServerConfiguration(_config);
+ assertEquals(false, serverConfig.getSynchedClocks());
+
+ // Check value we set
+ _config.setProperty("advanced.synced-clocks", true);
+ serverConfig = new ServerConfiguration(_config);
+ assertEquals(true, serverConfig.getSynchedClocks());
+ }
+
+ public void testGetMsgAuth() throws ConfigurationException
+ {
+ // Check default
+ ServerConfiguration serverConfig = new ServerConfiguration(_config);
+ assertEquals(false, serverConfig.getMsgAuth());
+
+ // Check value we set
+ _config.setProperty("security.msg-auth", true);
+ serverConfig = new ServerConfiguration(_config);
+ assertEquals(true, serverConfig.getMsgAuth());
+ }
+
+ public void testGetJMXPrincipalDatabase() throws ConfigurationException
+ {
+ // Check default
+ ServerConfiguration serverConfig = new ServerConfiguration(_config);
+ assertEquals(null, serverConfig.getJMXPrincipalDatabase());
+
+ // Check value we set
+ _config.setProperty("security.jmx.principal-database", "a");
+ serverConfig = new ServerConfiguration(_config);
+ assertEquals("a", serverConfig.getJMXPrincipalDatabase());
+ }
+
+ public void testGetManagementKeyStorePath() throws ConfigurationException
+ {
+ // Check default
+ ServerConfiguration serverConfig = new ServerConfiguration(_config);
+ assertEquals(null, serverConfig.getManagementKeyStorePath());
+
+ // Check value we set
+ _config.setProperty("management.ssl.keyStorePath", "a");
+ serverConfig = new ServerConfiguration(_config);
+ assertEquals("a", serverConfig.getManagementKeyStorePath());
+ }
+
+ public void testGetManagementSSLEnabled() throws ConfigurationException
+ {
+ // Check default
+ ServerConfiguration serverConfig = new ServerConfiguration(_config);
+ assertEquals(true, serverConfig.getManagementSSLEnabled());
+
+ // Check value we set
+ _config.setProperty("management.ssl.enabled", false);
+ serverConfig = new ServerConfiguration(_config);
+ assertEquals(false, serverConfig.getManagementSSLEnabled());
+ }
+
+ public void testGetManagementKeyStorePassword() throws ConfigurationException
+ {
+ // Check default
+ ServerConfiguration serverConfig = new ServerConfiguration(_config);
+ assertEquals(null, serverConfig.getManagementKeyStorePassword());
+
+ // Check value we set
+ _config.setProperty("management.ssl.keyStorePassword", "a");
+ serverConfig = new ServerConfiguration(_config);
+ assertEquals("a", serverConfig.getManagementKeyStorePassword());
+ }
+
+ public void testGetQueueAutoRegister() throws ConfigurationException
+ {
+ // Check default
+ ServerConfiguration serverConfig = new ServerConfiguration(_config);
+ assertEquals(true, serverConfig.getQueueAutoRegister());
+
+ // Check value we set
+ _config.setProperty("queue.auto_register", false);
+ serverConfig = new ServerConfiguration(_config);
+ assertEquals(false, serverConfig.getQueueAutoRegister());
+ }
+
+ public void testGetManagementEnabled() throws ConfigurationException
+ {
+ // Check default
+ ServerConfiguration serverConfig = new ServerConfiguration(_config);
+ assertEquals(true, serverConfig.getManagementEnabled());
+
+ // Check value we set
+ _config.setProperty("management.enabled", false);
+ serverConfig = new ServerConfiguration(_config);
+ assertEquals(false, serverConfig.getManagementEnabled());
+ }
+
+ public void testSetManagementEnabled() throws ConfigurationException
+ {
+ // Check value we set
+ ServerConfiguration serverConfig = new ServerConfiguration(_config);
+ serverConfig.setManagementEnabled(false);
+ assertEquals(false, serverConfig.getManagementEnabled());
+ }
+
+ public void testGetHeartBeatDelay() throws ConfigurationException
+ {
+ // Check default
+ ServerConfiguration serverConfig = new ServerConfiguration(_config);
+ assertEquals(5, serverConfig.getHeartBeatDelay());
+
+ // Check value we set
+ _config.setProperty("heartbeat.delay", 23);
+ serverConfig = new ServerConfiguration(_config);
+ assertEquals(23, serverConfig.getHeartBeatDelay());
+ }
+
+ public void testGetHeartBeatTimeout() throws ConfigurationException
+ {
+ // Check default
+ ServerConfiguration serverConfig = new ServerConfiguration(_config);
+ assertEquals(2.0, serverConfig.getHeartBeatTimeout());
+
+ // Check value we set
+ _config.setProperty("heartbeat.timeoutFactor", 2.3);
+ serverConfig = new ServerConfiguration(_config);
+ assertEquals(2.3, serverConfig.getHeartBeatTimeout());
+ }
+
+ public void testGetMaximumMessageAge() throws ConfigurationException
+ {
+ // Check default
+ ServerConfiguration serverConfig = new ServerConfiguration(_config);
+ assertEquals(0, serverConfig.getMaximumMessageAge());
+
+ // Check value we set
+ _config.setProperty("maximumMessageAge", 10L);
+ serverConfig = new ServerConfiguration(_config);
+ assertEquals(10, serverConfig.getMaximumMessageAge());
+ }
+
+ public void testGetMaximumMessageCount() throws ConfigurationException
+ {
+ // Check default
+ ServerConfiguration serverConfig = new ServerConfiguration(_config);
+ assertEquals(0, serverConfig.getMaximumMessageCount());
+
+ // Check value we set
+ _config.setProperty("maximumMessageCount", 10L);
+ serverConfig = new ServerConfiguration(_config);
+ assertEquals(10, serverConfig.getMaximumMessageCount());
+ }
+
+ public void testGetMaximumQueueDepth() throws ConfigurationException
+ {
+ // Check default
+ ServerConfiguration serverConfig = new ServerConfiguration(_config);
+ assertEquals(0, serverConfig.getMaximumQueueDepth());
+
+ // Check value we set
+ _config.setProperty("maximumQueueDepth", 10L);
+ serverConfig = new ServerConfiguration(_config);
+ assertEquals(10, serverConfig.getMaximumQueueDepth());
+ }
+
+ public void testGetMaximumMessageSize() throws ConfigurationException
+ {
+ // Check default
+ ServerConfiguration serverConfig = new ServerConfiguration(_config);
+ assertEquals(0, serverConfig.getMaximumMessageSize());
+
+ // Check value we set
+ _config.setProperty("maximumMessageSize", 10L);
+ serverConfig = new ServerConfiguration(_config);
+ assertEquals(10, serverConfig.getMaximumMessageSize());
+ }
+
+ public void testGetMinimumAlertRepeatGap() throws ConfigurationException
+ {
+ // Check default
+ ServerConfiguration serverConfig = new ServerConfiguration(_config);
+ assertEquals(0, serverConfig.getMinimumAlertRepeatGap());
+
+ // Check value we set
+ _config.setProperty("minimumAlertRepeatGap", 10L);
+ serverConfig = new ServerConfiguration(_config);
+ assertEquals(10, serverConfig.getMinimumAlertRepeatGap());
+ }
+
+ public void testGetProcessors() throws ConfigurationException
+ {
+ // Check default
+ ServerConfiguration serverConfig = new ServerConfiguration(_config);
+ assertEquals(4, serverConfig.getProcessors());
+
+ // Check value we set
+ _config.setProperty("connector.processors", 10);
+ serverConfig = new ServerConfiguration(_config);
+ assertEquals(10, serverConfig.getProcessors());
+ }
+
+ public void testGetPort() throws ConfigurationException
+ {
+ // Check default
+ ServerConfiguration serverConfig = new ServerConfiguration(_config);
+ assertEquals(5672, serverConfig.getPort());
+
+ // Check value we set
+ _config.setProperty("connector.port", 10);
+ serverConfig = new ServerConfiguration(_config);
+ assertEquals(10, serverConfig.getPort());
+ }
+
+ public void testGetBind() throws ConfigurationException
+ {
+ // Check default
+ ServerConfiguration serverConfig = new ServerConfiguration(_config);
+ assertEquals("wildcard", serverConfig.getBind());
+
+ // Check value we set
+ _config.setProperty("connector.bind", "a");
+ serverConfig = new ServerConfiguration(_config);
+ assertEquals("a", serverConfig.getBind());
+ }
+
+ public void testGetReceiveBufferSize() throws ConfigurationException
+ {
+ // Check default
+ ServerConfiguration serverConfig = new ServerConfiguration(_config);
+ assertEquals(32767, serverConfig.getReceiveBufferSize());
+
+ // Check value we set
+ _config.setProperty("connector.socketReceiveBuffer", "23");
+ serverConfig = new ServerConfiguration(_config);
+ assertEquals(23, serverConfig.getReceiveBufferSize());
+ }
+
+ public void testGetWriteBufferSize() throws ConfigurationException
+ {
+ // Check default
+ ServerConfiguration serverConfig = new ServerConfiguration(_config);
+ assertEquals(32767, serverConfig.getWriteBufferSize());
+
+ // Check value we set
+ _config.setProperty("connector.socketWriteBuffer", "23");
+ serverConfig = new ServerConfiguration(_config);
+ assertEquals(23, serverConfig.getWriteBufferSize());
+ }
+
+ public void testGetTcpNoDelay() throws ConfigurationException
+ {
+ // Check default
+ ServerConfiguration serverConfig = new ServerConfiguration(_config);
+ assertEquals(true, serverConfig.getTcpNoDelay());
+
+ // Check value we set
+ _config.setProperty("connector.tcpNoDelay", false);
+ serverConfig = new ServerConfiguration(_config);
+ assertEquals(false, serverConfig.getTcpNoDelay());
+ }
+
+ public void testGetEnableExecutorPool() throws ConfigurationException
+ {
+ // Check default
+ ServerConfiguration serverConfig = new ServerConfiguration(_config);
+ assertEquals(false, serverConfig.getEnableExecutorPool());
+
+ // Check value we set
+ _config.setProperty("advanced.filterchain[@enableExecutorPool]", true);
+ serverConfig = new ServerConfiguration(_config);
+ assertEquals(true, serverConfig.getEnableExecutorPool());
+ }
+
+ public void testGetEnablePooledAllocator() throws ConfigurationException
+ {
+ // Check default
+ ServerConfiguration serverConfig = new ServerConfiguration(_config);
+ assertEquals(false, serverConfig.getEnablePooledAllocator());
+
+ // Check value we set
+ _config.setProperty("advanced.enablePooledAllocator", true);
+ serverConfig = new ServerConfiguration(_config);
+ assertEquals(true, serverConfig.getEnablePooledAllocator());
+ }
+
+ public void testGetEnableDirectBuffers() throws ConfigurationException
+ {
+ // Check default
+ ServerConfiguration serverConfig = new ServerConfiguration(_config);
+ assertEquals(false, serverConfig.getEnableDirectBuffers());
+
+ // Check value we set
+ _config.setProperty("advanced.enableDirectBuffers", true);
+ serverConfig = new ServerConfiguration(_config);
+ assertEquals(true, serverConfig.getEnableDirectBuffers());
+ }
+
+ public void testGetEnableSSL() throws ConfigurationException
+ {
+ // Check default
+ ServerConfiguration serverConfig = new ServerConfiguration(_config);
+ assertEquals(false, serverConfig.getEnableSSL());
+
+ // Check value we set
+ _config.setProperty("connector.ssl.enabled", true);
+ serverConfig = new ServerConfiguration(_config);
+ assertEquals(true, serverConfig.getEnableSSL());
+ }
+
+ public void testGetSSLOnly() throws ConfigurationException
+ {
+ // Check default
+ ServerConfiguration serverConfig = new ServerConfiguration(_config);
+ assertEquals(true, serverConfig.getSSLOnly());
+
+ // Check value we set
+ _config.setProperty("connector.ssl.sslOnly", false);
+ serverConfig = new ServerConfiguration(_config);
+ assertEquals(false, serverConfig.getSSLOnly());
+ }
+
+ public void testGetSSLPort() throws ConfigurationException
+ {
+ // Check default
+ ServerConfiguration serverConfig = new ServerConfiguration(_config);
+ assertEquals(8672, serverConfig.getSSLPort());
+
+ // Check value we set
+ _config.setProperty("connector.ssl.port", 23);
+ serverConfig = new ServerConfiguration(_config);
+ assertEquals(23, serverConfig.getSSLPort());
+ }
+
+ public void testGetKeystorePath() throws ConfigurationException
+ {
+ // Check default
+ ServerConfiguration serverConfig = new ServerConfiguration(_config);
+ assertEquals("none", serverConfig.getKeystorePath());
+
+ // Check value we set
+ _config.setProperty("connector.ssl.keystorePath", "a");
+ serverConfig = new ServerConfiguration(_config);
+ assertEquals("a", serverConfig.getKeystorePath());
+ }
+
+ public void testGetKeystorePassword() throws ConfigurationException
+ {
+ // Check default
+ ServerConfiguration serverConfig = new ServerConfiguration(_config);
+ assertEquals("none", serverConfig.getKeystorePassword());
+
+ // Check value we set
+ _config.setProperty("connector.ssl.keystorePassword", "a");
+ serverConfig = new ServerConfiguration(_config);
+ assertEquals("a", serverConfig.getKeystorePassword());
+ }
+
+ public void testGetCertType() throws ConfigurationException
+ {
+ // Check default
+ ServerConfiguration serverConfig = new ServerConfiguration(_config);
+ assertEquals("SunX509", serverConfig.getCertType());
+
+ // Check value we set
+ _config.setProperty("connector.ssl.certType", "a");
+ serverConfig = new ServerConfiguration(_config);
+ assertEquals("a", serverConfig.getCertType());
+ }
+
+ public void testGetQpidNIO() throws ConfigurationException
+ {
+ // Check default
+ ServerConfiguration serverConfig = new ServerConfiguration(_config);
+ assertEquals(false, serverConfig.getQpidNIO());
+
+ // Check value we set
+ _config.setProperty("connector.qpidnio", true);
+ serverConfig = new ServerConfiguration(_config);
+ assertEquals(true, serverConfig.getQpidNIO());
+ }
+
+ public void testGetUseBiasedWrites() throws ConfigurationException
+ {
+ // Check default
+ ServerConfiguration serverConfig = new ServerConfiguration(_config);
+ assertEquals(false, serverConfig.getUseBiasedWrites());
+
+ // Check value we set
+ _config.setProperty("advanced.useWriteBiasedPool", true);
+ serverConfig = new ServerConfiguration(_config);
+ assertEquals(true, serverConfig.getUseBiasedWrites());
+ }
+
+ public void testGetHousekeepingExpiredMessageCheckPeriod() throws ConfigurationException
+ {
+ // Check default
+ ServerConfiguration serverConfig = new ServerConfiguration(_config);
+ assertEquals(30000, serverConfig.getHousekeepingCheckPeriod());
+
+ // Check value we set
+ _config.setProperty("housekeeping.expiredMessageCheckPeriod", 23L);
+ serverConfig = new ServerConfiguration(_config);
+ assertEquals(23, serverConfig.getHousekeepingCheckPeriod());
+ serverConfig.setHousekeepingExpiredMessageCheckPeriod(42L);
+ assertEquals(42, serverConfig.getHousekeepingCheckPeriod());
+ }
+
+ public void testSingleConfiguration() throws IOException, ConfigurationException
+ {
+ File fileA = File.createTempFile(getClass().getName(), null);
+ fileA.deleteOnExit();
+ FileWriter out = new FileWriter(fileA);
+ out.write("<broker><connector><port>2342</port><ssl><port>4235</port></ssl></connector></broker>");
+ out.close();
+ ServerConfiguration conf = new ServerConfiguration(fileA);
+ assertEquals(4235, conf.getSSLPort());
+ }
+
+ public void testCombinedConfiguration() throws IOException, ConfigurationException
+ {
+ File mainFile = File.createTempFile(getClass().getName(), null);
+ File fileA = File.createTempFile(getClass().getName(), null);
+ File fileB = File.createTempFile(getClass().getName(), null);
+
+ mainFile.deleteOnExit();
+ fileA.deleteOnExit();
+ fileB.deleteOnExit();
+
+ FileWriter out = new FileWriter(mainFile);
+ out.write("<configuration><system/>");
+ out.write("<xml fileName=\"" + fileA.getAbsolutePath() + "\"/>");
+ out.write("<xml fileName=\"" + fileB.getAbsolutePath() + "\"/>");
+ out.write("</configuration>");
+ out.close();
+
+ out = new FileWriter(fileA);
+ out.write("<broker><connector><port>2342</port><ssl><port>4235</port></ssl></connector></broker>");
+ out.close();
+
+ out = new FileWriter(fileB);
+ out.write("<broker><connector><ssl><port>2345</port></ssl><qpidnio>true</qpidnio></connector></broker>");
+ out.close();
+
+ ServerConfiguration config = new ServerConfiguration(mainFile.getAbsoluteFile());
+ assertEquals(4235, config.getSSLPort()); // From first file, not
+ // overriden by second
+ assertEquals(2342, config.getPort()); // From the first file, not
+ // present in the second
+ assertEquals(true, config.getQpidNIO()); // From the second file, not
+ // present in the first
+ }
+
+ public void testCombinedConfigurationFirewall() throws Exception
+ {
+ // Write out config
+ File mainFile = File.createTempFile(getClass().getName(), null);
+ File fileA = File.createTempFile(getClass().getName(), null);
+ File fileB = File.createTempFile(getClass().getName(), null);
+
+ mainFile.deleteOnExit();
+ fileA.deleteOnExit();
+ fileB.deleteOnExit();
+
+ FileWriter out = new FileWriter(mainFile);
+ out.write("<configuration><system/>");
+ out.write("<xml fileName=\"" + fileA.getAbsolutePath() + "\"/>");
+ out.write("</configuration>");
+ out.close();
+
+ out = new FileWriter(fileA);
+ out.write("<broker>\n");
+ out.write("\t<management><enabled>false</enabled></management>\n");
+ out.write("\t<security>\n");
+ out.write("\t\t<principal-databases>\n");
+ out.write("\t\t\t<principal-database>\n");
+ out.write("\t\t\t\t<name>passwordfile</name>\n");
+ out.write("\t\t\t\t<class>org.apache.qpid.server.security.auth.database.PlainPasswordFilePrincipalDatabase</class>\n");
+ out.write("\t\t\t\t<attributes>\n");
+ out.write("\t\t\t\t\t<attribute>\n");
+ out.write("\t\t\t\t\t\t<name>passwordFile</name>\n");
+ out.write("\t\t\t\t\t\t<value>/dev/null</value>\n");
+ out.write("\t\t\t\t\t</attribute>\n");
+ out.write("\t\t\t\t</attributes>\n");
+ out.write("\t\t\t</principal-database>\n");
+ out.write("\t\t</principal-databases>\n");
+ out.write("\t\t<jmx>\n");
+ out.write("\t\t\t<access>/dev/null</access>\n");
+ out.write("\t\t\t<principal-database>passwordfile</principal-database>\n");
+ out.write("\t\t</jmx>\n");
+ out.write("\t\t<firewall>\n");
+ out.write("\t\t\t<xml fileName=\"" + fileB.getAbsolutePath() + "\"/>");
+ out.write("\t\t</firewall>\n");
+ out.write("\t</security>\n");
+ out.write("\t<virtualhosts>\n");
+ out.write("\t\t<virtualhost>\n");
+ out.write("\t\t\t<name>test</name>\n");
+ out.write("\t\t</virtualhost>\n");
+ out.write("\t</virtualhosts>\n");
+ out.write("</broker>\n");
+ out.close();
+
+ out = new FileWriter(fileB);
+ out.write("<firewall>\n");
+ out.write("\t<rule access=\"deny\" network=\"127.0.0.1\"/>");
+ out.write("</firewall>\n");
+ out.close();
+
+ // Load config
+ ApplicationRegistry reg = new ConfigurationFileApplicationRegistry(mainFile);
+ ApplicationRegistry.initialise(reg, 1);
+
+ // Test config
+ TestIoSession iosession = new TestIoSession();
+ iosession.setAddress("127.0.0.1");
+ VirtualHostRegistry virtualHostRegistry = reg.getVirtualHostRegistry();
+ VirtualHost virtualHost = virtualHostRegistry.getVirtualHost("test");
+ AMQCodecFactory codecFactory = new AMQCodecFactory(true);
+ AMQProtocolSession session = new AMQMinaProtocolSession(iosession, virtualHostRegistry, codecFactory);
+ assertFalse(reg.getAccessManager().authoriseConnect(session, virtualHost));
+ }
+
+ public void testCombinedConfigurationFirewallReload() throws Exception
+ {
+ // Write out config
+ File mainFile = File.createTempFile(getClass().getName(), null);
+ File fileA = File.createTempFile(getClass().getName(), null);
+ File fileB = File.createTempFile(getClass().getName(), null);
+
+ mainFile.deleteOnExit();
+ fileA.deleteOnExit();
+ fileB.deleteOnExit();
+
+ FileWriter out = new FileWriter(mainFile);
+ out.write("<configuration><system/>");
+ out.write("<xml fileName=\"" + fileA.getAbsolutePath() + "\"/>");
+ out.write("</configuration>");
+ out.close();
+
+ out = new FileWriter(fileA);
+ out.write("<broker>\n");
+ out.write("\t<management><enabled>false</enabled></management>\n");
+ out.write("\t<security>\n");
+ out.write("\t\t<principal-databases>\n");
+ out.write("\t\t\t<principal-database>\n");
+ out.write("\t\t\t\t<name>passwordfile</name>\n");
+ out.write("\t\t\t\t<class>org.apache.qpid.server.security.auth.database.PlainPasswordFilePrincipalDatabase</class>\n");
+ out.write("\t\t\t\t<attributes>\n");
+ out.write("\t\t\t\t\t<attribute>\n");
+ out.write("\t\t\t\t\t\t<name>passwordFile</name>\n");
+ out.write("\t\t\t\t\t\t<value>/dev/null</value>\n");
+ out.write("\t\t\t\t\t</attribute>\n");
+ out.write("\t\t\t\t</attributes>\n");
+ out.write("\t\t\t</principal-database>\n");
+ out.write("\t\t</principal-databases>\n");
+ out.write("\t\t<jmx>\n");
+ out.write("\t\t\t<access>/dev/null</access>\n");
+ out.write("\t\t\t<principal-database>passwordfile</principal-database>\n");
+ out.write("\t\t</jmx>\n");
+ out.write("\t\t<firewall>\n");
+ out.write("\t\t\t<xml fileName=\"" + fileB.getAbsolutePath() + "\"/>");
+ out.write("\t\t</firewall>\n");
+ out.write("\t</security>\n");
+ out.write("\t<virtualhosts>\n");
+ out.write("\t\t<virtualhost>\n");
+ out.write("\t\t\t<name>test</name>\n");
+ out.write("\t\t</virtualhost>\n");
+ out.write("\t</virtualhosts>\n");
+ out.write("</broker>\n");
+ out.close();
+
+ out = new FileWriter(fileB);
+ out.write("<firewall>\n");
+ out.write("\t<rule access=\"deny\" network=\"127.0.0.1\"/>");
+ out.write("</firewall>\n");
+ out.close();
+
+ // Load config
+ ApplicationRegistry reg = new ConfigurationFileApplicationRegistry(mainFile);
+ ApplicationRegistry.initialise(reg, 1);
+
+ // Test config
+ TestIoSession iosession = new TestIoSession();
+ iosession.setAddress("127.0.0.1");
+ VirtualHostRegistry virtualHostRegistry = reg.getVirtualHostRegistry();
+ VirtualHost virtualHost = virtualHostRegistry.getVirtualHost("test");
+ AMQCodecFactory codecFactory = new AMQCodecFactory(true);
+ AMQProtocolSession session = new AMQMinaProtocolSession(iosession, virtualHostRegistry, codecFactory);
+ assertFalse(reg.getAccessManager().authoriseConnect(session, virtualHost));
+
+ RandomAccessFile fileBRandom = new RandomAccessFile(fileB, "rw");
+ fileBRandom.setLength(0);
+ fileBRandom.seek(0);
+ fileBRandom.close();
+
+ out = new FileWriter(fileB);
+ out.write("<firewall>\n");
+ out.write("\t<rule access=\"allow\" network=\"127.0.0.1\"/>");
+ out.write("</firewall>\n");
+ out.close();
+
+ reg.getConfiguration().reparseConfigFile();
+
+ assertTrue(reg.getAccessManager().authoriseConnect(session, virtualHost));
+
+ fileBRandom = new RandomAccessFile(fileB, "rw");
+ fileBRandom.setLength(0);
+ fileBRandom.seek(0);
+ fileBRandom.close();
+
+ out = new FileWriter(fileB);
+ out.write("<firewall>\n");
+ out.write("\t<rule access=\"deny\" network=\"127.0.0.1\"/>");
+ out.write("</firewall>\n");
+ out.close();
+
+ reg.getConfiguration().reparseConfigFile();
+
+ assertFalse(reg.getAccessManager().authoriseConnect(session, virtualHost));
+ }
+
+}
diff --git a/qpid/java/broker/src/test/java/org/apache/qpid/server/configuration/VirtualHostConfigurationTest.java b/qpid/java/broker/src/test/java/org/apache/qpid/server/configuration/VirtualHostConfigurationTest.java
index 8f743d8856..7239ec9303 100644
--- a/qpid/java/broker/src/test/java/org/apache/qpid/server/configuration/VirtualHostConfigurationTest.java
+++ b/qpid/java/broker/src/test/java/org/apache/qpid/server/configuration/VirtualHostConfigurationTest.java
@@ -20,13 +20,10 @@
package org.apache.qpid.server.configuration;
-import java.io.File;
-import java.util.ArrayList;
-import java.util.Collection;
+import junit.framework.TestCase;
import org.apache.commons.configuration.ConfigurationException;
import org.apache.commons.configuration.XMLConfiguration;
-import org.apache.commons.configuration.HierarchicalConfiguration.Node;
import org.apache.qpid.AMQException;
import org.apache.qpid.framing.AMQShortString;
import org.apache.qpid.server.queue.AMQPriorityQueue;
@@ -34,29 +31,22 @@ import org.apache.qpid.server.queue.AMQQueue;
import org.apache.qpid.server.registry.ApplicationRegistry;
import org.apache.qpid.server.virtualhost.VirtualHost;
-import junit.framework.TestCase;
-
public class VirtualHostConfigurationTest extends TestCase
{
- private File configFile;
private VirtualHostConfiguration vhostConfig;
private XMLConfiguration configXml;
@Override
protected void setUp() throws Exception
- {
- // Create temporary configuration file
- configFile = File.createTempFile(this.getName()+"config", ".xml");
- configFile.deleteOnExit();
-
+ {
// Fill config file with stuff
configXml = new XMLConfiguration();
configXml.setRootElementName("virtualhosts");
configXml.addProperty("virtualhost(-1).name", "test");
}
- public void testQueuePriority() throws ConfigurationException, AMQException
+ public void testQueuePriority() throws Exception
{
// Set up queue with 5 priorities
configXml.addProperty("virtualhost.test.queues(-1).queue(-1).name(-1)",
@@ -81,14 +71,8 @@ public class VirtualHostConfigurationTest extends TestCase
"amq.direct");
configXml.addProperty("virtualhost.test.queues.queue.ntest.priority",
"false");
- configXml.save(configFile);
-
- // Setup virtual host configuration
- vhostConfig = new VirtualHostConfiguration(configFile.getAbsolutePath());
- // Do bindings and get resulting vhost
- vhostConfig.performBindings();
- VirtualHost vhost = ApplicationRegistry.getInstance().getVirtualHostRegistry().getVirtualHost("test");
+ VirtualHost vhost = new VirtualHost(new VirtualHostConfiguration("test", configXml.subset("virtualhost.test")));
// Check that atest was a priority queue with 5 priorities
AMQQueue atest = vhost.getQueueRegistry().getQueue(new AMQShortString("atest"));
@@ -105,4 +89,64 @@ public class VirtualHostConfigurationTest extends TestCase
assertFalse(ntest instanceof AMQPriorityQueue);
}
+ public void testQueueAlerts() throws Exception
+ {
+ // Set up queue with 5 priorities
+ configXml.addProperty("virtualhost.test.queues.exchange", "amq.topic");
+ configXml.addProperty("virtualhost.test.queues.maximumQueueDepth", "1");
+ configXml.addProperty("virtualhost.test.queues.maximumMessageSize", "2");
+ configXml.addProperty("virtualhost.test.queues.maximumMessageAge", "3");
+
+ configXml.addProperty("virtualhost.test.queues(-1).queue(1).name(1)", "atest");
+ configXml.addProperty("virtualhost.test.queues.queue.atest(-1).exchange", "amq.direct");
+ configXml.addProperty("virtualhost.test.queues.queue.atest(-1).maximumQueueDepth", "4");
+ configXml.addProperty("virtualhost.test.queues.queue.atest(-1).maximumMessageSize", "5");
+ configXml.addProperty("virtualhost.test.queues.queue.atest(-1).maximumMessageAge", "6");
+
+ configXml.addProperty("virtualhost.test.queues(-1).queue(-1).name(-1)", "btest");
+
+ VirtualHost vhost = new VirtualHost(new VirtualHostConfiguration("test", configXml.subset("virtualhost.test")));
+
+ // Check specifically configured values
+ AMQQueue aTest = vhost.getQueueRegistry().getQueue(new AMQShortString("atest"));
+ assertEquals(4, aTest.getMaximumQueueDepth());
+ assertEquals(5, aTest.getMaximumMessageSize());
+ assertEquals(6, aTest.getMaximumMessageAge());
+
+ // Check default values
+ AMQQueue bTest = vhost.getQueueRegistry().getQueue(new AMQShortString("btest"));
+ assertEquals(1, bTest.getMaximumQueueDepth());
+ assertEquals(2, bTest.getMaximumMessageSize());
+ assertEquals(3, bTest.getMaximumMessageAge());
+
+ }
+
+ public void testQueueMemoryValues() throws Exception
+ {
+ // Set up queue with 5 priorities
+ configXml.addProperty("virtualhost.test.queues.exchange", "amq.topic");
+ configXml.addProperty("virtualhost.test.queues.maximumMemoryUsage", "11");
+ configXml.addProperty("virtualhost.test.queues.minimumMemoryUsage", "22");
+
+ configXml.addProperty("virtualhost.test.queues(-1).queue(1).name(1)", "atest");
+ configXml.addProperty("virtualhost.test.queues.queue.atest(-1).exchange", "amq.direct");
+ configXml.addProperty("virtualhost.test.queues.queue.atest(-1).maximumMemoryUsage", "44");
+ configXml.addProperty("virtualhost.test.queues.queue.atest(-1).minimumMemoryUsage", "55");
+
+ configXml.addProperty("virtualhost.test.queues(-1).queue(-1).name(-1)", "btest");
+
+ VirtualHost vhost = new VirtualHost(new VirtualHostConfiguration("test", configXml.subset("virtualhost.test")));
+
+ // Check specifically configured values
+ AMQQueue aTest = vhost.getQueueRegistry().getQueue(new AMQShortString("atest"));
+ assertEquals(44, aTest.getMemoryUsageMaximum());
+ assertEquals(55, aTest.getMemoryUsageMinimum());
+
+ // Check default values
+ AMQQueue bTest = vhost.getQueueRegistry().getQueue(new AMQShortString("btest"));
+ assertEquals(11, bTest.getMemoryUsageMaximum());
+ assertEquals(22, bTest.getMemoryUsageMinimum());
+ }
+
+
}
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 40b08a2e39..ee1796ba2f 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
@@ -36,7 +36,6 @@ import org.apache.qpid.server.queue.AMQMessage;
import org.apache.qpid.server.queue.AMQQueue;
import org.apache.qpid.server.queue.FailedDequeueException;
import org.apache.qpid.server.queue.IncomingMessage;
-import org.apache.qpid.server.queue.MessageCleanupException;
import org.apache.qpid.server.queue.MockProtocolSession;
import org.apache.qpid.server.queue.QueueEntry;
import org.apache.qpid.server.queue.SimpleAMQQueue;
@@ -214,6 +213,11 @@ public class AbstractHeadersExchangeTestBase extends TestCase
return null; //To change body of implemented methods use File | Settings | File Templates.
}
+ public Long getMessageId()
+ {
+ return null; //To change body of implemented methods use File | Settings | File Templates.
+ }
+
public long getSize()
{
return 0; //To change body of implemented methods use File | Settings | File Templates.
@@ -229,11 +233,21 @@ public class AbstractHeadersExchangeTestBase extends TestCase
return false; //To change body of implemented methods use File | Settings | File Templates.
}
+ public void setExpiration(long expiration)
+ {
+ //To change body of implemented methods use File | Settings | File Templates.
+ }
+
public boolean isAcquired()
{
return false; //To change body of implemented methods use File | Settings | File Templates.
}
+ public boolean isAvailable()
+ {
+ return false; //To change body of implemented methods use File | Settings | File Templates.
+ }
+
public boolean acquire()
{
return false; //To change body of implemented methods use File | Settings | File Templates.
@@ -314,32 +328,38 @@ public class AbstractHeadersExchangeTestBase extends TestCase
//To change body of implemented methods use File | Settings | File Templates.
}
- public void dispose(final StoreContext storeContext) throws MessageCleanupException
+
+ public void dequeueAndDelete(StoreContext storeContext) throws FailedDequeueException
{
//To change body of implemented methods use File | Settings | File Templates.
}
- public void restoreCredit()
+ public boolean isQueueDeleted()
{
- //To change body of implemented methods use File | Settings | File Templates.
+ return false; //To change body of implemented methods use File | Settings | File Templates.
}
- public void discard(StoreContext storeContext) throws FailedDequeueException, MessageCleanupException
+ public void addStateChangeListener(StateChangeListener listener)
{
//To change body of implemented methods use File | Settings | File Templates.
}
- public boolean isQueueDeleted()
+ public boolean removeStateChangeListener(StateChangeListener listener)
{
return false; //To change body of implemented methods use File | Settings | File Templates.
}
- public void addStateChangeListener(StateChangeListener listener)
+ public void unload()
{
//To change body of implemented methods use File | Settings | File Templates.
}
- public boolean removeStateChangeListener(StateChangeListener listener)
+ public AMQMessage load()
+ {
+ return null;
+ }
+
+ public boolean isFlowed()
{
return false; //To change body of implemented methods use File | Settings | File Templates.
}
diff --git a/qpid/java/broker/src/test/java/org/apache/qpid/server/exchange/DestWildExchangeTest.java b/qpid/java/broker/src/test/java/org/apache/qpid/server/exchange/DestWildExchangeTest.java
index f8544a33bd..890b641540 100644
--- a/qpid/java/broker/src/test/java/org/apache/qpid/server/exchange/DestWildExchangeTest.java
+++ b/qpid/java/broker/src/test/java/org/apache/qpid/server/exchange/DestWildExchangeTest.java
@@ -100,7 +100,7 @@ public class DestWildExchangeTest extends TestCase
Assert.assertEquals(1, queue.getMessageCount());
- Assert.assertEquals("Wrong message recevied", (Object) message.getMessageId(), queue.getMessagesOnTheQueue().get(0).getMessage().getMessageId());
+ Assert.assertEquals("Wrong message recevied", (Object) message.getMessageId(), queue.getMessagesOnTheQueue().get(0).getMessageId());
queue.deleteMessageFromTop(_context);
Assert.assertEquals(0, queue.getMessageCount());
@@ -140,7 +140,7 @@ public class DestWildExchangeTest extends TestCase
Assert.assertEquals(1, queue.getMessageCount());
- Assert.assertEquals("Wrong message recevied", (Object) message.getMessageId(), queue.getMessagesOnTheQueue().get(0).getMessage().getMessageId());
+ Assert.assertEquals("Wrong message recevied", (Object) message.getMessageId(), queue.getMessagesOnTheQueue().get(0).getMessageId());
queue.deleteMessageFromTop(_context);
Assert.assertEquals(0, queue.getMessageCount());
@@ -159,7 +159,7 @@ public class DestWildExchangeTest extends TestCase
Assert.assertEquals(1, queue.getMessageCount());
- Assert.assertEquals("Wrong message recevied", (Object) message.getMessageId(), queue.getMessagesOnTheQueue().get(0).getMessage().getMessageId());
+ Assert.assertEquals("Wrong message recevied", (Object) message.getMessageId(), queue.getMessagesOnTheQueue().get(0).getMessageId());
queue.deleteMessageFromTop(_context);
Assert.assertEquals(0, queue.getMessageCount());
@@ -198,7 +198,7 @@ public class DestWildExchangeTest extends TestCase
Assert.assertEquals(1, queue.getMessageCount());
- Assert.assertEquals("Wrong message recevied", (Object) message.getMessageId(), queue.getMessagesOnTheQueue().get(0).getMessage().getMessageId());
+ Assert.assertEquals("Wrong message recevied", (Object) message.getMessageId(), queue.getMessagesOnTheQueue().get(0).getMessageId());
queue.deleteMessageFromTop(_context);
Assert.assertEquals(0, queue.getMessageCount());
@@ -217,7 +217,7 @@ public class DestWildExchangeTest extends TestCase
Assert.assertEquals(1, queue.getMessageCount());
- Assert.assertEquals("Wrong message recevied", (Object) message.getMessageId(), queue.getMessagesOnTheQueue().get(0).getMessage().getMessageId());
+ Assert.assertEquals("Wrong message recevied", (Object) message.getMessageId(), queue.getMessagesOnTheQueue().get(0).getMessageId());
queue.deleteMessageFromTop(_context);
Assert.assertEquals(0, queue.getMessageCount());
@@ -236,7 +236,7 @@ public class DestWildExchangeTest extends TestCase
Assert.assertEquals(1, queue.getMessageCount());
- Assert.assertEquals("Wrong message recevied", (Object) message.getMessageId(), queue.getMessagesOnTheQueue().get(0).getMessage().getMessageId());
+ Assert.assertEquals("Wrong message recevied", (Object) message.getMessageId(), queue.getMessagesOnTheQueue().get(0).getMessageId());
queue.deleteMessageFromTop(_context);
Assert.assertEquals(0, queue.getMessageCount());
@@ -254,7 +254,7 @@ public class DestWildExchangeTest extends TestCase
Assert.assertEquals(1, queue.getMessageCount());
- Assert.assertEquals("Wrong message recevied", (Object) message.getMessageId(), queue.getMessagesOnTheQueue().get(0).getMessage().getMessageId());
+ Assert.assertEquals("Wrong message recevied", (Object) message.getMessageId(), queue.getMessagesOnTheQueue().get(0).getMessageId());
queue.deleteMessageFromTop(_context);
Assert.assertEquals(0, queue.getMessageCount());
@@ -294,7 +294,7 @@ public class DestWildExchangeTest extends TestCase
Assert.assertEquals(1, queue.getMessageCount());
- Assert.assertEquals("Wrong message recevied", (Object) message.getMessageId(), queue.getMessagesOnTheQueue().get(0).getMessage().getMessageId());
+ Assert.assertEquals("Wrong message recevied", (Object) message.getMessageId(), queue.getMessagesOnTheQueue().get(0).getMessageId());
queue.deleteMessageFromTop(_context);
Assert.assertEquals(0, queue.getMessageCount());
@@ -312,7 +312,7 @@ public class DestWildExchangeTest extends TestCase
Assert.assertEquals(1, queue.getMessageCount());
- Assert.assertEquals("Wrong message recevied", (Object) message.getMessageId(), queue.getMessagesOnTheQueue().get(0).getMessage().getMessageId());
+ Assert.assertEquals("Wrong message recevied", (Object) message.getMessageId(), queue.getMessagesOnTheQueue().get(0).getMessageId());
queue.deleteMessageFromTop(_context);
Assert.assertEquals(0, queue.getMessageCount());
@@ -352,7 +352,7 @@ public class DestWildExchangeTest extends TestCase
Assert.assertEquals(1, queue.getMessageCount());
- Assert.assertEquals("Wrong message recevied", (Object) message.getMessageId(), queue.getMessagesOnTheQueue().get(0).getMessage().getMessageId());
+ Assert.assertEquals("Wrong message recevied", (Object) message.getMessageId(), queue.getMessagesOnTheQueue().get(0).getMessageId());
queue.deleteMessageFromTop(_context);
Assert.assertEquals(0, queue.getMessageCount());
@@ -384,7 +384,7 @@ public class DestWildExchangeTest extends TestCase
Assert.assertEquals(1, queue.getMessageCount());
- Assert.assertEquals("Wrong message recevied", (Object) message.getMessageId(), queue.getMessagesOnTheQueue().get(0).getMessage().getMessageId());
+ Assert.assertEquals("Wrong message recevied", (Object) message.getMessageId(), queue.getMessagesOnTheQueue().get(0).getMessageId());
queue.deleteMessageFromTop(_context);
Assert.assertEquals(0, queue.getMessageCount());
@@ -425,7 +425,7 @@ public class DestWildExchangeTest extends TestCase
Assert.assertEquals(1, queue.getMessageCount());
- Assert.assertEquals("Wrong message recevied", (Object) message.getMessageId(), queue.getMessagesOnTheQueue().get(0).getMessage().getMessageId());
+ Assert.assertEquals("Wrong message recevied", (Object) message.getMessageId(), queue.getMessagesOnTheQueue().get(0).getMessageId());
queue.deleteMessageFromTop(_context);
Assert.assertEquals(0, queue.getMessageCount());
@@ -464,7 +464,7 @@ public class DestWildExchangeTest extends TestCase
Assert.assertEquals(1, queue.getMessageCount());
- Assert.assertEquals("Wrong message recevied", (Object) message.getMessageId(), queue.getMessagesOnTheQueue().get(0).getMessage().getMessageId());
+ Assert.assertEquals("Wrong message recevied", (Object) message.getMessageId(), queue.getMessagesOnTheQueue().get(0).getMessageId());
queue.deleteMessageFromTop(_context);
Assert.assertEquals(0, queue.getMessageCount());
diff --git a/qpid/java/broker/src/test/java/org/apache/qpid/server/filter/PropertyExpressionTest.java b/qpid/java/broker/src/test/java/org/apache/qpid/server/filter/PropertyExpressionTest.java
index 9344efd4a8..e7b3f40393 100644
--- a/qpid/java/broker/src/test/java/org/apache/qpid/server/filter/PropertyExpressionTest.java
+++ b/qpid/java/broker/src/test/java/org/apache/qpid/server/filter/PropertyExpressionTest.java
@@ -23,10 +23,18 @@ package org.apache.qpid.server.filter;
import junit.framework.TestCase;
import org.apache.qpid.AMQException;
import org.apache.qpid.server.queue.MockQueueEntry;
+import org.apache.qpid.server.registry.ApplicationRegistry;
public class PropertyExpressionTest extends TestCase
{
+ public void tearDown() throws Exception
+ {
+ //Ensure we close the registry that the MockQueueEntry will create
+ ApplicationRegistry.remove(1);
+ }
+
+
public void testJMSRedelivered()
{
PropertyExpression<AMQException> pe = new PropertyExpression<AMQException>("JMSRedelivered");
diff --git a/qpid/java/broker/src/test/java/org/apache/qpid/server/logging/management/LoggingManagementMBeanTest.java b/qpid/java/broker/src/test/java/org/apache/qpid/server/logging/management/LoggingManagementMBeanTest.java
new file mode 100644
index 0000000000..40153be331
--- /dev/null
+++ b/qpid/java/broker/src/test/java/org/apache/qpid/server/logging/management/LoggingManagementMBeanTest.java
@@ -0,0 +1,413 @@
+/*
+ * 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.logging.management;
+
+import java.io.BufferedWriter;
+import java.io.File;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.management.JMException;
+import javax.management.openmbean.CompositeData;
+import javax.management.openmbean.TabularDataSupport;
+
+import org.apache.log4j.Level;
+import org.apache.log4j.Logger;
+
+import junit.framework.TestCase;
+
+public class LoggingManagementMBeanTest extends TestCase
+{
+ private static final String TEST_LOGGER = "LoggingManagementMBeanTestLogger";
+ private static final String TEST_LOGGER_CHILD1 = "LoggingManagementMBeanTestLogger.child1";
+ private static final String TEST_LOGGER_CHILD2 = "LoggingManagementMBeanTestLogger.child2";
+
+ private static final String CATEGORY_PRIORITY = "LogManMBeanTest.category.priority";
+ private static final String CATEGORY_LEVEL = "LogManMBeanTest.category.level";
+ private static final String LOGGER_LEVEL = "LogManMBeanTest.logger.level";
+
+ private static final String NAME_INDEX = LoggingManagement.COMPOSITE_ITEM_NAMES[0];
+ private static final String LEVEL_INDEX = LoggingManagement.COMPOSITE_ITEM_NAMES[1];
+
+ private static final String NEWLINE = System.getProperty("line.separator");
+
+ private File _testConfigFile;
+
+ protected void setUp() throws Exception
+ {
+ _testConfigFile = createTempTestLog4JConfig();
+ }
+
+ private File createTempTestLog4JConfig()
+ {
+ File tmpFile = null;
+ try
+ {
+ tmpFile = File.createTempFile("LogManMBeanTestLog4jConfig", ".tmp");
+ tmpFile.deleteOnExit();
+
+ FileWriter fstream = new FileWriter(tmpFile);
+ BufferedWriter writer = new BufferedWriter(fstream);
+
+ writer.write("<?xml version=\"1.0\" encoding=\"UTF-8\"?>"+NEWLINE);
+ writer.write("<!DOCTYPE log4j:configuration SYSTEM \"log4j.dtd\">"+NEWLINE);
+
+ writer.write("<log4j:configuration xmlns:log4j=\"http://jakarta.apache.org/log4j/\" debug=\"null\" " +
+ "threshold=\"null\">"+NEWLINE);
+
+ writer.write(" <appender class=\"org.apache.log4j.ConsoleAppender\" name=\"STDOUT\">"+NEWLINE);
+ writer.write(" <layout class=\"org.apache.log4j.PatternLayout\">"+NEWLINE);
+ writer.write(" <param name=\"ConversionPattern\" value=\"%d %-5p [%t] %C{2} (%F:%L) - %m%n\"/>"+NEWLINE);
+ writer.write(" </layout>"+NEWLINE);
+ writer.write(" </appender>"+NEWLINE);
+
+ //Example of a 'category' with a 'priority'
+ writer.write(" <category additivity=\"true\" name=\"" + CATEGORY_PRIORITY +"\">"+NEWLINE);
+ writer.write(" <priority value=\"info\"/>"+NEWLINE);
+ writer.write(" <appender-ref ref=\"STDOUT\"/>"+NEWLINE);
+ writer.write(" </category>"+NEWLINE);
+
+ //Example of a 'category' with a 'level'
+ writer.write(" <category additivity=\"true\" name=\"" + CATEGORY_LEVEL +"\">"+NEWLINE);
+ writer.write(" <level value=\"warn\"/>"+NEWLINE);
+ writer.write(" <appender-ref ref=\"STDOUT\"/>"+NEWLINE);
+ writer.write(" </category>"+NEWLINE);
+
+ //Example of a 'logger' with a 'level'
+ writer.write(" <logger additivity=\"true\" name=\"" + LOGGER_LEVEL + "\">"+NEWLINE);
+ writer.write(" <level value=\"error\"/>"+NEWLINE);
+ writer.write(" <appender-ref ref=\"STDOUT\"/>"+NEWLINE);
+ writer.write(" </logger>"+NEWLINE);
+
+ //'root' logger
+ writer.write(" <root>"+NEWLINE);
+ writer.write(" <priority value=\"info\"/>"+NEWLINE);
+ writer.write(" <appender-ref ref=\"STDOUT\"/>"+NEWLINE);
+ writer.write(" </root>"+NEWLINE);
+
+ writer.write("</log4j:configuration>"+NEWLINE);
+
+ writer.flush();
+ writer.close();
+ }
+ catch (IOException e)
+ {
+ fail("Unable to create temporary test log4j configuration");
+ }
+
+ return tmpFile;
+ }
+
+
+
+ //******* Test Methods ******* //
+
+ public void testSetRuntimeLoggerLevel()
+ {
+ LoggingManagementMBean lm = null;
+ try
+ {
+ lm = new LoggingManagementMBean(_testConfigFile.getAbsolutePath(), 0);
+ }
+ catch (JMException e)
+ {
+ fail("Could not create test LoggingManagementMBean");
+ }
+
+ //create a parent test logger, set its level explicitly
+ Logger log = Logger.getLogger(TEST_LOGGER);
+ log.setLevel(Level.toLevel("info"));
+
+ //create child1 test logger, check its *effective* level is the same as the parent, "info"
+ Logger log1 = Logger.getLogger(TEST_LOGGER_CHILD1);
+ assertTrue("Test logger's level was not the expected value",
+ log1.getEffectiveLevel().toString().equalsIgnoreCase("info"));
+
+ //now change its level to "warn"
+ assertTrue("Failed to set logger level", lm.setRuntimeLoggerLevel(TEST_LOGGER_CHILD1, "warn"));
+
+ //check the change, see its actual level is "warn
+ assertTrue("Test logger's level was not the expected value",
+ log1.getLevel().toString().equalsIgnoreCase("warn"));
+
+ //try an invalid level
+ assertFalse("Trying to set an invalid level succeded", lm.setRuntimeLoggerLevel(TEST_LOGGER_CHILD1, "made.up.level"));
+ }
+
+ public void testSetRuntimeRootLoggerLevel()
+ {
+ LoggingManagementMBean lm = null;
+ try
+ {
+ lm = new LoggingManagementMBean(_testConfigFile.getAbsolutePath(), 0);
+ }
+ catch (JMException e)
+ {
+ fail("Could not create test LoggingManagementMBean");
+ }
+
+ Logger log = Logger.getRootLogger();
+
+ //get current root logger level
+ Level origLevel = log.getLevel();
+
+ //change level twice to ensure a new level is actually selected
+
+ //set root loggers level to info
+ assertTrue("Failed to set root logger level", lm.setRuntimeRootLoggerLevel("debug"));
+ //check it is now actually info
+ Level currentLevel = log.getLevel();
+ assertTrue("Logger level was not expected value", currentLevel.equals(Level.toLevel("debug")));
+
+ //try an invalid level
+ assertFalse("Trying to set an invalid level succeded", lm.setRuntimeRootLoggerLevel("made.up.level"));
+
+ //set root loggers level to warn
+ assertTrue("Failed to set logger level", lm.setRuntimeRootLoggerLevel("info"));
+ //check it is now actually warn
+ currentLevel = log.getLevel();
+ assertTrue("Logger level was not expected value", currentLevel.equals(Level.toLevel("info")));
+
+ //restore original level
+ log.setLevel(origLevel);
+ }
+
+ public void testGetRuntimeRootLoggerLevel()
+ {
+ LoggingManagementMBean lm = null;
+ try
+ {
+ lm = new LoggingManagementMBean(_testConfigFile.getAbsolutePath(), 0);
+ }
+ catch (JMException e)
+ {
+ fail("Could not create test LoggingManagementMBean");
+ }
+
+ Logger log = Logger.getRootLogger();
+
+ //get current root logger level
+ Level origLevel = log.getLevel();
+
+ //change level twice to ensure a new level is actually selected
+
+ //set root loggers level to debug
+ log.setLevel(Level.toLevel("debug"));
+ //check it is now actually debug
+ assertTrue("Logger level was not expected value", lm.getRuntimeRootLoggerLevel().equalsIgnoreCase("debug"));
+
+
+ //set root loggers level to warn
+ log.setLevel(Level.toLevel("info"));
+ //check it is now actually warn
+ assertTrue("Logger level was not expected value", lm.getRuntimeRootLoggerLevel().equalsIgnoreCase("info"));
+
+ //restore original level
+ log.setLevel(origLevel);
+ }
+
+ public void testViewEffectiveRuntimeLoggerLevels()
+ {
+ LoggingManagementMBean lm = null;
+ try
+ {
+ lm = new LoggingManagementMBean(_testConfigFile.getAbsolutePath(), 0);
+ }
+ catch (JMException e)
+ {
+ fail("Could not create test LoggingManagementMBean");
+ }
+
+ //(re)create a parent test logger, set its level explicitly
+ Logger log = Logger.getLogger(TEST_LOGGER);
+ log.setLevel(Level.toLevel("info"));
+
+ //retrieve the current effective runtime logger level values
+ TabularDataSupport levels = (TabularDataSupport) lm.viewEffectiveRuntimeLoggerLevels();
+ Collection<Object> records = levels.values();
+ Map<String,String> list = new HashMap<String,String>();
+ for (Object o : records)
+ {
+ CompositeData data = (CompositeData) o;
+ list.put(data.get(NAME_INDEX).toString(), data.get(LEVEL_INDEX).toString());
+ }
+
+ //check child2 does not exist already
+ assertFalse("Did not expect this logger to exist already", list.containsKey(TEST_LOGGER_CHILD2));
+
+ //create child2 test logger
+ Logger log2 = Logger.getLogger(TEST_LOGGER_CHILD2);
+
+ //retrieve the current effective runtime logger level values
+ levels = (TabularDataSupport) lm.viewEffectiveRuntimeLoggerLevels();
+ records = levels.values();
+ list = new HashMap<String,String>();
+ for (Object o : records)
+ {
+ CompositeData data = (CompositeData) o;
+ list.put(data.get(NAME_INDEX).toString(), data.get(LEVEL_INDEX).toString());
+ }
+
+ //verify the parent and child2 loggers are present in returned values
+ assertTrue(TEST_LOGGER + " logger was not in the returned list", list.containsKey(TEST_LOGGER));
+ assertTrue(TEST_LOGGER_CHILD2 + " logger was not in the returned list", list.containsKey(TEST_LOGGER_CHILD2));
+
+ //check child2's effective level is the same as the parent, "info"
+ assertTrue("Test logger's level was not the expected value",
+ list.get(TEST_LOGGER_CHILD2).equalsIgnoreCase("info"));
+
+ //now change its level explicitly to "warn"
+ log2.setLevel(Level.toLevel("warn"));
+
+ //retrieve the current effective runtime logger level values
+ levels = (TabularDataSupport) lm.viewEffectiveRuntimeLoggerLevels();
+ records = levels.values();
+ list = new HashMap<String,String>();
+ for (Object o : records)
+ {
+ CompositeData data = (CompositeData) o;
+ list.put(data.get(NAME_INDEX).toString(), data.get(LEVEL_INDEX).toString());
+ }
+
+ //check child2's effective level is now "warn"
+ assertTrue("Test logger's level was not the expected value",
+ list.get(TEST_LOGGER_CHILD2).equalsIgnoreCase("warn"));
+ }
+
+ public void testViewAndSetConfigFileLoggerLevel() throws Exception
+ {
+ LoggingManagementMBean lm =null;
+ try
+ {
+ lm = new LoggingManagementMBean(_testConfigFile.getAbsolutePath(), 0);
+ }
+ catch (JMException e)
+ {
+ fail("Could not create test LoggingManagementMBean");
+ }
+
+ //retrieve the current values
+ TabularDataSupport levels = (TabularDataSupport) lm.viewConfigFileLoggerLevels();
+ Collection<Object> records = levels.values();
+ Map<String,String> list = new HashMap<String,String>();
+ for (Object o : records)
+ {
+ CompositeData data = (CompositeData) o;
+ list.put(data.get(NAME_INDEX).toString(), data.get(LEVEL_INDEX).toString());
+ }
+
+ //check the 3 different types of logger definition are successfully retrieved before update
+ assertTrue("Wrong number of items in returned list", list.size() == 3);
+ assertTrue(CATEGORY_PRIORITY + " logger was not in the returned list", list.containsKey(CATEGORY_PRIORITY));
+ assertTrue(CATEGORY_LEVEL + " logger was not in the returned list", list.containsKey(CATEGORY_LEVEL));
+ assertTrue(LOGGER_LEVEL + " logger was not in the returned list", list.containsKey(LOGGER_LEVEL));
+
+ //check that their level is as expected
+ assertTrue(CATEGORY_PRIORITY + " logger's level was incorrect", list.get(CATEGORY_PRIORITY).equalsIgnoreCase("info"));
+ assertTrue(CATEGORY_LEVEL + " logger's level was incorrect", list.get(CATEGORY_LEVEL).equalsIgnoreCase("warn"));
+ assertTrue(LOGGER_LEVEL + " logger's level was incorrect", list.get(LOGGER_LEVEL).equalsIgnoreCase("error"));
+
+ //increase their levels a notch to test the 3 different types of logger definition are successfully updated
+ //change the category+priority to warn
+ assertTrue("failed to set new level", lm.setConfigFileLoggerLevel(CATEGORY_PRIORITY, "warn"));
+ //change the category+level to error
+ assertTrue("failed to set new level", lm.setConfigFileLoggerLevel(CATEGORY_LEVEL, "error"));
+ //change the logger+level to trace
+ assertTrue("failed to set new level", lm.setConfigFileLoggerLevel(LOGGER_LEVEL, "trace"));
+
+ //try an invalid level
+ assertFalse("Use of an invalid logger level was successfull", lm.setConfigFileLoggerLevel(LOGGER_LEVEL, "made.up.level"));
+
+ //try an invalid logger name
+ assertFalse("Use of an invalid logger name was successfull", lm.setConfigFileLoggerLevel("made.up.logger.name", "info"));
+
+ //retrieve the new values from the file and check them
+ levels = (TabularDataSupport) lm.viewConfigFileLoggerLevels();
+ records = levels.values();
+ list = new HashMap<String,String>();
+ for (Object o : records)
+ {
+ CompositeData data = (CompositeData) o;
+ list.put(data.get(NAME_INDEX).toString(), data.get(LEVEL_INDEX).toString());
+ }
+
+ //check the 3 different types of logger definition are successfully retrieved after update
+ assertTrue("Wrong number of items in returned list", list.size() == 3);
+ assertTrue(CATEGORY_PRIORITY + " logger was not in the returned list", list.containsKey(CATEGORY_PRIORITY));
+ assertTrue(CATEGORY_LEVEL + " logger was not in the returned list", list.containsKey(CATEGORY_LEVEL));
+ assertTrue(LOGGER_LEVEL + " logger was not in the returned list", list.containsKey(LOGGER_LEVEL));
+
+ //check that their level is as expected after the changes
+ assertTrue(CATEGORY_PRIORITY + " logger's level was incorrect", list.get(CATEGORY_PRIORITY).equalsIgnoreCase("warn"));
+ assertTrue(CATEGORY_LEVEL + " logger's level was incorrect", list.get(CATEGORY_LEVEL).equalsIgnoreCase("error"));
+ assertTrue(LOGGER_LEVEL + " logger's level was incorrect", list.get(LOGGER_LEVEL).equalsIgnoreCase("trace"));
+ }
+
+ public void testGetAndSetConfigFileRootLoggerLevel() throws Exception
+ {
+ LoggingManagementMBean lm =null;
+ try
+ {
+ lm = new LoggingManagementMBean(_testConfigFile.getAbsolutePath(), 0);
+ }
+ catch (JMException e)
+ {
+ fail("Could not create test LoggingManagementMBean");
+ }
+
+ //retrieve the current value
+ String level = lm.getConfigFileRootLoggerLevel();
+
+ //check the value was successfully retrieved before update
+ assertTrue("Retrieved RootLogger level was incorrect", level.equalsIgnoreCase("info"));
+
+ //try an invalid level
+ assertFalse("Use of an invalid RootLogger level was successfull", lm.setConfigFileRootLoggerLevel("made.up.level"));
+
+ //change the level to warn
+ assertTrue("Failed to set new RootLogger level", lm.setConfigFileRootLoggerLevel("warn"));
+
+ //retrieve the current value
+ level = lm.getConfigFileRootLoggerLevel();
+
+ //check the value was successfully retrieved after update
+ assertTrue("Retrieved RootLogger level was incorrect", level.equalsIgnoreCase("warn"));
+ }
+
+ public void testGetLog4jLogWatchInterval()
+ {
+ LoggingManagementMBean lm =null;
+ try
+ {
+ lm = new LoggingManagementMBean(_testConfigFile.getAbsolutePath(), 5000);
+ }
+ catch (JMException e)
+ {
+ fail("Could not create test LoggingManagementMBean");
+ }
+
+ assertTrue("Wrong value returned for logWatch period", lm.getLog4jLogWatchInterval() == 5000);
+ }
+
+}
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 ba02e6f6bd..d7844730d1 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
@@ -23,20 +23,21 @@ package org.apache.qpid.server.queue;
import junit.framework.AssertionFailedError;
import org.apache.qpid.AMQException;
import org.apache.qpid.framing.BasicContentHeaderProperties;
-import org.apache.qpid.framing.ContentHeaderBody;
import org.apache.qpid.framing.FieldTable;
+import org.apache.qpid.framing.AMQShortString;
+import org.apache.qpid.server.txn.NonTransactionalContext;
import java.util.ArrayList;
public class AMQPriorityQueueTest extends SimpleAMQQueueTest
{
- private static final long MESSAGE_SIZE = 100L;
+ private static final int PRIORITIES = 3;
@Override
protected void setUp() throws Exception
- {
+ {
_arguments = new FieldTable();
- _arguments.put(AMQQueueFactory.X_QPID_PRIORITIES, 3);
+ _arguments.put(AMQQueueFactory.X_QPID_PRIORITIES, PRIORITIES);
super.setUp();
}
@@ -64,20 +65,20 @@ public class AMQPriorityQueueTest extends SimpleAMQQueueTest
_queue.registerSubscription(_subscription, false);
Thread.sleep(150);
- ArrayList<QueueEntry> msgs = _subscription.getMessages();
+ ArrayList<QueueEntry> msgs = _subscription.getQueueEntries();
try
{
- assertEquals(new Long(1 + messagIDOffset), msgs.get(0).getMessage().getMessageId());
- assertEquals(new Long(6 + messagIDOffset), msgs.get(1).getMessage().getMessageId());
- assertEquals(new Long(8 + messagIDOffset), msgs.get(2).getMessage().getMessageId());
+ assertEquals(new Long(1 + messagIDOffset), msgs.get(0).getMessageId());
+ assertEquals(new Long(6 + messagIDOffset), msgs.get(1).getMessageId());
+ assertEquals(new Long(8 + messagIDOffset), msgs.get(2).getMessageId());
- assertEquals(new Long(2 + messagIDOffset), msgs.get(3).getMessage().getMessageId());
- assertEquals(new Long(5 + messagIDOffset), msgs.get(4).getMessage().getMessageId());
- assertEquals(new Long(7 + messagIDOffset), msgs.get(5).getMessage().getMessageId());
+ assertEquals(new Long(2 + messagIDOffset), msgs.get(3).getMessageId());
+ assertEquals(new Long(5 + messagIDOffset), msgs.get(4).getMessageId());
+ assertEquals(new Long(7 + messagIDOffset), msgs.get(5).getMessageId());
- assertEquals(new Long(3 + messagIDOffset), msgs.get(6).getMessage().getMessageId());
- assertEquals(new Long(4 + messagIDOffset), msgs.get(7).getMessage().getMessageId());
- assertEquals(new Long(9 + messagIDOffset), msgs.get(8).getMessage().getMessageId());
+ assertEquals(new Long(3 + messagIDOffset), msgs.get(6).getMessageId());
+ assertEquals(new Long(4 + messagIDOffset), msgs.get(7).getMessageId());
+ assertEquals(new Long(9 + messagIDOffset), msgs.get(8).getMessageId());
}
catch (AssertionFailedError afe)
{
@@ -85,7 +86,6 @@ public class AMQPriorityQueueTest extends SimpleAMQQueueTest
int index = 1;
for (QueueEntry qe : msgs)
{
- System.err.println(index + ":" + qe.getMessage().getMessageId());
index++;
}
@@ -97,9 +97,96 @@ public class AMQPriorityQueueTest extends SimpleAMQQueueTest
protected AMQMessage createMessage(byte i) throws AMQException
{
AMQMessage message = super.createMessage();
-
- ((BasicContentHeaderProperties)message.getContentHeaderBody().properties).setPriority(i);
+
+ ((BasicContentHeaderProperties) message.getContentHeaderBody().properties).setPriority(i);
return message;
}
+
+
+ public void testMessagesFlowToDiskWithPriority() throws AMQException, InterruptedException
+ {
+ int PRIORITIES = 1;
+ FieldTable arguments = new FieldTable();
+ arguments.put(AMQQueueFactory.X_QPID_PRIORITIES, PRIORITIES);
+
+ // Create IncomingMessage and nondurable queue
+ NonTransactionalContext txnContext = new NonTransactionalContext(_transactionLog, null, null, null);
+
+ //Create a priorityQueue
+ _queue = (SimpleAMQQueue) AMQQueueFactory.createAMQQueueImpl(new AMQShortString("testMessagesFlowToDiskWithPriority"), false, _owner, false, _virtualHost, arguments);
+
+ MESSAGE_SIZE = 1;
+ long MEMORY_MAX = PRIORITIES * 2;
+ int MESSAGE_COUNT = (int) MEMORY_MAX * 2;
+ //Set the Memory Usage to be very low
+ _queue.setMemoryUsageMaximum(MEMORY_MAX);
+
+ for (int msgCount = 0; msgCount < MESSAGE_COUNT / 2; msgCount++)
+ {
+ sendMessage(txnContext, (msgCount % 10));
+ }
+
+ //Check that we can hold 10 messages without flowing
+ assertEquals(MESSAGE_COUNT / 2, _queue.getMessageCount());
+ assertEquals(MEMORY_MAX, _queue.getMemoryUsageMaximum());
+ assertEquals(_queue.getMemoryUsageMaximum(), _queue.getMemoryUsageCurrent());
+ assertTrue("Queue is flowed.", !_queue.isFlowed());
+
+ // Send another and ensure we are flowed
+ sendMessage(txnContext, 9);
+
+ //Give the Purging Thread a chance to run
+ Thread.yield();
+ Thread.sleep(500);
+
+ assertTrue("Queue is not flowed.", _queue.isFlowed());
+ assertEquals("Queue contains more messages than expected.", MESSAGE_COUNT / 2 + 1, _queue.getMessageCount());
+ assertEquals("Queue over memory quota.",MESSAGE_COUNT / 2, _queue.getMemoryUsageCurrent());
+
+
+ //send another batch of messagse so the total in each queue is equal
+ for (int msgCount = 0; msgCount < (MESSAGE_COUNT / 2) ; msgCount++)
+ {
+ sendMessage(txnContext, (msgCount % 10));
+
+ long usage = _queue.getMemoryUsageCurrent();
+ assertTrue("Queue has gone over quota:" + usage,
+ usage <= _queue.getMemoryUsageMaximum());
+
+ assertTrue("Queue has a negative quota:" + usage, usage > 0);
+
+ }
+ assertEquals(MESSAGE_COUNT + 1, _queue.getMessageCount());
+ assertEquals(MEMORY_MAX, _queue.getMemoryUsageCurrent());
+ assertTrue("Queue is not flowed.", _queue.isFlowed());
+
+ _queue.registerSubscription(_subscription, false);
+
+ int slept = 0;
+ while (_subscription.getQueueEntries().size() != MESSAGE_COUNT + 1 && slept < 10)
+ {
+ Thread.yield();
+ Thread.sleep(500);
+ slept++;
+ }
+
+ //Ensure the messages are retreived
+ assertEquals("Not all messages were received, slept:" + slept / 2 + "s", MESSAGE_COUNT + 1, _subscription.getQueueEntries().size());
+
+ //Check the queue is still within it's limits.
+ assertTrue("Queue has gone over quota:" + _queue.getMemoryUsageCurrent(),
+ _queue.getMemoryUsageCurrent() <= _queue.getMemoryUsageMaximum());
+
+ assertTrue("Queue has a negative quota:" + _queue.getMemoryUsageCurrent(), _queue.getMemoryUsageCurrent() >= 0);
+
+ for (int index = 0; index < MESSAGE_COUNT; index++)
+ {
+ // Ensure that we have received the messages and it wasn't flushed to disk before we received it.
+ AMQMessage message = _subscription.getMessages().get(index);
+ assertNotNull("Message:" + message.debugIdentity() + " was null.", message);
+ }
+
+ }
+
}
diff --git a/qpid/java/broker/src/test/java/org/apache/qpid/server/queue/AMQQueueAlertTest.java b/qpid/java/broker/src/test/java/org/apache/qpid/server/queue/AMQQueueAlertTest.java
index 1bc50db1d5..237fe20f7e 100644
--- a/qpid/java/broker/src/test/java/org/apache/qpid/server/queue/AMQQueueAlertTest.java
+++ b/qpid/java/broker/src/test/java/org/apache/qpid/server/queue/AMQQueueAlertTest.java
@@ -34,6 +34,7 @@ import org.apache.qpid.server.AMQChannel;
import org.apache.qpid.server.transactionlog.TransactionLog;
import org.apache.qpid.server.subscription.Subscription;
import org.apache.qpid.server.subscription.SubscriptionFactoryImpl;
+import org.apache.qpid.server.configuration.QueueConfiguration;
import org.apache.qpid.server.protocol.AMQMinaProtocolSession;
import org.apache.qpid.server.protocol.InternalTestProtocolSession;
import org.apache.qpid.framing.ContentHeaderBody;
@@ -203,7 +204,7 @@ public class AMQQueueAlertTest extends TestCase
// Send messages(no of message to be little more than what can cause a Queue_Depth alert)
int messageCount = Math.round(MAX_QUEUE_DEPTH / MAX_MESSAGE_SIZE) + 10;
- long totalSize = (messageCount * MAX_MESSAGE_SIZE) >> 10;
+ long totalSize = (messageCount * MAX_MESSAGE_SIZE);
sendMessages(messageCount, MAX_MESSAGE_SIZE);
// Check queueDepth. There should be no messages on the queue and as the subscriber is listening
@@ -250,26 +251,6 @@ public class AMQQueueAlertTest extends TestCase
_queueMBean.clearQueue();
assertEquals(new Long(0), new Long(_queueMBean.getQueueDepth()));
}
-
- public void testAlertConfiguration() throws AMQException
- {
- // Setup configuration
- CompositeConfiguration config = new CompositeConfiguration();
- config.setProperty("maximumMessageSize", new Long(23));
- config.setProperty("maximumMessageCount", new Long(24));
- config.setProperty("maximumQueueDepth", new Long(25));
- config.setProperty("maximumMessageAge", new Long(26));
-
- // Create queue and set config
- _queue = getNewQueue();
- _queue.configure(config);
-
- // Check alerts and notifications
- Set<NotificationCheck> checks = _queue.getNotificationChecks();
- assertNotNull("No checks found", checks);
- assertFalse("Checks should not be empty", checks.isEmpty());
- assertEquals("Wrong number of checks", 4, checks.size());
- }
protected IncomingMessage message(final boolean immediate, long size) throws AMQException
{
diff --git a/qpid/java/broker/src/test/java/org/apache/qpid/server/queue/AMQQueueFactoryPriorityTest.java b/qpid/java/broker/src/test/java/org/apache/qpid/server/queue/AMQQueueFactoryPriorityTest.java
new file mode 100644
index 0000000000..0d6c5948b4
--- /dev/null
+++ b/qpid/java/broker/src/test/java/org/apache/qpid/server/queue/AMQQueueFactoryPriorityTest.java
@@ -0,0 +1,70 @@
+/*
+ *
+ * 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.framing.AMQShortString;
+
+public class AMQQueueFactoryPriorityTest extends AMQQueueFactoryTest
+{
+ private static final int PRIORITIES = 5;
+
+ @Override
+ public void setUp()
+ {
+ super.setUp();
+ _arguments.put(new AMQShortString(AMQQueueFactory.X_QPID_PRIORITIES), PRIORITIES);
+ }
+
+ @Override
+ public void testQueueRegistration()
+ {
+ try
+ {
+ AMQQueue queue = createQueue();
+
+ assertEquals("Queue not a priorty queue", AMQPriorityQueue.class, queue.getClass());
+
+ assertEquals("Incorrect number of priorities set", PRIORITIES, ((AMQPriorityQueue) queue).getPriorities());
+ }
+ catch (AMQException e)
+ {
+ fail(e.getMessage());
+ }
+ }
+
+ @Override
+ public void testQueueValuesAfterCreation()
+ {
+ try
+ {
+ AMQQueue queue = createQueue();
+
+ assertEquals("MemoryMaximumSize not set correctly:", MAX_SIZE, queue.getMemoryUsageMaximum());
+ //NOTE: Priority queue will show 0 as minimum as the minimum value is actually spread between its sub QELs
+ assertEquals("MemoryMinimumSize not 0 as expected for a priority queue:", 0, queue.getMemoryUsageMinimum());
+ }
+ catch (AMQException e)
+ {
+ fail(e.getMessage());
+ }
+ }
+}
diff --git a/qpid/java/broker/src/test/java/org/apache/qpid/server/queue/AMQQueueFactoryTest.java b/qpid/java/broker/src/test/java/org/apache/qpid/server/queue/AMQQueueFactoryTest.java
index 520e49c56a..b8aa8272ba 100644
--- a/qpid/java/broker/src/test/java/org/apache/qpid/server/queue/AMQQueueFactoryTest.java
+++ b/qpid/java/broker/src/test/java/org/apache/qpid/server/queue/AMQQueueFactoryTest.java
@@ -29,8 +29,11 @@ import org.apache.qpid.AMQException;
public class AMQQueueFactoryTest extends TestCase
{
+ final int MAX_SIZE = 50;
+
QueueRegistry _queueRegistry;
VirtualHost _virtualHost;
+ protected FieldTable _arguments;
public void setUp()
{
@@ -41,6 +44,15 @@ public class AMQQueueFactoryTest extends TestCase
_queueRegistry = _virtualHost.getQueueRegistry();
assertEquals("Queues registered on an empty virtualhost", 0, _queueRegistry.getQueues().size());
+
+
+ _arguments = new FieldTable();
+
+ //Ensure we can call createQueue with a priority int value
+ _arguments.put(AMQQueueFactory.QPID_POLICY_TYPE, AMQQueueFactory.QPID_FLOW_TO_DISK);
+ // each message in the QBAAT is around 9-10 bytes each so only give space for half
+
+ _arguments.put(AMQQueueFactory.QPID_MAX_SIZE, MAX_SIZE);
}
public void tearDown()
@@ -50,17 +62,19 @@ public class AMQQueueFactoryTest extends TestCase
}
- public void testPriorityQueueRegistration()
+ protected AMQQueue createQueue() throws AMQException
{
- FieldTable fieldTable = new FieldTable();
- fieldTable.put(new AMQShortString(AMQQueueFactory.X_QPID_PRIORITIES), 5);
+ return AMQQueueFactory.createAMQQueueImpl(new AMQShortString(this.getName()), false, new AMQShortString("owner"), false,
+ _virtualHost, _arguments);
+ }
+
+ public void testQueueRegistration()
+ {
try
{
- AMQQueue queue = AMQQueueFactory.createAMQQueueImpl(new AMQShortString("testPriorityQueue"), false, new AMQShortString("owner"), false,
- _virtualHost, fieldTable);
-
- assertEquals("Queue not a priorty queue", AMQPriorityQueue.class, queue.getClass());
+ AMQQueue queue = createQueue();
+ assertEquals("Queue not a simple queue", SimpleAMQQueue.class, queue.getClass());
}
catch (AMQException e)
{
@@ -68,18 +82,20 @@ public class AMQQueueFactoryTest extends TestCase
}
}
-
- public void testSimpleQueueRegistration()
+ public void testQueueValuesAfterCreation()
{
try
{
- AMQQueue queue = AMQQueueFactory.createAMQQueueImpl(new AMQShortString("testQueue"), false, new AMQShortString("owner"), false,
- _virtualHost, null);
- assertEquals("Queue not a simple queue", SimpleAMQQueue.class, queue.getClass());
+ AMQQueue queue = createQueue();
+
+ assertEquals("MemoryMaximumSize not set correctly:", MAX_SIZE, queue.getMemoryUsageMaximum());
+ assertEquals("MemoryMinimumSize not defaulted to half maximum:", MAX_SIZE / 2, queue.getMemoryUsageMinimum());
+
}
catch (AMQException e)
{
fail(e.getMessage());
}
}
+
}
diff --git a/qpid/java/broker/src/test/java/org/apache/qpid/server/queue/AMQQueueMBeanTest.java b/qpid/java/broker/src/test/java/org/apache/qpid/server/queue/AMQQueueMBeanTest.java
index daa8e4beb7..3d189ae6c5 100644
--- a/qpid/java/broker/src/test/java/org/apache/qpid/server/queue/AMQQueueMBeanTest.java
+++ b/qpid/java/broker/src/test/java/org/apache/qpid/server/queue/AMQQueueMBeanTest.java
@@ -73,7 +73,7 @@ public class AMQQueueMBeanTest extends TestCase
sendMessages(messageCount, false);
assertTrue(_queueMBean.getMessageCount() == messageCount);
assertTrue(_queueMBean.getReceivedMessageCount() == messageCount);
- long queueDepth = (messageCount * MESSAGE_SIZE) >> 10;
+ long queueDepth = (messageCount * MESSAGE_SIZE);
assertTrue(_queueMBean.getQueueDepth() == queueDepth);
_queueMBean.deleteMessageFromTop();
@@ -94,7 +94,7 @@ public class AMQQueueMBeanTest extends TestCase
sendMessages(messageCount, true);
assertEquals("", messageCount, _queueMBean.getMessageCount().intValue());
assertTrue(_queueMBean.getReceivedMessageCount() == messageCount);
- long queueDepth = (messageCount * MESSAGE_SIZE) >> 10;
+ long queueDepth = (messageCount * MESSAGE_SIZE);
assertTrue(_queueMBean.getQueueDepth() == queueDepth);
_queueMBean.deleteMessageFromTop();
@@ -175,7 +175,7 @@ public class AMQQueueMBeanTest extends TestCase
assertTrue(_queueMBean.getMaximumMessageCount() == 50000);
assertTrue(_queueMBean.getMaximumMessageSize() == 2000);
- assertTrue(_queueMBean.getMaximumQueueDepth() == (maxQueueDepth >> 10));
+ assertTrue(_queueMBean.getMaximumQueueDepth() == (maxQueueDepth));
assertTrue(_queueMBean.getName().equals("testQueue"));
assertTrue(_queueMBean.getOwner().equals("AMQueueMBeanTest"));
diff --git a/qpid/java/broker/src/test/java/org/apache/qpid/server/queue/AMQQueueThreadPoolTest.java b/qpid/java/broker/src/test/java/org/apache/qpid/server/queue/AMQQueueThreadPoolTest.java
new file mode 100644
index 0000000000..c7cf778d93
--- /dev/null
+++ b/qpid/java/broker/src/test/java/org/apache/qpid/server/queue/AMQQueueThreadPoolTest.java
@@ -0,0 +1,98 @@
+/*
+ *
+ * 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 junit.framework.TestCase;
+import org.apache.qpid.AMQException;
+import org.apache.qpid.framing.AMQShortString;
+import org.apache.qpid.framing.FieldTable;
+import org.apache.qpid.pool.ReferenceCountingExecutorService;
+import org.apache.qpid.server.registry.ApplicationRegistry;
+import org.apache.qpid.server.virtualhost.VirtualHost;
+
+public class AMQQueueThreadPoolTest extends TestCase
+{
+
+ public void testSimpleAMQQueue() throws AMQException
+ {
+ int initialCount = ReferenceCountingExecutorService.getInstance().getReferenceCount();
+ VirtualHost test = ApplicationRegistry.getInstance(1).getVirtualHostRegistry().getVirtualHost("test");
+
+ try
+ {
+ SimpleAMQQueue queue = (SimpleAMQQueue) AMQQueueFactory.createAMQQueueImpl(new AMQShortString("test"), false,
+ new AMQShortString("owner"),
+ false, test, null);
+
+ assertFalse("Creation did not start Pool.", ReferenceCountingExecutorService.getInstance().getPool().isShutdown());
+
+ //This is +2 because:
+ // 1 - asyncDelivery Thread
+ // 2 - queue InhalerThread
+ // 3 - queue PurgerThread
+ assertEquals("References not increased", initialCount + 3, ReferenceCountingExecutorService.getInstance().getReferenceCount());
+
+ queue.stop();
+
+ assertEquals("References not decreased", initialCount, ReferenceCountingExecutorService.getInstance().getReferenceCount());
+ }
+ finally
+ {
+ ApplicationRegistry.remove(1);
+ }
+ }
+
+ public void testPriorityAMQQueue() throws AMQException
+ {
+ int initialCount = ReferenceCountingExecutorService.getInstance().getReferenceCount();
+ VirtualHost test = ApplicationRegistry.getInstance(1).getVirtualHostRegistry().getVirtualHost("test");
+
+ try
+ {
+
+ FieldTable arguements = new FieldTable();
+ int priorities = 10;
+ arguements.put(AMQQueueFactory.X_QPID_PRIORITIES, priorities);
+
+ SimpleAMQQueue queue = (SimpleAMQQueue) AMQQueueFactory.createAMQQueueImpl(new AMQShortString("test"), false,
+ new AMQShortString("owner"),
+ false, test, arguements);
+
+ assertFalse("Creation did not start Pool.", ReferenceCountingExecutorService.getInstance().getPool().isShutdown());
+
+ //This is +2 because:
+ // 1 - asyncDelivery Thread
+ // 2 + 3 - queue InhalerThread, PurgerThread for the Priority Queue
+ // priorities * ( Inhaler , Purger) for each priority level
+ assertEquals("References not increased", (initialCount + 3) + priorities * 2,
+ ReferenceCountingExecutorService.getInstance().getReferenceCount());
+
+ queue.stop();
+
+ assertEquals("References not decreased", initialCount, ReferenceCountingExecutorService.getInstance().getReferenceCount());
+ }
+ finally
+ {
+ ApplicationRegistry.remove(1);
+ }
+ }
+
+}
diff --git a/qpid/java/broker/src/test/java/org/apache/qpid/server/queue/AckTest.java b/qpid/java/broker/src/test/java/org/apache/qpid/server/queue/AckTest.java
index 98465eda20..9f8d5f9a99 100644
--- a/qpid/java/broker/src/test/java/org/apache/qpid/server/queue/AckTest.java
+++ b/qpid/java/broker/src/test/java/org/apache/qpid/server/queue/AckTest.java
@@ -30,14 +30,16 @@ import org.apache.qpid.framing.abstraction.MessagePublishInfo;
import org.apache.qpid.framing.abstraction.MessagePublishInfoImpl;
import org.apache.qpid.server.AMQChannel;
import org.apache.qpid.server.RequiredDeliveryException;
+import org.apache.qpid.server.virtualhost.VirtualHost;
import org.apache.qpid.server.subscription.Subscription;
import org.apache.qpid.server.subscription.SubscriptionFactoryImpl;
import org.apache.qpid.server.flow.LimitlessCreditManager;
import org.apache.qpid.server.flow.Pre0_10CreditManager;
import org.apache.qpid.server.ack.UnacknowledgedMessageMap;
import org.apache.qpid.server.registry.ApplicationRegistry;
-import org.apache.qpid.server.store.TestMemoryMessageStore;
import org.apache.qpid.server.store.StoreContext;
+import org.apache.qpid.server.store.TestableMemoryMessageStore;
+import org.apache.qpid.server.store.MemoryMessageStore;
import org.apache.qpid.server.txn.NonTransactionalContext;
import org.apache.qpid.server.txn.TransactionalContext;
import org.apache.qpid.server.util.NullApplicationRegistry;
@@ -57,7 +59,7 @@ public class AckTest extends TestCase
private MockProtocolSession _protocolSession;
- private TestMemoryMessageStore _messageStore;
+ private TestableMemoryMessageStore _messageStore;
private StoreContext _storeContext = new StoreContext();
@@ -72,14 +74,15 @@ public class AckTest extends TestCase
super.setUp();
ApplicationRegistry.initialise(new NullApplicationRegistry(), 1);
- _messageStore = new TestMemoryMessageStore();
+ VirtualHost vhost = ApplicationRegistry.getInstance().getVirtualHostRegistry().getVirtualHost("test");
+ _messageStore = new TestableMemoryMessageStore((MemoryMessageStore)vhost.getTransactionLog());
_protocolSession = new MockProtocolSession(_messageStore);
_channel = new AMQChannel(_protocolSession,5, _messageStore /*dont need exchange registry*/);
_protocolSession.addChannel(_channel);
- _queue = AMQQueueFactory.createAMQQueueImpl(new AMQShortString("myQ"), false, new AMQShortString("guest"), true, ApplicationRegistry.getInstance().getVirtualHostRegistry().getVirtualHost("test"),
- null);
+ _queue = AMQQueueFactory.createAMQQueueImpl(new AMQShortString("myQ"), false, new AMQShortString("guest"),
+ true, vhost, null);
}
protected void tearDown()
@@ -185,7 +188,7 @@ public class AckTest extends TestCase
/**
* Tests that in no-ack mode no messages are retained
*/
- public void testPersistentNoAckMode() throws AMQException
+ public void testPersistentNoAckMode() throws AMQException, InterruptedException
{
// false arg means no acks expected
_subscription = SubscriptionFactoryImpl.INSTANCE.createSubscription(5, _protocolSession, DEFAULT_CONSUMER_TAG, false,null,false, new LimitlessCreditManager());
@@ -194,7 +197,7 @@ public class AckTest extends TestCase
UnacknowledgedMessageMap map = _channel.getUnacknowledgedMessageMap();
assertTrue(map.size() == 0);
- assertTrue(_messageStore.getMessageMetaDataMap().size() == 0);
+ assertTrue("Size:" + _messageStore.getMessageMetaDataMap().size(), _messageStore.getMessageMetaDataMap().size() == 0);
assertTrue(_messageStore.getContentBodyMap().size() == 0);
}
diff --git a/qpid/java/broker/src/test/java/org/apache/qpid/server/queue/FileQueueBackingStoreTest.java b/qpid/java/broker/src/test/java/org/apache/qpid/server/queue/FileQueueBackingStoreTest.java
new file mode 100644
index 0000000000..d2cbd46e28
--- /dev/null
+++ b/qpid/java/broker/src/test/java/org/apache/qpid/server/queue/FileQueueBackingStoreTest.java
@@ -0,0 +1,223 @@
+/*
+ *
+ * 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 junit.framework.TestCase;
+import org.apache.commons.configuration.Configuration;
+import org.apache.commons.configuration.ConfigurationException;
+import org.apache.commons.configuration.PropertiesConfiguration;
+import org.apache.qpid.AMQException;
+import org.apache.qpid.exchange.ExchangeDefaults;
+import org.apache.qpid.framing.AMQShortString;
+import org.apache.qpid.framing.BasicContentHeaderProperties;
+import org.apache.qpid.framing.ContentHeaderBody;
+import org.apache.qpid.framing.abstraction.ContentChunk;
+import org.apache.qpid.framing.abstraction.MessagePublishInfo;
+import org.apache.qpid.framing.abstraction.MessagePublishInfoImpl;
+import org.apache.qpid.framing.amqp_8_0.BasicPublishBodyImpl;
+import org.apache.qpid.server.configuration.VirtualHostConfiguration;
+import org.apache.qpid.server.store.MemoryMessageStore;
+import org.apache.qpid.server.transactionlog.TransactionLog;
+import org.apache.qpid.server.virtualhost.VirtualHost;
+
+import java.io.File;
+
+public class FileQueueBackingStoreTest extends TestCase
+{
+ QueueBackingStore _backing;
+ private TransactionLog _transactionLog;
+ VirtualHost _vhost;
+ VirtualHostConfiguration _vhostConfig;
+ FileQueueBackingStoreFactory _factory;
+ AMQQueue _queue;
+
+ public void setUp() throws Exception
+ {
+ _factory = new FileQueueBackingStoreFactory();
+ PropertiesConfiguration config = new PropertiesConfiguration();
+ config.addProperty("store.class", MemoryMessageStore.class.getName());
+ _vhostConfig = new VirtualHostConfiguration(this.getName() + "-Vhost", config);
+ _vhost = new VirtualHost(_vhostConfig);
+ _transactionLog = _vhost.getTransactionLog();
+
+ _factory.configure(_vhost, _vhost.getConfiguration());
+
+ _queue = new SimpleAMQQueue(new AMQShortString(this.getName()), false, null, false, _vhost);
+ _backing = _factory.createBacking(_queue);
+ }
+
+ private void resetBacking(Configuration configuration) throws Exception
+ {
+ configuration.addProperty("store.class", MemoryMessageStore.class.getName());
+ _vhostConfig = new VirtualHostConfiguration(this.getName() + "-Vhost", configuration);
+ _vhost = new VirtualHost(_vhostConfig);
+ _transactionLog = _vhost.getTransactionLog();
+
+ _factory = new FileQueueBackingStoreFactory();
+
+ _factory.configure(_vhost, _vhost.getConfiguration());
+
+ _backing = _factory.createBacking(_queue);
+ }
+
+ public void testInvalidSetupRootExistsIsFile() throws Exception
+ {
+
+ File fileAsRoot = File.createTempFile("tmpRoot", "");
+ fileAsRoot.deleteOnExit();
+
+ PropertiesConfiguration configuration = new PropertiesConfiguration();
+ configuration.addProperty(VirtualHostConfiguration.FLOW_TO_DISK_PATH, fileAsRoot.getAbsolutePath());
+
+ try
+ {
+ resetBacking(configuration);
+ fail("Exception expected to be thrown");
+ }
+ catch (ConfigurationException ce)
+ {
+ assertTrue("Expected Exception not thrown, expecting:" +
+ "Unable to create Temporary Flow to Disk store as specified root is a file:",
+ ce.getMessage().
+ startsWith("Unable to create Temporary Flow to Disk store as specified root is a file:"));
+ }
+
+ }
+
+ public void testInvalidSetupRootExistsCantWrite() throws Exception
+ {
+
+ File fileAsRoot = new File("/var/log");
+
+ PropertiesConfiguration configuration = new PropertiesConfiguration();
+
+ configuration.addProperty(VirtualHostConfiguration.FLOW_TO_DISK_PATH, fileAsRoot.getAbsolutePath());
+
+ try
+ {
+ resetBacking(configuration);
+ fail("Exception expected to be thrown");
+ }
+ catch (ConfigurationException ce)
+ {
+ assertEquals("Unable to create Temporary Flow to Disk store. Unable to write to specified root:/var/log",
+ ce.getMessage());
+ }
+
+ }
+
+ public void testEmptyTransientFlowToDisk() throws UnableToFlowMessageException, AMQException
+ {
+ AMQMessage original = MessageFactory.getInstance().createMessage(null, false);
+
+ ContentHeaderBody chb = new ContentHeaderBody(new BasicContentHeaderProperties(), BasicPublishBodyImpl.CLASS_ID);
+ chb.bodySize = 0L;
+
+ runTestWithMessage(original, chb);
+ }
+
+ public void testEmptyPersistentFlowToDisk() throws UnableToFlowMessageException, AMQException
+ {
+
+ AMQMessage original = MessageFactory.getInstance().createMessage(_transactionLog, true);
+ ContentHeaderBody chb = new ContentHeaderBody(new BasicContentHeaderProperties(), BasicPublishBodyImpl.CLASS_ID);
+ chb.bodySize = 0L;
+ ((BasicContentHeaderProperties) chb.properties).setDeliveryMode((byte) 2);
+
+ runTestWithMessage(original, chb);
+
+ }
+
+ public void testNonEmptyTransientFlowToDisk() throws UnableToFlowMessageException, AMQException
+ {
+ AMQMessage original = MessageFactory.getInstance().createMessage(null, false);
+
+ ContentHeaderBody chb = new ContentHeaderBody(new BasicContentHeaderProperties(), BasicPublishBodyImpl.CLASS_ID);
+ chb.bodySize = 100L;
+
+ runTestWithMessage(original, chb);
+ }
+
+ public void testNonEmptyPersistentFlowToDisk() throws UnableToFlowMessageException, AMQException
+ {
+ AMQMessage original = MessageFactory.getInstance().createMessage(_transactionLog, true);
+ ContentHeaderBody chb = new ContentHeaderBody(new BasicContentHeaderProperties(), BasicPublishBodyImpl.CLASS_ID);
+ chb.bodySize = 100L;
+ ((BasicContentHeaderProperties) chb.properties).setDeliveryMode((byte) 2);
+
+ runTestWithMessage(original, chb);
+ }
+
+ void runTestWithMessage(AMQMessage original, ContentHeaderBody chb) throws UnableToFlowMessageException, AMQException
+ {
+
+ // Create message
+
+ original.setPublishAndContentHeaderBody(null,
+ new MessagePublishInfoImpl(ExchangeDefaults.DIRECT_EXCHANGE_NAME,
+ false, false, new AMQShortString("routing")),
+ chb);
+ if (chb.bodySize > 0)
+ {
+ ContentChunk chunk = new MockContentChunk((int) chb.bodySize / 2);
+
+ original.addContentBodyFrame(null, chunk, false);
+
+ chunk = new MockContentChunk((int) chb.bodySize / 2);
+
+ original.addContentBodyFrame(null, chunk, true);
+ }
+
+ _backing.unload(original);
+
+ AMQMessage fromDisk = _backing.load(original.getMessageId());
+
+ assertEquals("Message IDs do not match", original.getMessageId(), fromDisk.getMessageId());
+ assertEquals("Message arrival times do not match", original.getArrivalTime(), fromDisk.getArrivalTime());
+ assertEquals(original.isPersistent(), fromDisk.isPersistent());
+
+ // Validate the MPI data was restored correctly
+ MessagePublishInfo originalMPI = original.getMessagePublishInfo();
+ MessagePublishInfo fromDiskMPI = fromDisk.getMessagePublishInfo();
+ assertEquals("Exchange", originalMPI.getExchange(), fromDiskMPI.getExchange());
+ assertEquals(originalMPI.isImmediate(), fromDiskMPI.isImmediate());
+ assertEquals(originalMPI.isMandatory(), fromDiskMPI.isMandatory());
+ assertEquals(originalMPI.getRoutingKey(), fromDiskMPI.getRoutingKey());
+
+ // Validate BodyCounts.
+ int originalBodyCount = original.getBodyCount();
+ assertEquals(originalBodyCount, fromDisk.getBodyCount());
+
+ if (originalBodyCount > 0)
+ {
+ for (int index = 0; index < originalBodyCount; index++)
+ {
+ ContentChunk originalChunk = original.getContentChunk(index);
+ ContentChunk fromDiskChunk = fromDisk.getContentChunk(index);
+
+ assertEquals(originalChunk.getSize(), fromDiskChunk.getSize());
+ assertEquals(originalChunk.getData(), fromDiskChunk.getData());
+ }
+ }
+
+ }
+
+}
diff --git a/qpid/java/broker/src/test/java/org/apache/qpid/server/queue/MessageFactoryRecoveryTest.java b/qpid/java/broker/src/test/java/org/apache/qpid/server/queue/MessageFactoryRecoveryTest.java
index db0fc56303..a272da88ac 100644
--- a/qpid/java/broker/src/test/java/org/apache/qpid/server/queue/MessageFactoryRecoveryTest.java
+++ b/qpid/java/broker/src/test/java/org/apache/qpid/server/queue/MessageFactoryRecoveryTest.java
@@ -29,16 +29,15 @@ public class MessageFactoryRecoveryTest extends TestCase
public void setUp()
{
_factory = MessageFactory.getInstance();
-
+ _factory.reset();
}
public void test()
{
- AMQMessage message = _factory.createMessage(null, false);
-
- _factory.enableRecover();
- Long messasgeID = message.getMessageId();
+ Long messasgeID = 1L;
+ //Create initial message
+ _factory.createMessage(messasgeID, null);
try
{
@@ -67,7 +66,7 @@ public class MessageFactoryRecoveryTest extends TestCase
messasgeID += 100;
try
{
- message = _factory.createMessage(messasgeID, null);
+ AMQMessage message = _factory.createMessage(messasgeID, null);
assertEquals("Factory assigned incorrect id.", messasgeID, message.getMessageId());
}
catch (Exception re)
@@ -76,7 +75,7 @@ public class MessageFactoryRecoveryTest extends TestCase
}
// End the reovery process.
- _factory.start();
+ _factory.recoveryComplete();
//Check we cannot still create by id after ending recovery phase
try
@@ -96,7 +95,7 @@ public class MessageFactoryRecoveryTest extends TestCase
try
{
- message = _factory.createMessage(null, false);
+ AMQMessage message = _factory.createMessage(null, false);
assertEquals("Factory assigned incorrect id.", messasgeID, message.getMessageId());
}
catch (Exception re)
diff --git a/qpid/java/broker/src/test/java/org/apache/qpid/server/queue/MockAMQMessage.java b/qpid/java/broker/src/test/java/org/apache/qpid/server/queue/MockAMQMessage.java
index cc6c486e11..11049a7ae3 100644
--- a/qpid/java/broker/src/test/java/org/apache/qpid/server/queue/MockAMQMessage.java
+++ b/qpid/java/broker/src/test/java/org/apache/qpid/server/queue/MockAMQMessage.java
@@ -22,6 +22,15 @@ package org.apache.qpid.server.queue;
import org.apache.qpid.server.store.StoreContext;
import org.apache.qpid.AMQException;
+import org.apache.qpid.framing.abstraction.MessagePublishInfoImpl;
+import org.apache.qpid.framing.abstraction.ContentChunk;
+import org.apache.qpid.framing.ContentHeaderBody;
+import org.apache.qpid.framing.BasicContentHeaderProperties;
+import org.apache.qpid.framing.BasicPublishBody;
+import org.apache.qpid.framing.amqp_8_0.BasicPublishBodyImpl;
+
+import java.util.LinkedList;
+import java.util.ArrayList;
public class MockAMQMessage extends TransientAMQMessage
{
@@ -29,6 +38,15 @@ public class MockAMQMessage extends TransientAMQMessage
throws AMQException
{
super(messageId);
+ _messagePublishInfo = new MessagePublishInfoImpl(null,false,false,null);
+ BasicContentHeaderProperties properties = new BasicContentHeaderProperties();
+
+ properties.setMessageId(String.valueOf(messageId));
+ properties.setTimestamp(System.currentTimeMillis());
+ properties.setDeliveryMode((byte)1);
+
+ _contentHeaderBody = new ContentHeaderBody(properties, BasicPublishBodyImpl.CLASS_ID);
+ _contentBodies = new ArrayList<ContentChunk>();
}
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 5f1cc81772..ff814840bc 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
@@ -20,15 +20,18 @@
*/
package org.apache.qpid.server.queue;
+import org.apache.commons.configuration.PropertiesConfiguration;
+import org.apache.qpid.AMQException;
import org.apache.qpid.framing.AMQShortString;
import org.apache.qpid.framing.FieldTable;
-import org.apache.qpid.server.virtualhost.VirtualHost;
+import org.apache.qpid.server.configuration.ServerConfiguration;
+import org.apache.qpid.server.configuration.VirtualHostConfiguration;
import org.apache.qpid.server.exchange.Exchange;
-import org.apache.qpid.server.subscription.Subscription;
-import org.apache.qpid.server.store.StoreContext;
import org.apache.qpid.server.management.ManagedObject;
-import org.apache.qpid.AMQException;
-import org.apache.commons.configuration.Configuration;
+import org.apache.qpid.server.store.StoreContext;
+import org.apache.qpid.server.subscription.Subscription;
+import org.apache.qpid.server.virtualhost.VirtualHost;
+import org.apache.qpid.server.registry.ApplicationRegistry;
import java.util.List;
import java.util.Set;
@@ -38,10 +41,20 @@ public class MockAMQQueue implements AMQQueue
private boolean _deleted = false;
private int _queueCount;
private AMQShortString _name;
+ private VirtualHost _virtualhost;
public MockAMQQueue(String name)
{
- _name = new AMQShortString(name);
+ _name = new AMQShortString(name);
+ _virtualhost = ApplicationRegistry.getInstance().getVirtualHostRegistry().getVirtualHost("test");
+ try
+ {
+ _virtualhost.getQueueRegistry().registerQueue(this);
+ }
+ catch (AMQException e)
+ {
+ e.printStackTrace();
+ }
}
public AMQShortString getName()
@@ -66,7 +79,7 @@ public class MockAMQQueue implements AMQQueue
public VirtualHost getVirtualHost()
{
- return null; //To change body of implemented methods use File | Settings | File Templates.
+ return _virtualhost;
}
public void bind(Exchange exchange, AMQShortString routingKey, FieldTable arguments) throws AMQException
@@ -114,6 +127,11 @@ public class MockAMQQueue implements AMQQueue
return false; //To change body of implemented methods use File | Settings | File Templates.
}
+ public boolean isFlowed()
+ {
+ return false; //To change body of implemented methods use File | Settings | File Templates.
+ }
+
public int getMessageCount()
{
return 0; //To change body of implemented methods use File | Settings | File Templates.
@@ -146,7 +164,7 @@ public class MockAMQQueue implements AMQQueue
public int delete() throws AMQException
{
- return 0; //To change body of implemented methods use File | Settings | File Templates.
+ return 0; //To change body of implemented methods use File | Settings | File Templates.
}
public QueueEntry enqueue(StoreContext storeContext, AMQMessage message) throws AMQException
@@ -215,6 +233,26 @@ public class MockAMQQueue implements AMQQueue
//To change body of implemented methods use File | Settings | File Templates.
}
+ public long getMemoryUsageMaximum()
+ {
+ return 0; //To change body of implemented methods use File | Settings | File Templates.
+ }
+
+ public void setMemoryUsageMaximum(long maximumMemoryUsage)
+ {
+ //To change body of implemented methods use File | Settings | File Templates.
+ }
+
+ public long getMemoryUsageMinimum()
+ {
+ return 0; //To change body of implemented methods use File | Settings | File Templates.
+ }
+
+ public void setMemoryUsageMinimum(long minimumMemoryUsage)
+ {
+ //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.
@@ -270,7 +308,6 @@ public class MockAMQQueue implements AMQQueue
return 0; //To change body of implemented methods use File | Settings | File Templates.
}
- @Override
public void checkMessageStatus() throws AMQException
{
//To change body of implemented methods use File | Settings | File Templates.
@@ -301,9 +338,9 @@ public class MockAMQQueue implements AMQQueue
//To change body of implemented methods use File | Settings | File Templates.
}
- public void configure(Configuration virtualHostDefaultQueueConfiguration)
+ public long getMemoryUsageCurrent()
{
- //To change body of implemented methods use File | Settings | File Templates.
+ return 0;
}
public ManagedObject getManagedObject()
@@ -315,4 +352,10 @@ public class MockAMQQueue implements AMQQueue
{
return 0; //To change body of implemented methods use File | Settings | File Templates.
}
+
+ public void setMinimumAlertRepeatGap(long value)
+ {
+
+ }
+
}
diff --git a/qpid/java/broker/src/test/java/org/apache/qpid/server/queue/MockQueueEntry.java b/qpid/java/broker/src/test/java/org/apache/qpid/server/queue/MockQueueEntry.java
index ed7b2923e7..92235648ec 100644
--- a/qpid/java/broker/src/test/java/org/apache/qpid/server/queue/MockQueueEntry.java
+++ b/qpid/java/broker/src/test/java/org/apache/qpid/server/queue/MockQueueEntry.java
@@ -20,193 +20,27 @@
*/
package org.apache.qpid.server.queue;
-import org.apache.qpid.AMQException;
-import org.apache.qpid.framing.ContentHeaderBody;
-import org.apache.qpid.server.store.StoreContext;
-import org.apache.qpid.server.subscription.Subscription;
-
-public class MockQueueEntry implements QueueEntry
+public class MockQueueEntry extends QueueEntryImpl
{
+ static SimpleQueueEntryList _defaultList = new SimpleQueueEntryList(new MockAMQQueue("MockQueueEntry_DefaultQueue"));
- private AMQMessage _message;
- private boolean _redelivered;
-
- public boolean acquire()
- {
- return false;
- }
-
- public boolean acquire(Subscription sub)
- {
- return false;
- }
-
- public boolean acquiredBySubscription()
- {
- return false;
- }
-
- public void addStateChangeListener(StateChangeListener listener)
- {
-
- }
-
- public String debugIdentity()
- {
- return null;
- }
-
- public boolean delete()
- {
- return false;
- }
-
- public void dequeue(StoreContext storeContext) throws FailedDequeueException
- {
-
- }
-
- public void discard(StoreContext storeContext) throws FailedDequeueException, MessageCleanupException
- {
-
- }
-
- public void dispose(StoreContext storeContext) throws MessageCleanupException
- {
-
- }
-
- public boolean expired() throws AMQException
- {
- return false;
- }
-
- public Subscription getDeliveredSubscription()
- {
- return null;
- }
-
- public boolean getDeliveredToConsumer()
- {
- return false;
- }
-
- public AMQMessage getMessage()
- {
- return _message;
- }
-
- public AMQQueue getQueue()
- {
- return null;
- }
-
- public long getSize()
- {
- return 0;
- }
-
- public boolean immediateAndNotDelivered()
- {
- return false;
- }
-
- public boolean isAcquired()
- {
- return false;
- }
-
- public boolean isDeleted()
- {
- return false;
- }
-
-
- public boolean isQueueDeleted()
- {
-
- return false;
- }
-
-
- public boolean isRejectedBy(Subscription subscription)
- {
-
- return false;
- }
-
-
- public void reject()
- {
-
-
- }
-
-
- public void reject(Subscription subscription)
- {
-
-
- }
-
-
- public void release()
- {
-
-
- }
-
-
- public boolean removeStateChangeListener(StateChangeListener listener)
- {
-
- return false;
- }
-
-
- public void requeue(StoreContext storeContext) throws AMQException
- {
-
-
- }
-
-
- public void setDeliveredToSubscription()
- {
-
-
- }
-
-
- public void setRedelivered(boolean redelivered)
- {
- _redelivered = redelivered;
- }
-
-
- public int compareTo(QueueEntry o)
- {
-
- return 0;
- }
-
- public void setMessage(AMQMessage msg)
+ public MockQueueEntry()
{
- _message = msg;
+ super(_defaultList);
}
- public ContentHeaderBody getContentHeaderBody() throws AMQException
+ public MockQueueEntry(SimpleQueueEntryList queueEntryList, AMQMessage message)
{
- return _message.getContentHeaderBody();
+ super(queueEntryList, message);
}
- public boolean isPersistent() throws AMQException
+ public MockQueueEntry(AMQMessage message)
{
- return _message.isPersistent();
+ super(_defaultList, message);
}
- public boolean isRedelivered()
+ public MockQueueEntry(AMQMessage message, SimpleAMQQueue queue)
{
- return _redelivered;
+ super(new SimpleQueueEntryList(queue) ,message);
}
}
diff --git a/qpid/java/broker/src/test/java/org/apache/qpid/server/queue/PersistentMessageTest.java b/qpid/java/broker/src/test/java/org/apache/qpid/server/queue/PersistentMessageTest.java
index fdaf2c309f..7a944a5399 100644
--- a/qpid/java/broker/src/test/java/org/apache/qpid/server/queue/PersistentMessageTest.java
+++ b/qpid/java/broker/src/test/java/org/apache/qpid/server/queue/PersistentMessageTest.java
@@ -20,18 +20,50 @@
*/
package org.apache.qpid.server.queue;
-import org.apache.qpid.server.store.MemoryMessageStore;
+import org.apache.qpid.AMQException;
+import org.apache.qpid.framing.AMQShortString;
+import org.apache.qpid.framing.BasicContentHeaderProperties;
+import org.apache.qpid.framing.ContentHeaderBody;
+import org.apache.qpid.framing.abstraction.MessagePublishInfo;
+import org.apache.qpid.framing.abstraction.MessagePublishInfoImpl;
+import org.apache.qpid.framing.amqp_8_0.BasicConsumeBodyImpl;
+import org.apache.qpid.server.RequiredDeliveryException;
+import org.apache.qpid.server.configuration.VirtualHostConfiguration;
import org.apache.qpid.server.store.StoreContext;
+import org.apache.qpid.server.store.TestableMemoryMessageStore;
+import org.apache.qpid.server.txn.NonTransactionalContext;
+import org.apache.qpid.server.txn.TransactionalContext;
+import org.apache.qpid.server.virtualhost.VirtualHost;
+import org.apache.commons.configuration.PropertiesConfiguration;
+
+import java.util.ArrayList;
+import java.util.LinkedList;
+import java.util.List;
public class PersistentMessageTest extends TransientMessageTest
{
- private MemoryMessageStore _messageStore;
+ private TestableMemoryMessageStore _messageStore;
+
+ protected SimpleAMQQueue _queue;
+ protected AMQShortString _q1name = new AMQShortString("q1name");
+ protected AMQShortString _owner = new AMQShortString("owner");
+ protected AMQShortString _routingKey = new AMQShortString("routing key");
+ private TransactionalContext _messageDeliveryContext;
+ private static final long MESSAGE_SIZE = 0L;
+ private List<RequiredDeliveryException> _returnMessages = new LinkedList<RequiredDeliveryException>();
- public void setUp()
+ public void setUp() throws Exception
{
- _messageStore = new MemoryMessageStore();
- _messageStore.configure();
+ _messageStore = new TestableMemoryMessageStore();
+
_storeContext = new StoreContext();
+ VirtualHost vhost = new VirtualHost(new VirtualHostConfiguration(PersistentMessageTest.class.getName(),
+ new PropertiesConfiguration()),
+ _messageStore);
+ _queue = (SimpleAMQQueue) AMQQueueFactory.createAMQQueueImpl(_q1name, false, _owner, false, vhost, null);
+ // Create IncomingMessage and nondurable queue
+ _messageDeliveryContext = new NonTransactionalContext(_messageStore, new StoreContext(), null, _returnMessages);
+
}
@Override
@@ -47,4 +79,86 @@ public class PersistentMessageTest extends TransientMessageTest
assertTrue(_message.isPersistent());
}
+ /**
+ * Tests the returning of a single persistent message to a queue. An immediate message is sent to the queue and
+ * checked that it bounced. The transactionlog and returnMessasges are then checked to ensure they have the right
+ * contents. TransactionLog = Empty, returnMessages 1 item.
+ *
+ * @throws Exception
+ */
+ public void testImmediateReturnNotInLog() throws Exception
+ {
+ MessagePublishInfo info = new MessagePublishInfoImpl(null, true, false, null);
+ IncomingMessage msg = createMessage(info);
+
+ // Send persistent message
+ ArrayList<AMQQueue> qs = new ArrayList<AMQQueue>();
+ qs.add(_queue);
+
+ // equivalent to amqChannel.routeMessage()
+ msg.enqueue(qs);
+
+ msg.routingComplete(_messageStore);
+
+ // equivalent to amqChannel.deliverCurrentMessageIfComplete
+ msg.deliverToQueues();
+
+ // Check that data has been stored to disk
+ long messageId = msg.getMessageId();
+ checkMessageMetaDataExists(messageId);
+
+ // Check that it was not enqueued
+ List<AMQQueue> queueList = _messageStore.getMessageReferenceMap(messageId);
+ assertNull("TransactionLog contains a queue reference for this messageID:" + messageId, queueList);
+ checkMessageMetaDataRemoved(messageId);
+
+ assertEquals("Return message count not correct", 1, _returnMessages.size());
+ }
+
+ protected IncomingMessage createMessage(MessagePublishInfo info) throws AMQException
+ {
+ IncomingMessage msg = new IncomingMessage(info, _messageDeliveryContext,
+ new MockProtocolSession(_messageStore), _messageStore);
+
+ // equivalent to amqChannel.publishContenHeader
+ ContentHeaderBody contentHeaderBody = new ContentHeaderBody();
+ contentHeaderBody.classId = BasicConsumeBodyImpl.CLASS_ID;
+ // This message has no bodies
+ contentHeaderBody.bodySize = MESSAGE_SIZE;
+ contentHeaderBody.properties = new BasicContentHeaderProperties();
+ ((BasicContentHeaderProperties) contentHeaderBody.properties).setDeliveryMode((byte) 2);
+
+ msg.setContentHeaderBody(contentHeaderBody);
+ msg.setExpiration();
+
+ return msg;
+ }
+
+ protected void checkMessageMetaDataExists(long messageId)
+ {
+ try
+ {
+ _messageStore.getMessageMetaData(_messageDeliveryContext.getStoreContext(), messageId);
+ }
+ catch (AMQException amqe)
+ {
+ fail("Message MetaData does not exist for message:" + messageId);
+ }
+ }
+
+ protected void checkMessageMetaDataRemoved(long messageId)
+ {
+ try
+ {
+ assertNull("Message MetaData still exists for message:" + messageId,
+ _messageStore.getMessageMetaData(_messageDeliveryContext.getStoreContext(), messageId));
+ assertNull("Message still has values in the reference map:" + messageId,
+ _messageStore.getMessageReferenceMap(messageId));
+
+ }
+ catch (AMQException e)
+ {
+ fail("AMQE thrown whilst trying to getMessageMetaData:" + e.getMessage());
+ }
+ }
}
diff --git a/qpid/java/broker/src/test/java/org/apache/qpid/server/queue/QueueEntryImplTest.java b/qpid/java/broker/src/test/java/org/apache/qpid/server/queue/QueueEntryImplTest.java
index f7cd860c22..75b0d0ab60 100644
--- a/qpid/java/broker/src/test/java/org/apache/qpid/server/queue/QueueEntryImplTest.java
+++ b/qpid/java/broker/src/test/java/org/apache/qpid/server/queue/QueueEntryImplTest.java
@@ -21,16 +21,22 @@
package org.apache.qpid.server.queue;
import junit.framework.TestCase;
+import org.apache.qpid.AMQException;
+import org.apache.qpid.framing.BasicContentHeaderProperties;
+import org.apache.qpid.framing.ContentHeaderBody;
+import org.apache.qpid.framing.abstraction.MessagePublishInfo;
+import org.apache.qpid.framing.abstraction.MessagePublishInfoImpl;
+
+import java.util.concurrent.locks.Condition;
+import java.util.concurrent.locks.ReentrantLock;
public class QueueEntryImplTest extends TestCase
{
- /**
- * Test the Redelivered state of a QueueEntryImpl
- */
+ /** Test the Redelivered state of a QueueEntryImpl */
public void testRedelivered()
{
- QueueEntry entry = new QueueEntryImpl(null, null);
+ QueueEntry entry = new MockQueueEntry(null);
assertFalse("New message should not be redelivered", entry.isRedelivered());
@@ -45,5 +51,186 @@ public class QueueEntryImplTest extends TestCase
}
+ public void testImmediateAndNotDelivered()
+ {
+ AMQMessage message = MessageFactory.getInstance().createMessage(null, false);
+
+ MessagePublishInfo mpi = new MessagePublishInfoImpl(null, true, false, null);
+ int bodySize = 0;
+
+ BasicContentHeaderProperties props = new BasicContentHeaderProperties();
+
+ props.setAppId("HandleTest");
+
+ ContentHeaderBody chb = new ContentHeaderBody(0, 0, props, bodySize);
+
+ try
+ {
+ message.setPublishAndContentHeaderBody(null, mpi, chb);
+
+ QueueEntry queueEntry = new MockQueueEntry(message);
+
+ assertTrue("Undelivered Immediate message should still be marked as so", queueEntry.immediateAndNotDelivered());
+
+ assertFalse("Undelivered Message should not say it is delivered.", queueEntry.getDeliveredToConsumer());
+
+ queueEntry.setDeliveredToSubscription();
+
+ assertTrue("Delivered Message should say it is delivered.", queueEntry.getDeliveredToConsumer());
+
+ assertFalse("Delivered Immediate message now be marked as so", queueEntry.immediateAndNotDelivered());
+ }
+ catch (AMQException e)
+ {
+ fail(e.getMessage());
+ }
+ }
+
+ public void testNotImmediateAndNotDelivered()
+ {
+ AMQMessage message = MessageFactory.getInstance().createMessage(null, false);
+
+ MessagePublishInfo mpi = new MessagePublishInfoImpl(null, false, false, null);
+ int bodySize = 0;
+
+ BasicContentHeaderProperties props = new BasicContentHeaderProperties();
+
+ props.setAppId("HandleTest");
+
+ ContentHeaderBody chb = new ContentHeaderBody(0, 0, props, bodySize);
+
+ try
+ {
+ message.setPublishAndContentHeaderBody(null, mpi, chb);
+
+ QueueEntry queueEntry = new MockQueueEntry(message);
+
+ assertFalse("Undelivered Non-Immediate message should not result in true.", queueEntry.immediateAndNotDelivered());
+
+ assertFalse("Undelivered Message should not say it is delivered.", queueEntry.getDeliveredToConsumer());
+
+ queueEntry.setDeliveredToSubscription();
+
+ assertTrue("Delivered Message should say it is delivered.", queueEntry.getDeliveredToConsumer());
+
+ assertFalse("Delivered Non-Immediate message not change this return", queueEntry.immediateAndNotDelivered());
+ }
+ catch (AMQException e)
+ {
+ fail(e.getMessage());
+ }
+ }
+
+ public void testExpiry()
+ {
+ AMQMessage message = MessageFactory.getInstance().createMessage(null, false);
+
+ MessagePublishInfo mpi = new MessagePublishInfoImpl(null, false, false, null);
+ int bodySize = 0;
+
+ BasicContentHeaderProperties props = new BasicContentHeaderProperties();
+
+ props.setAppId("HandleTest");
+
+ ContentHeaderBody chb = new ContentHeaderBody(0, 0, props, bodySize);
+
+ ReentrantLock waitLock = new ReentrantLock();
+ Condition wait = waitLock.newCondition();
+ try
+ {
+ message.setExpiration(System.currentTimeMillis() + 500L);
+
+ message.setPublishAndContentHeaderBody(null, mpi, chb);
+
+ QueueEntry queueEntry = new MockQueueEntry(message);
+
+ assertFalse("New messages should not be expired.", queueEntry.expired());
+
+ final long MILLIS = 1000000L;
+ long waitTime = 500 * MILLIS;
+
+ while (waitTime > 0)
+ {
+ try
+ {
+ waitLock.lock();
+
+ waitTime = wait.awaitNanos(waitTime);
+ }
+ catch (InterruptedException e)
+ {
+ //Stop if we are interrupted
+ fail(e.getMessage());
+ }
+ finally
+ {
+ waitLock.unlock();
+ }
+
+ }
+ assertTrue("After a sleep messages should now be expired.", queueEntry.expired());
+
+ }
+ catch (AMQException e)
+ {
+ fail(e.getMessage());
+ }
+ }
+
+ public void testNoExpiry()
+ {
+ AMQMessage message = MessageFactory.getInstance().createMessage(null, false);
+
+ MessagePublishInfo mpi = new MessagePublishInfoImpl(null, false, false, null);
+ int bodySize = 0;
+
+ BasicContentHeaderProperties props = new BasicContentHeaderProperties();
+
+ props.setAppId("HandleTest");
+
+ ContentHeaderBody chb = new ContentHeaderBody(0, 0, props, bodySize);
+
+ ReentrantLock waitLock = new ReentrantLock();
+ Condition wait = waitLock.newCondition();
+ try
+ {
+
+ message.setPublishAndContentHeaderBody(null, mpi, chb);
+
+ QueueEntry queueEntry = new MockQueueEntry(message);
+
+ assertFalse("New messages should not be expired.", queueEntry.expired());
+
+ final long MILLIS = 1000000L;
+ long waitTime = 10 * MILLIS;
+
+ while (waitTime > 0)
+ {
+ try
+ {
+ waitLock.lock();
+
+ waitTime = wait.awaitNanos(waitTime);
+ }
+ catch (InterruptedException e)
+ {
+ //Stop if we are interrupted
+ fail(e.getMessage());
+ }
+ finally
+ {
+ waitLock.unlock();
+ }
+
+ }
+
+ assertFalse("After a sleep messages without an expiry should not expire.", queueEntry.expired());
+
+ }
+ catch (AMQException e)
+ {
+ fail(e.getMessage());
+ }
+ }
}
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 98772e7b61..f39dfe765e 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
@@ -21,6 +21,7 @@ package org.apache.qpid.server.queue;
*/
import junit.framework.TestCase;
+import org.apache.commons.configuration.PropertiesConfiguration;
import org.apache.qpid.AMQException;
import org.apache.qpid.framing.AMQShortString;
import org.apache.qpid.framing.BasicContentHeaderProperties;
@@ -28,13 +29,17 @@ import org.apache.qpid.framing.ContentHeaderBody;
import org.apache.qpid.framing.FieldTable;
import org.apache.qpid.framing.abstraction.MessagePublishInfo;
import org.apache.qpid.framing.abstraction.MessagePublishInfoImpl;
+import org.apache.qpid.framing.amqp_8_0.BasicConsumeBodyImpl;
+import org.apache.qpid.server.configuration.VirtualHostConfiguration;
import org.apache.qpid.server.exchange.DirectExchange;
import org.apache.qpid.server.registry.ApplicationRegistry;
import org.apache.qpid.server.store.StoreContext;
+import org.apache.qpid.server.store.TestTransactionLog;
import org.apache.qpid.server.store.TestableMemoryMessageStore;
import org.apache.qpid.server.subscription.MockSubscription;
import org.apache.qpid.server.subscription.Subscription;
import org.apache.qpid.server.txn.NonTransactionalContext;
+import org.apache.qpid.server.txn.TransactionalContext;
import org.apache.qpid.server.virtualhost.VirtualHost;
import java.util.ArrayList;
@@ -45,7 +50,7 @@ public class SimpleAMQQueueTest extends TestCase
protected SimpleAMQQueue _queue;
protected VirtualHost _virtualHost;
- protected TestableMemoryMessageStore _store = new TestableMemoryMessageStore();
+ protected TestableMemoryMessageStore _transactionLog = new TestableMemoryMessageStore();
protected AMQShortString _qname = new AMQShortString("qname");
protected AMQShortString _owner = new AMQShortString("owner");
protected AMQShortString _routingKey = new AMQShortString("routing key");
@@ -54,7 +59,7 @@ public class SimpleAMQQueueTest extends TestCase
protected FieldTable _arguments = null;
MessagePublishInfo info = new MessagePublishInfoImpl();
- private static final long MESSAGE_SIZE = 100;
+ protected static long MESSAGE_SIZE = 100;
@Override
protected void setUp() throws Exception
@@ -63,7 +68,8 @@ public class SimpleAMQQueueTest extends TestCase
//Create Application Registry for test
ApplicationRegistry applicationRegistry = (ApplicationRegistry) ApplicationRegistry.getInstance(1);
- _virtualHost = new VirtualHost("vhost", _store);
+ PropertiesConfiguration env = new PropertiesConfiguration();
+ _virtualHost = new VirtualHost(new VirtualHostConfiguration(getClass().getSimpleName(), env), _transactionLog);
applicationRegistry.getVirtualHostRegistry().registerVirtualHost(_virtualHost);
_queue = (SimpleAMQQueue) AMQQueueFactory.createAMQQueueImpl(_qname, false, _owner, false, _virtualHost, _arguments);
@@ -291,7 +297,7 @@ public class SimpleAMQQueueTest extends TestCase
public void testGetLastFiveMessageIds() throws Exception
{
AMQMessage message = createMessage();
- Long messageIdOffset = message.getMessageId() -1 ;
+ Long messageIdOffset = message.getMessageId() - 1;
for (int i = 0; i < 10; i++)
{
// Put message on queue
@@ -313,8 +319,8 @@ public class SimpleAMQQueueTest extends TestCase
public void testEnqueueDequeueOfPersistentMessageToNonDurableQueue() throws AMQException
{
// Create IncomingMessage and nondurable queue
- NonTransactionalContext txnContext = new NonTransactionalContext(_store, null, null, null);
- IncomingMessage msg = new IncomingMessage(info, txnContext, null, _store);
+ NonTransactionalContext txnContext = new NonTransactionalContext(_transactionLog, null, null, null);
+ IncomingMessage msg = new IncomingMessage(info, txnContext, new MockProtocolSession(_transactionLog), _transactionLog);
ContentHeaderBody contentHeaderBody = new ContentHeaderBody();
contentHeaderBody.properties = new BasicContentHeaderProperties();
@@ -328,31 +334,184 @@ public class SimpleAMQQueueTest extends TestCase
// Send persistent message
qs.add(_queue);
msg.enqueue(qs);
- msg.routingComplete(_store);
+ msg.routingComplete(_transactionLog);
-
- _store.storeMessageMetaData(null, messageId, new MessageMetaData(info, contentHeaderBody, 1));
+ _transactionLog.storeMessageMetaData(null, messageId, new MessageMetaData(info, contentHeaderBody, 1));
// Check that it is enqueued
- AMQQueue data = _store.getMessages().get(messageId);
+ List<AMQQueue> data = _transactionLog.getMessageReferenceMap(messageId);
assertNotNull(data);
// Dequeue message
- MockQueueEntry entry = new MockQueueEntry();
-
ContentHeaderBody header = new ContentHeaderBody();
header.bodySize = MESSAGE_SIZE;
- AMQMessage message = new MockPersistentAMQMessage(msg.getMessageId(), _store);
+ AMQMessage message = new MockPersistentAMQMessage(msg.getMessageId(), _transactionLog);
message.setPublishAndContentHeaderBody(new StoreContext(), info, header);
- entry.setMessage(message);
- _queue.dequeue(null, entry);
+ MockQueueEntry entry = new MockQueueEntry(message, _queue);
+ entry.getQueueEntryList().add(message);
+ entry.acquire();
+ entry.dequeue(null);
// Check that it is dequeued
- data = _store.getMessages().get(messageId);
+ data = _transactionLog.getMessageReferenceMap(messageId);
assertNull(data);
}
+ public void testMessagesFlowToDisk() throws AMQException, InterruptedException
+ {
+ // Create IncomingMessage and nondurable queue
+ NonTransactionalContext txnContext = new NonTransactionalContext(_transactionLog, null, null, null);
+
+ MESSAGE_SIZE = 1;
+ long MEMORY_MAX = 500;
+ int MESSAGE_COUNT = (int) MEMORY_MAX * 2;
+ //Set the Memory Usage to be very low
+ _queue.setMemoryUsageMaximum(MEMORY_MAX);
+
+ for (int msgCount = 0; msgCount < MESSAGE_COUNT / 2; msgCount++)
+ {
+ sendMessage(txnContext);
+ }
+
+ //Check that we can hold 10 messages without flowing
+ assertEquals(MESSAGE_COUNT / 2, _queue.getMessageCount());
+ assertEquals(MEMORY_MAX, _queue.getMemoryUsageCurrent());
+ assertTrue("Queue is flowed.", !_queue.isFlowed());
+
+ // Send anothe and ensure we are flowed
+ sendMessage(txnContext);
+ assertEquals(MESSAGE_COUNT / 2 + 1, _queue.getMessageCount());
+ assertEquals(MESSAGE_COUNT / 2, _queue.getMemoryUsageCurrent());
+ assertTrue("Queue is not flowed.", _queue.isFlowed());
+
+ //send another 99 so there are 200msgs in total on the queue
+ for (int msgCount = 0; msgCount < (MESSAGE_COUNT / 2) - 1; msgCount++)
+ {
+ sendMessage(txnContext);
+
+ long usage = _queue.getMemoryUsageCurrent();
+ assertTrue("Queue has gone over quota:" + usage,
+ usage <= _queue.getMemoryUsageMaximum());
+
+ assertTrue("Queue has a negative quota:" + usage, usage > 0);
+
+ }
+ assertEquals(MESSAGE_COUNT, _queue.getMessageCount());
+ assertEquals(MEMORY_MAX, _queue.getMemoryUsageCurrent());
+ assertTrue("Queue is not flowed.", _queue.isFlowed());
+
+ _queue.registerSubscription(_subscription, false);
+
+ int slept = 0;
+ while (_subscription.getQueueEntries().size() != MESSAGE_COUNT && slept < 10)
+ {
+ Thread.sleep(500);
+ slept++;
+ }
+
+ //Ensure the messages are retreived
+ assertEquals("Not all messages were received, slept:" + slept / 2 + "s", MESSAGE_COUNT, _subscription.getQueueEntries().size());
+
+ //Check the queue is still within it's limits.
+ long current = _queue.getMemoryUsageCurrent();
+ assertTrue("Queue has gone over quota:" + current + "/" + _queue.getMemoryUsageMaximum(),
+ current <= _queue.getMemoryUsageMaximum());
+
+ assertTrue("Queue has a negative quota:" + _queue.getMemoryUsageCurrent(), _queue.getMemoryUsageCurrent() >= 0);
+
+ for (int index = 0; index < MESSAGE_COUNT; index++)
+ {
+ // Ensure that we have received the messages and it wasn't flushed to disk before we received it.
+ AMQMessage message = _subscription.getMessages().get(index);
+ assertNotNull("Message:" + message.debugIdentity() + " was null.", message);
+ }
+ }
+
+ public void testMessagesFlowToDiskPurger() throws AMQException, InterruptedException
+ {
+ // Create IncomingMessage and nondurable queue
+ NonTransactionalContext txnContext = new NonTransactionalContext(_transactionLog, null, null, null);
+
+ MESSAGE_SIZE = 1;
+ /** Set to larger than the purge batch size. Default 100.
+ * @see FlowableBaseQueueEntryList.BATCH_PROCESS_COUNT */
+ long MEMORY_MAX = 500;
+ int MESSAGE_COUNT = (int) MEMORY_MAX;
+ //Set the Memory Usage to be very low
+ _queue.setMemoryUsageMaximum(MEMORY_MAX);
+
+ for (int msgCount = 0; msgCount < MESSAGE_COUNT; msgCount++)
+ {
+ sendMessage(txnContext);
+ }
+
+ //Check that we can hold all messages without flowing
+ assertEquals(MESSAGE_COUNT, _queue.getMessageCount());
+ assertEquals(MEMORY_MAX, _queue.getMemoryUsageCurrent());
+ assertTrue("Queue is flowed.", !_queue.isFlowed());
+
+ // Send anothe and ensure we are flowed
+ sendMessage(txnContext);
+ assertEquals(MESSAGE_COUNT + 1, _queue.getMessageCount());
+ assertEquals(MESSAGE_COUNT, _queue.getMemoryUsageCurrent());
+ assertTrue("Queue is not flowed.", _queue.isFlowed());
+
+ _queue.setMemoryUsageMaximum(0L);
+
+ //Give the purger time to work maximum of 1s
+ int slept = 0;
+ while (_queue.getMemoryUsageCurrent() > 0 && slept < 5)
+ {
+ Thread.yield();
+ Thread.sleep(200);
+ slept++;
+ }
+
+ assertEquals(MESSAGE_COUNT + 1, _queue.getMessageCount());
+ assertEquals(0L, _queue.getMemoryUsageCurrent());
+ assertTrue("Queue is not flowed.", _queue.isFlowed());
+
+ }
+
+ protected void sendMessage(TransactionalContext txnContext) throws AMQException
+ {
+ sendMessage(txnContext, 5);
+ }
+
+ protected void sendMessage(TransactionalContext txnContext, int priority) throws AMQException
+ {
+ IncomingMessage msg = new IncomingMessage(info, txnContext, new MockProtocolSession(_transactionLog), _transactionLog);
+
+ ContentHeaderBody contentHeaderBody = new ContentHeaderBody();
+ contentHeaderBody.classId = BasicConsumeBodyImpl.CLASS_ID;
+ contentHeaderBody.bodySize = MESSAGE_SIZE;
+ contentHeaderBody.properties = new BasicContentHeaderProperties();
+ ((BasicContentHeaderProperties) contentHeaderBody.properties).setDeliveryMode((byte) 2);
+ ((BasicContentHeaderProperties) contentHeaderBody.properties).setPriority((byte) priority);
+ msg.setContentHeaderBody(contentHeaderBody);
+
+ long messageId = msg.getMessageId();
+
+ ArrayList<AMQQueue> qs = new ArrayList<AMQQueue>();
+
+ // Send persistent 10 messages
+
+ qs.add(_queue);
+ msg.enqueue(qs);
+
+ msg.routingComplete(_transactionLog);
+
+ msg.addContentBodyFrame(new MockContentChunk(1));
+
+ msg.deliverToQueues();
+
+ //Check message was correctly enqueued
+ List<AMQQueue> data = _transactionLog.getMessageReferenceMap(messageId);
+ assertNotNull(data);
+ }
+
+
// FIXME: move this to somewhere useful
private static AMQMessage createMessage(final MessagePublishInfo publishBody)
{
@@ -378,7 +537,7 @@ public class SimpleAMQQueueTest extends TestCase
public AMQMessage createMessage() throws AMQException
{
- AMQMessage message = new TestMessage(info);
+ AMQMessage message = new TestMessage(info, _transactionLog);
ContentHeaderBody header = new ContentHeaderBody();
header.bodySize = MESSAGE_SIZE;
@@ -394,29 +553,20 @@ public class SimpleAMQQueueTest extends TestCase
public class TestMessage extends TransientAMQMessage
{
private final long _tag;
- private int _count;
+ private TestTransactionLog _transactionLog;
- TestMessage(MessagePublishInfo publishBody)
+ TestMessage(MessagePublishInfo publishBody, TestTransactionLog transactionLog)
throws AMQException
{
super(SimpleAMQQueueTest.createMessage(publishBody));
_tag = getMessageId();
- }
-
- public boolean incrementReference()
- {
- _count++;
- return true;
- }
-
- public void decrementReference(StoreContext context)
- {
- _count--;
+ _transactionLog = transactionLog;
}
void assertCountEquals(int expected)
{
- assertEquals("Wrong count for message with tag " + _tag, expected, _count);
+ assertEquals("Wrong count for message with tag " + _tag, expected,
+ _transactionLog.getMessageReferenceMap(_messageId).size());
}
}
diff --git a/qpid/java/broker/src/test/java/org/apache/qpid/server/queue/SimpleAMQQueueThreadPoolTest.java b/qpid/java/broker/src/test/java/org/apache/qpid/server/queue/SimpleAMQQueueThreadPoolTest.java
deleted file mode 100644
index f45d887dec..0000000000
--- a/qpid/java/broker/src/test/java/org/apache/qpid/server/queue/SimpleAMQQueueThreadPoolTest.java
+++ /dev/null
@@ -1,60 +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.server.queue;
-
-import junit.framework.TestCase;
-import org.apache.qpid.framing.AMQShortString;
-import org.apache.qpid.pool.ReferenceCountingExecutorService;
-import org.apache.qpid.server.virtualhost.VirtualHost;
-
-import org.apache.qpid.server.registry.ApplicationRegistry;
-import org.apache.qpid.AMQException;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public class SimpleAMQQueueThreadPoolTest extends TestCase
-{
-
- public void test() throws AMQException
- {
- assertEquals("References exist before start!", 0, ReferenceCountingExecutorService.getInstance().getReferenceCount());
- VirtualHost test = ApplicationRegistry.getInstance(1).getVirtualHostRegistry().getVirtualHost("test");
-
- try
- {
- SimpleAMQQueue queue = (SimpleAMQQueue) AMQQueueFactory.createAMQQueueImpl(new AMQShortString("test"), false,
- new AMQShortString("owner"),
- false, test, null);
-
- assertFalse("Creation did not start Pool.", ReferenceCountingExecutorService.getInstance().getPool().isShutdown());
-
- queue.stop();
-
- assertEquals("References still exist", 0, ReferenceCountingExecutorService.getInstance().getReferenceCount());
-
- assertTrue("Stop did not clean up.", ReferenceCountingExecutorService.getInstance().getPool().isShutdown());
- }
- finally
- {
- ApplicationRegistry.remove(1);
- }
- }
-}
diff --git a/qpid/java/broker/src/test/java/org/apache/qpid/server/queue/TransientMessageTest.java b/qpid/java/broker/src/test/java/org/apache/qpid/server/queue/TransientMessageTest.java
index 16d1ab60f3..6fd153f398 100644
--- a/qpid/java/broker/src/test/java/org/apache/qpid/server/queue/TransientMessageTest.java
+++ b/qpid/java/broker/src/test/java/org/apache/qpid/server/queue/TransientMessageTest.java
@@ -287,180 +287,5 @@ public class TransientMessageTest extends TestCase
assertFalse(_message.isPersistent());
}
- public void testImmediateAndNotDelivered()
- {
- _message = newMessage();
-
- MessagePublishInfo mpi = new MessagePublishInfoImpl(null, true, false, null);
- int bodySize = 0;
-
- BasicContentHeaderProperties props = new BasicContentHeaderProperties();
-
- props.setAppId("HandleTest");
-
- ContentHeaderBody chb = new ContentHeaderBody(0, 0, props, bodySize);
-
- try
- {
- _message.setPublishAndContentHeaderBody(_storeContext, mpi, chb);
-
- assertTrue("Undelivered Immediate message should still be marked as so", _message.immediateAndNotDelivered());
-
- assertFalse("Undelivered Message should not say it is delivered.", _message.getDeliveredToConsumer());
-
- _message.setDeliveredToConsumer();
-
- assertTrue("Delivered Message should say it is delivered.", _message.getDeliveredToConsumer());
-
- assertFalse("Delivered Immediate message now be marked as so", _message.immediateAndNotDelivered());
- }
- catch (AMQException e)
- {
- fail(e.getMessage());
- }
- }
-
- public void testNotImmediateAndNotDelivered()
- {
- _message = newMessage();
-
- MessagePublishInfo mpi = new MessagePublishInfoImpl(null, false, false, null);
- int bodySize = 0;
-
- BasicContentHeaderProperties props = new BasicContentHeaderProperties();
-
- props.setAppId("HandleTest");
-
- ContentHeaderBody chb = new ContentHeaderBody(0, 0, props, bodySize);
-
- try
- {
- _message.setPublishAndContentHeaderBody(_storeContext, mpi, chb);
-
- assertFalse("Undelivered Non-Immediate message should not result in true.", _message.immediateAndNotDelivered());
-
- assertFalse("Undelivered Message should not say it is delivered.", _message.getDeliveredToConsumer());
-
- _message.setDeliveredToConsumer();
-
- assertTrue("Delivered Message should say it is delivered.", _message.getDeliveredToConsumer());
-
- assertFalse("Delivered Non-Immediate message not change this return", _message.immediateAndNotDelivered());
- }
- catch (AMQException e)
- {
- fail(e.getMessage());
- }
- }
-
- public void testExpiry()
- {
- _message = newMessage();
-
- MessagePublishInfo mpi = new MessagePublishInfoImpl(null, false, false, null);
- int bodySize = 0;
-
- BasicContentHeaderProperties props = new BasicContentHeaderProperties();
-
- props.setAppId("HandleTest");
-
- ContentHeaderBody chb = new ContentHeaderBody(0, 0, props, bodySize);
-
- ReentrantLock waitLock = new ReentrantLock();
- Condition wait = waitLock.newCondition();
- try
- {
- _message.setExpiration(System.currentTimeMillis() + 10L);
-
- _message.setPublishAndContentHeaderBody(_storeContext, mpi, chb);
-
- assertFalse("New messages should not be expired.", _message.expired());
-
- final long MILLIS =1000000L;
- long waitTime = 20 * MILLIS;
-
- while (waitTime > 0)
- {
- try
- {
- waitLock.lock();
-
- waitTime = wait.awaitNanos(waitTime);
- }
- catch (InterruptedException e)
- {
- //Stop if we are interrupted
- fail(e.getMessage());
- }
- finally
- {
- waitLock.unlock();
- }
-
- }
-
- assertTrue("After a sleep messages should now be expired.", _message.expired());
-
- }
- catch (AMQException e)
- {
- fail(e.getMessage());
- }
- }
-
-
- public void testNoExpiry()
- {
- _message = newMessage();
-
- MessagePublishInfo mpi = new MessagePublishInfoImpl(null, false, false, null);
- int bodySize = 0;
-
- BasicContentHeaderProperties props = new BasicContentHeaderProperties();
-
- props.setAppId("HandleTest");
-
- ContentHeaderBody chb = new ContentHeaderBody(0, 0, props, bodySize);
-
- ReentrantLock waitLock = new ReentrantLock();
- Condition wait = waitLock.newCondition();
- try
- {
-
- _message.setPublishAndContentHeaderBody(_storeContext, mpi, chb);
-
- assertFalse("New messages should not be expired.", _message.expired());
-
- final long MILLIS =1000000L;
- long waitTime = 10 * MILLIS;
-
- while (waitTime > 0)
- {
- try
- {
- waitLock.lock();
-
- waitTime = wait.awaitNanos(waitTime);
- }
- catch (InterruptedException e)
- {
- //Stop if we are interrupted
- fail(e.getMessage());
- }
- finally
- {
- waitLock.unlock();
- }
-
- }
-
- assertFalse("After a sleep messages without an expiry should not expire.", _message.expired());
-
- }
- catch (AMQException e)
- {
- fail(e.getMessage());
- }
- }
-
+
}
diff --git a/qpid/java/broker/src/test/java/org/apache/qpid/server/registry/ApplicationRegistryShutdownTest.java b/qpid/java/broker/src/test/java/org/apache/qpid/server/registry/ApplicationRegistryShutdownTest.java
index 03fcfc31e9..939e3436a5 100644
--- a/qpid/java/broker/src/test/java/org/apache/qpid/server/registry/ApplicationRegistryShutdownTest.java
+++ b/qpid/java/broker/src/test/java/org/apache/qpid/server/registry/ApplicationRegistryShutdownTest.java
@@ -39,7 +39,7 @@ public class ApplicationRegistryShutdownTest extends TestCase
ApplicationRegistry _registry;
- public void setUp()
+ public void setUp() throws Exception
{
_registry = new TestApplicationRegistry();
}
diff --git a/qpid/java/broker/src/test/java/org/apache/qpid/server/security/access/ACLManagerTest.java b/qpid/java/broker/src/test/java/org/apache/qpid/server/security/access/ACLManagerTest.java
index d12a0b1f1b..abcd9855d9 100644
--- a/qpid/java/broker/src/test/java/org/apache/qpid/server/security/access/ACLManagerTest.java
+++ b/qpid/java/broker/src/test/java/org/apache/qpid/server/security/access/ACLManagerTest.java
@@ -27,8 +27,11 @@ import java.io.FileWriter;
import junit.framework.TestCase;
import org.apache.commons.configuration.Configuration;
+import org.apache.commons.configuration.ConfigurationException;
import org.apache.commons.configuration.PropertiesConfiguration;
import org.apache.commons.configuration.XMLConfiguration;
+import org.apache.qpid.server.configuration.SecurityConfiguration;
+import org.apache.qpid.server.configuration.ServerConfiguration;
import org.apache.qpid.server.exchange.Exchange;
import org.apache.qpid.server.plugins.MockPluginManager;
import org.apache.qpid.server.plugins.PluginManager;
@@ -37,13 +40,14 @@ import org.apache.qpid.server.queue.AMQQueue;
import org.apache.qpid.server.queue.MockAMQQueue;
import org.apache.qpid.server.queue.MockProtocolSession;
import org.apache.qpid.server.store.TestableMemoryMessageStore;
+import org.apache.qpid.server.registry.ApplicationRegistry;
public class ACLManagerTest extends TestCase
{
private ACLManager _authzManager;
private AMQProtocolSession _session;
- private XMLConfiguration _conf;
+ private SecurityConfiguration _conf;
private PluginManager _pluginManager;
@Override
@@ -52,10 +56,10 @@ public class ACLManagerTest extends TestCase
File tmpFile = File.createTempFile(getClass().getName(), "testconfig");
tmpFile.deleteOnExit();
BufferedWriter out = new BufferedWriter(new FileWriter(tmpFile));
- out.write("<broker><security><queueDenier>notyet</queueDenier><exchangeDenier>yes</exchangeDenier></security></broker>");
+ out.write("<security><queueDenier>notyet</queueDenier><exchangeDenier>yes</exchangeDenier></security>");
out.close();
- _conf = new XMLConfiguration(tmpFile);
+ _conf = new SecurityConfiguration(new XMLConfiguration(tmpFile));
// Create ACLManager
@@ -64,6 +68,12 @@ public class ACLManagerTest extends TestCase
_session = new MockProtocolSession(new TestableMemoryMessageStore());
}
+
+ public void tearDown() throws Exception
+ {
+ //Ensure we close the registry that the MockAMQQueue will create
+ ApplicationRegistry.getInstance().close();
+ }
public void testACLManagerConfigurationPluginManager() throws Exception
{
@@ -77,7 +87,7 @@ public class ACLManagerTest extends TestCase
assertTrue(_authzManager.authorisePurge(_session, queue));
}
- public void testACLManagerConfigurationPluginManagerACLPlugin()
+ public void testACLManagerConfigurationPluginManagerACLPlugin() throws ConfigurationException
{
_authzManager = new ACLManager(_conf, _pluginManager, ExchangeDenier.FACTORY);
@@ -85,13 +95,12 @@ public class ACLManagerTest extends TestCase
assertFalse(_authzManager.authoriseDelete(_session, exchange));
}
- public void testConfigurePlugins()
+ public void testConfigurePlugins() throws ConfigurationException
{
Configuration hostConfig = new PropertiesConfiguration();
- hostConfig.setProperty("security.queueDenier", "thisoneneither");
- _authzManager.configureHostPlugins(hostConfig);
+ hostConfig.setProperty("queueDenier", "thisoneneither");
+ _authzManager.configureHostPlugins(new SecurityConfiguration(hostConfig));
AMQQueue queue = new MockAMQQueue("thisoneneither");
assertFalse(_authzManager.authoriseDelete(_session, queue));
}
-
}
diff --git a/qpid/java/broker/src/test/java/org/apache/qpid/server/security/access/PrincipalPermissionsTest.java b/qpid/java/broker/src/test/java/org/apache/qpid/server/security/access/PrincipalPermissionsTest.java
index bcbd83cde3..56a3783126 100644
--- a/qpid/java/broker/src/test/java/org/apache/qpid/server/security/access/PrincipalPermissionsTest.java
+++ b/qpid/java/broker/src/test/java/org/apache/qpid/server/security/access/PrincipalPermissionsTest.java
@@ -23,11 +23,13 @@ package org.apache.qpid.server.security.access;
import junit.framework.TestCase;
+import org.apache.commons.configuration.PropertiesConfiguration;
import org.apache.qpid.framing.AMQShortString;
import org.apache.qpid.framing.FieldTable;
import org.apache.qpid.framing.amqp_0_9.ExchangeDeclareBodyImpl;
import org.apache.qpid.framing.amqp_0_9.QueueDeclareBodyImpl;
import org.apache.qpid.framing.amqp_8_0.QueueBindBodyImpl;
+import org.apache.qpid.server.configuration.VirtualHostConfiguration;
import org.apache.qpid.server.exchange.DirectExchange;
import org.apache.qpid.server.queue.AMQQueue;
import org.apache.qpid.server.queue.AMQQueueFactory;
@@ -50,7 +52,6 @@ public class PrincipalPermissionsTest extends TestCase
private boolean _nowait = false;
private boolean _passive = false;
private boolean _durable = false;
- private boolean _exclusive = false;
private boolean _autoDelete = false;
private AMQShortString _exchangeType = new AMQShortString("direct");
private boolean _internal = false;
@@ -67,7 +68,8 @@ public class PrincipalPermissionsTest extends TestCase
_perms = new PrincipalPermissions(_user);
try
{
- _virtualHost = new VirtualHost("localhost", new SkeletonMessageStore());
+ PropertiesConfiguration env = new PropertiesConfiguration();
+ _virtualHost = new VirtualHost(new VirtualHostConfiguration("test", env));
_exchange = DirectExchange.TYPE.newInstance(_virtualHost, _exchangeName, _durable, _ticket, _autoDelete);
_queue = AMQQueueFactory.createAMQQueueImpl(_queueName, false, _owner , false, _virtualHost, _arguments);
}
diff --git a/qpid/java/broker/src/test/java/org/apache/qpid/server/security/access/management/AMQUserManagementMBeanTest.java b/qpid/java/broker/src/test/java/org/apache/qpid/server/security/access/management/AMQUserManagementMBeanTest.java
index f3c07d9eb2..958ee35476 100644
--- a/qpid/java/broker/src/test/java/org/apache/qpid/server/security/access/management/AMQUserManagementMBeanTest.java
+++ b/qpid/java/broker/src/test/java/org/apache/qpid/server/security/access/management/AMQUserManagementMBeanTest.java
@@ -21,103 +21,213 @@
package org.apache.qpid.server.security.access.management;
+import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
-import org.apache.qpid.server.security.auth.database.Base64MD5PasswordFilePrincipalDatabase;
+import javax.management.MalformedObjectNameException;
+import javax.management.ObjectName;
+
+import org.apache.commons.configuration.ConfigurationException;
+import org.apache.qpid.server.management.MBeanInvocationHandlerImpl;
+import org.apache.qpid.server.security.auth.database.PlainPasswordFilePrincipalDatabase;
import junit.framework.TestCase;
+/* Note: The main purpose is to test the jmx access rights file manipulation
+ * within AMQUserManagementMBean. The Principal Databases are tested by their own tests,
+ * this test just exercises their usage in AMQUserManagementMBean.
+ */
public class AMQUserManagementMBeanTest extends TestCase
{
- private Base64MD5PasswordFilePrincipalDatabase _database;
+ private PlainPasswordFilePrincipalDatabase _database;
private AMQUserManagementMBean _amqumMBean;
+
+ private File _passwordFile;
+ private File _accessFile;
- private static final String _QPID_HOME = System.getProperty("QPID_HOME");
-
- private static final String USERNAME = "testuser";
- private static final String PASSWORD = "password";
- private static final String JMXRIGHTS = "admin";
- private static final String TEMP_PASSWORD_FILE_NAME = "tempPasswordFile.tmp";
- private static final String TEMP_JMXACCESS_FILE_NAME = "tempJMXAccessFile.tmp";
+ private static final String TEST_USERNAME = "testuser";
+ private static final String TEST_PASSWORD = "password";
@Override
protected void setUp() throws Exception
{
- assertNotNull("QPID_HOME not set", _QPID_HOME);
-
- _database = new Base64MD5PasswordFilePrincipalDatabase();
+ _database = new PlainPasswordFilePrincipalDatabase();
_amqumMBean = new AMQUserManagementMBean();
+ loadFreshTestPasswordFile();
+ loadFreshTestAccessFile();
}
@Override
protected void tearDown() throws Exception
{
- File testFile = new File(_QPID_HOME + File.separator + TEMP_JMXACCESS_FILE_NAME + ".tmp");
- if (testFile.exists())
+ _passwordFile.delete();
+ _accessFile.delete();
+ }
+
+ public void testDeleteUser()
+ {
+ loadFreshTestPasswordFile();
+ loadFreshTestAccessFile();
+
+ //try deleting a non existant user
+ assertFalse(_amqumMBean.deleteUser("made.up.username"));
+
+ assertTrue(_amqumMBean.deleteUser(TEST_USERNAME));
+ }
+
+ public void testDeleteUserIsSavedToAccessFile()
+ {
+ loadFreshTestPasswordFile();
+ loadFreshTestAccessFile();
+
+ assertTrue(_amqumMBean.deleteUser(TEST_USERNAME));
+
+ //check the access rights were actually deleted from the file
+ try{
+ BufferedReader reader = new BufferedReader(new FileReader(_accessFile));
+
+ //check the 'generated by' comment line is present
+ assertTrue("File has no content", reader.ready());
+ assertTrue("'Generated by' comment line was missing",reader.readLine().contains("Generated by " +
+ "AMQUserManagementMBean Console : Last edited by user:"));
+
+ //there should also be a modified date/time comment line
+ assertTrue("File has no modified date/time comment line", reader.ready());
+ assertTrue("Modification date/time comment line was missing",reader.readLine().startsWith("#"));
+
+ //the access file should not contain any further data now as we just deleted the only user
+ assertFalse("User access data was present when it should have been deleted", reader.ready());
+ }
+ catch (IOException e)
{
- testFile.delete();
+ fail("Unable to valdate file contents due to:" + e.getMessage());
}
+
+ }
+
+ public void testSetRights()
+ {
+ loadFreshTestPasswordFile();
+ loadFreshTestAccessFile();
+
+ assertFalse(_amqumMBean.setRights("made.up.username", true, false, false));
+
+ assertTrue(_amqumMBean.setRights(TEST_USERNAME, true, false, false));
+ assertTrue(_amqumMBean.setRights(TEST_USERNAME, false, true, false));
+ assertTrue(_amqumMBean.setRights(TEST_USERNAME, false, false, true));
+ }
+
+ public void testSetRightsIsSavedToAccessFile()
+ {
+ loadFreshTestPasswordFile();
+ loadFreshTestAccessFile();
+
+ assertTrue(_amqumMBean.setRights(TEST_USERNAME, false, false, true));
+
+ //check the access rights were actually updated in the file
+ try{
+ BufferedReader reader = new BufferedReader(new FileReader(_accessFile));
+
+ //check the 'generated by' comment line is present
+ assertTrue("File has no content", reader.ready());
+ assertTrue("'Generated by' comment line was missing",reader.readLine().contains("Generated by " +
+ "AMQUserManagementMBean Console : Last edited by user:"));
- testFile = new File(_QPID_HOME + File.separator + TEMP_JMXACCESS_FILE_NAME + ".old");
- if (testFile.exists())
+ //there should also be a modified date/time comment line
+ assertTrue("File has no modified date/time comment line", reader.ready());
+ assertTrue("Modification date/time comment line was missing",reader.readLine().startsWith("#"));
+
+ //the access file should not contain any further data now as we just deleted the only user
+ assertTrue("User access data was not updated in the access file",
+ reader.readLine().equals(TEST_USERNAME + "=" + MBeanInvocationHandlerImpl.ADMIN));
+
+ //the access file should not contain any further data now as we just deleted the only user
+ assertFalse("Additional user access data was present when there should be no more", reader.ready());
+ }
+ catch (IOException e)
{
- testFile.delete();
+ fail("Unable to valdate file contents due to:" + e.getMessage());
}
+ }
- testFile = new File(_QPID_HOME + File.separator + TEMP_PASSWORD_FILE_NAME + ".tmp");
- if (testFile.exists())
+ public void testMBeanVersion()
+ {
+ try
{
- testFile.delete();
+ ObjectName name = _amqumMBean.getObjectName();
+ assertEquals(AMQUserManagementMBean.VERSION, Integer.parseInt(name.getKeyProperty("version")));
}
-
- testFile = new File(_QPID_HOME + File.separator + TEMP_PASSWORD_FILE_NAME + ".old");
- if (testFile.exists())
+ catch (MalformedObjectNameException e)
{
- testFile.delete();
+ fail(e.getMessage());
}
}
- public void testDeleteUser()
+ public void testSetAccessFileWithMissingFile()
{
- loadTestPasswordFile();
- loadTestAccessFile();
-
- boolean deleted = false;
+ try
+ {
+ _amqumMBean.setAccessFile("made.up.filename");
+ }
+ catch (IOException e)
+ {
+ fail("Should not have been an IOE." + e.getMessage());
+ }
+ catch (ConfigurationException e)
+ {
+ assertTrue(e.getMessage(), e.getMessage().endsWith("does not exist"));
+ }
+ }
+ public void testSetAccessFileWithReadOnlyFile()
+ {
+ File testFile = null;
try
{
- deleted = _amqumMBean.deleteUser(USERNAME);
+ testFile = File.createTempFile(this.getClass().getName(),".access.readonly");
+ BufferedWriter passwordWriter = new BufferedWriter(new FileWriter(testFile, false));
+ passwordWriter.write(TEST_USERNAME + ":" + TEST_PASSWORD);
+ passwordWriter.newLine();
+ passwordWriter.flush();
+ passwordWriter.close();
+
+ testFile.setReadOnly();
+ _amqumMBean.setAccessFile(testFile.getPath());
}
- catch(Exception e){
- fail("Unable to delete user: " + e.getMessage());
+ catch (IOException e)
+ {
+ fail("Access file was not created." + e.getMessage());
+ }
+ catch (ConfigurationException e)
+ {
+ fail("There should not have been a configuration exception." + e.getMessage());
}
- assertTrue(deleted);
+ testFile.delete();
}
-
-
+
// ============================ Utility methods =========================
- private void loadTestPasswordFile()
+ private void loadFreshTestPasswordFile()
{
try
{
- File tempPasswordFile = new File(_QPID_HOME + File.separator + TEMP_PASSWORD_FILE_NAME);
- if (tempPasswordFile.exists())
+ if(_passwordFile == null)
{
- tempPasswordFile.delete();
+ _passwordFile = File.createTempFile(this.getClass().getName(),".password");
}
- tempPasswordFile.deleteOnExit();
- BufferedWriter passwordWriter = new BufferedWriter(new FileWriter(tempPasswordFile));
- passwordWriter.write(USERNAME + ":" + PASSWORD);
+ BufferedWriter passwordWriter = new BufferedWriter(new FileWriter(_passwordFile, false));
+ passwordWriter.write(TEST_USERNAME + ":" + TEST_PASSWORD);
passwordWriter.newLine();
passwordWriter.flush();
-
- _database.setPasswordFile(tempPasswordFile.toString());
+ passwordWriter.close();
+ _database.setPasswordFile(_passwordFile.toString());
_amqumMBean.setPrincipalDatabase(_database);
}
catch (IOException e)
@@ -126,27 +236,36 @@ public class AMQUserManagementMBeanTest extends TestCase
}
}
- private void loadTestAccessFile()
+ private void loadFreshTestAccessFile()
{
try
{
- File tempAccessFile = new File(_QPID_HOME + File.separator + TEMP_JMXACCESS_FILE_NAME);
- if (tempAccessFile.exists())
+ if(_accessFile == null)
{
- tempAccessFile.delete();
+ _accessFile = File.createTempFile(this.getClass().getName(),".access");
}
- tempAccessFile.deleteOnExit();
-
- BufferedWriter accessWriter = new BufferedWriter(new FileWriter(tempAccessFile));
- accessWriter.write(USERNAME + "=" + JMXRIGHTS);
+
+ BufferedWriter accessWriter = new BufferedWriter(new FileWriter(_accessFile,false));
+ accessWriter.write("#Last Updated By comment");
+ accessWriter.newLine();
+ accessWriter.write("#Date/time comment");
+ accessWriter.newLine();
+ accessWriter.write(TEST_USERNAME + "=" + MBeanInvocationHandlerImpl.READONLY);
accessWriter.newLine();
accessWriter.flush();
+ accessWriter.close();
+ }
+ catch (IOException e)
+ {
+ fail("Unable to create test access file: " + e.getMessage());
+ }
- _amqumMBean.setAccessFile(tempAccessFile.toString());
+ try{
+ _amqumMBean.setAccessFile(_accessFile.toString());
}
catch (Exception e)
{
- fail("Unable to create test access file: " + e.getMessage());
+ fail("Unable to set access file: " + e.getMessage());
}
}
}
diff --git a/qpid/java/broker/src/test/java/org/apache/qpid/server/security/access/plugins/network/FirewallPluginTest.java b/qpid/java/broker/src/test/java/org/apache/qpid/server/security/access/plugins/network/FirewallPluginTest.java
index 8028362979..ff1fb8c97d 100644
--- a/qpid/java/broker/src/test/java/org/apache/qpid/server/security/access/plugins/network/FirewallPluginTest.java
+++ b/qpid/java/broker/src/test/java/org/apache/qpid/server/security/access/plugins/network/FirewallPluginTest.java
@@ -30,8 +30,10 @@ import java.net.InetSocketAddress;
import junit.framework.TestCase;
import org.apache.commons.configuration.ConfigurationException;
+import org.apache.commons.configuration.PropertiesConfiguration;
import org.apache.commons.configuration.XMLConfiguration;
import org.apache.qpid.codec.AMQCodecFactory;
+import org.apache.qpid.server.configuration.VirtualHostConfiguration;
import org.apache.qpid.server.protocol.AMQMinaProtocolSession;
import org.apache.qpid.server.protocol.TestIoSession;
import org.apache.qpid.server.security.access.ACLPlugin.AuthzResult;
@@ -87,7 +89,8 @@ public class FirewallPluginTest extends TestCase
public void setUp() throws Exception
{
_store = new TestableMemoryMessageStore();
- _virtualHost = new VirtualHost("vhost", _store);
+ PropertiesConfiguration env = new PropertiesConfiguration();
+ _virtualHost = new VirtualHost(new VirtualHostConfiguration("test", env));
TestIoSession iosession = new TestIoSession();
iosession.setAddress("127.0.0.1");
VirtualHostRegistry virtualHostRegistry = null;
diff --git a/qpid/java/broker/src/test/java/org/apache/qpid/server/security/auth/database/Base64MD5PasswordFilePrincipalDatabaseTest.java b/qpid/java/broker/src/test/java/org/apache/qpid/server/security/auth/database/Base64MD5PasswordFilePrincipalDatabaseTest.java
index b5034d9f5d..413b974986 100644
--- a/qpid/java/broker/src/test/java/org/apache/qpid/server/security/auth/database/Base64MD5PasswordFilePrincipalDatabaseTest.java
+++ b/qpid/java/broker/src/test/java/org/apache/qpid/server/security/auth/database/Base64MD5PasswordFilePrincipalDatabaseTest.java
@@ -22,8 +22,10 @@ package org.apache.qpid.server.security.auth.database;
import junit.framework.TestCase;
+import javax.security.auth.callback.PasswordCallback;
import javax.security.auth.login.AccountNotFoundException;
+import org.apache.commons.codec.binary.Base64;
import org.apache.qpid.server.security.auth.sasl.UsernamePrincipal;
import java.io.BufferedReader;
@@ -33,7 +35,9 @@ import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
+import java.io.UnsupportedEncodingException;
import java.security.Principal;
+import java.util.Arrays;
import java.util.List;
import java.util.regex.Pattern;
@@ -41,12 +45,38 @@ public class Base64MD5PasswordFilePrincipalDatabaseTest extends TestCase
{
private static final String TEST_COMMENT = "# Test Comment";
- private String USERNAME = "testUser";
- private String _username = this.getClass().getName()+"username";
- private char[] _password = "password".toCharArray();
- private Principal _principal = new UsernamePrincipal(_username);
+
+ private static final String USERNAME = "testUser";
+ private static final String PASSWORD = "guest";
+ private static final String PASSWORD_B64MD5HASHED = "CE4DQ6BIb/BVMN9scFyLtA==";
+ private static char[] PASSWORD_MD5_CHARS;
+ private static final String PRINCIPAL_USERNAME = "testUserPrincipal";
+ private static final Principal PRINCIPAL = new UsernamePrincipal(PRINCIPAL_USERNAME);
private Base64MD5PasswordFilePrincipalDatabase _database;
private File _pwdFile;
+
+ static
+ {
+ try
+ {
+ Base64 b64 = new Base64();
+ byte[] md5passBytes = PASSWORD_B64MD5HASHED.getBytes(Base64MD5PasswordFilePrincipalDatabase.DEFAULT_ENCODING);
+ byte[] decoded = b64.decode(md5passBytes);
+
+ PASSWORD_MD5_CHARS = new char[decoded.length];
+
+ int index = 0;
+ for (byte c : decoded)
+ {
+ PASSWORD_MD5_CHARS[index++] = (char) c;
+ }
+ }
+ catch (UnsupportedEncodingException e)
+ {
+ fail("Unable to perform B64 decode to get the md5 char[] password");
+ }
+ }
+
public void setUp() throws Exception
{
@@ -111,7 +141,56 @@ public class Base64MD5PasswordFilePrincipalDatabaseTest extends TestCase
loadPasswordFile(testFile);
- final String CREATED_PASSWORD = "createdPassword";
+
+ Principal principal = new Principal()
+ {
+ public String getName()
+ {
+ return USERNAME;
+ }
+ };
+
+ assertTrue("New user not created.", _database.createPrincipal(principal, PASSWORD.toCharArray()));
+
+ PasswordCallback callback = new PasswordCallback("prompt",false);
+ try
+ {
+ _database.setPassword(principal, callback);
+ }
+ catch (AccountNotFoundException e)
+ {
+ fail("user account did not exist");
+ }
+ assertTrue("Password returned was incorrect.", Arrays.equals(PASSWORD_MD5_CHARS, callback.getPassword()));
+
+ loadPasswordFile(testFile);
+
+ try
+ {
+ _database.setPassword(principal, callback);
+ }
+ catch (AccountNotFoundException e)
+ {
+ fail("user account did not exist");
+ }
+ assertTrue("Password returned was incorrect.", Arrays.equals(PASSWORD_MD5_CHARS, callback.getPassword()));
+
+ assertNotNull("Created User was not saved", _database.getUser(USERNAME));
+
+ assertFalse("Duplicate user created.", _database.createPrincipal(principal, PASSWORD.toCharArray()));
+
+ testFile.delete();
+ }
+
+ public void testCreatePrincipalIsSavedToFile()
+ {
+
+ File testFile = createPasswordFile(1, 0);
+
+ loadPasswordFile(testFile);
+
+ final String CREATED_PASSWORD = "guest";
+ final String CREATED_B64MD5HASHED_PASSWORD = "CE4DQ6BIb/BVMN9scFyLtA==";
final String CREATED_USERNAME = "createdUser";
Principal principal = new Principal()
@@ -122,16 +201,37 @@ public class Base64MD5PasswordFilePrincipalDatabaseTest extends TestCase
}
};
- assertTrue("New user not created.", _database.createPrincipal(principal, CREATED_PASSWORD.toCharArray()));
+ _database.createPrincipal(principal, CREATED_PASSWORD.toCharArray());
- loadPasswordFile(testFile);
+ try
+ {
+ BufferedReader reader = new BufferedReader(new FileReader(testFile));
+
+ assertTrue("File has no content", reader.ready());
+
+ assertEquals("Comment line has been corrupted.", TEST_COMMENT, reader.readLine());
- assertNotNull("Created User was not saved", _database.getUser(CREATED_USERNAME));
+ assertTrue("File is missing user data.", reader.ready());
- assertFalse("Duplicate user created.", _database.createPrincipal(principal, CREATED_PASSWORD.toCharArray()));
+ String userLine = reader.readLine();
+
+ String[] result = Pattern.compile(":").split(userLine);
+ assertEquals("User line not complete '" + userLine + "'", 2, result.length);
+
+ assertEquals("Username not correct,", CREATED_USERNAME, result[0]);
+ assertEquals("Password not correct,", CREATED_B64MD5HASHED_PASSWORD, result[1]);
+
+ assertFalse("File has more content", reader.ready());
+
+ }
+ catch (IOException e)
+ {
+ fail("Unable to valdate file contents due to:" + e.getMessage());
+ }
testFile.delete();
}
+
public void testDeletePrincipal()
{
@@ -228,8 +328,8 @@ public class Base64MD5PasswordFilePrincipalDatabaseTest extends TestCase
assertNotNull(testUser);
- String NEW_PASSWORD = "NewPassword";
- String NEW_PASSWORD_HASH = "TmV3UGFzc3dvcmQ=";
+ String NEW_PASSWORD = "guest";
+ String NEW_PASSWORD_HASH = "CE4DQ6BIb/BVMN9scFyLtA==";
try
{
_database.updatePassword(testUser, NEW_PASSWORD.toCharArray());
@@ -268,7 +368,7 @@ public class Base64MD5PasswordFilePrincipalDatabaseTest extends TestCase
testFile.delete();
}
- public void testSetPasswordWithMissingFile()
+ public void testSetPasswordFileWithMissingFile()
{
try
{
@@ -285,7 +385,7 @@ public class Base64MD5PasswordFilePrincipalDatabaseTest extends TestCase
}
- public void testSetPasswordWithReadOnlyFile()
+ public void testSetPasswordFileWithReadOnlyFile()
{
File testFile = createPasswordFile(0, 0);
@@ -310,28 +410,38 @@ public class Base64MD5PasswordFilePrincipalDatabaseTest extends TestCase
public void testCreateUserPrincipal() throws IOException
{
- _database.createPrincipal(_principal, _password);
- Principal newPrincipal = _database.getUser(_username);
+ _database.createPrincipal(PRINCIPAL, PASSWORD.toCharArray());
+ Principal newPrincipal = _database.getUser(PRINCIPAL_USERNAME);
assertNotNull(newPrincipal);
- assertEquals(_principal.getName(), newPrincipal.getName());
+ assertEquals(PRINCIPAL.getName(), newPrincipal.getName());
}
public void testVerifyPassword() throws IOException, AccountNotFoundException
{
testCreateUserPrincipal();
//assertFalse(_pwdDB.verifyPassword(_username, null));
- assertFalse(_database.verifyPassword(_username, new char[]{}));
- assertFalse(_database.verifyPassword(_username, "massword".toCharArray()));
- assertTrue(_database.verifyPassword(_username, _password));
+ assertFalse(_database.verifyPassword(PRINCIPAL_USERNAME, new char[]{}));
+ assertFalse(_database.verifyPassword(PRINCIPAL_USERNAME, (PASSWORD+"z").toCharArray()));
+ assertTrue(_database.verifyPassword(PRINCIPAL_USERNAME, PASSWORD.toCharArray()));
+
+ try
+ {
+ _database.verifyPassword("made.up.username", PASSWORD.toCharArray());
+ fail("Should not have been able to verify this non-existant users password.");
+ }
+ catch (AccountNotFoundException e)
+ {
+ // pass
+ }
}
public void testUpdatePassword() throws IOException, AccountNotFoundException
{
testCreateUserPrincipal();
char[] newPwd = "newpassword".toCharArray();
- _database.updatePassword(_principal, newPwd);
- assertFalse(_database.verifyPassword(_username, _password));
- assertTrue(_database.verifyPassword(_username, newPwd));
+ _database.updatePassword(PRINCIPAL, newPwd);
+ assertFalse(_database.verifyPassword(PRINCIPAL_USERNAME, PASSWORD.toCharArray()));
+ assertTrue(_database.verifyPassword(PRINCIPAL_USERNAME, newPwd));
}
-
+
}
diff --git a/qpid/java/broker/src/test/java/org/apache/qpid/server/security/auth/database/HashedUserTest.java b/qpid/java/broker/src/test/java/org/apache/qpid/server/security/auth/database/HashedUserTest.java
index a7d951cb5b..aa85cac758 100644
--- a/qpid/java/broker/src/test/java/org/apache/qpid/server/security/auth/database/HashedUserTest.java
+++ b/qpid/java/broker/src/test/java/org/apache/qpid/server/security/auth/database/HashedUserTest.java
@@ -34,7 +34,7 @@ public class HashedUserTest extends TestCase
String USERNAME = "username";
String PASSWORD = "password";
- String HASHED_PASSWORD = "cGFzc3dvcmQ=";
+ String B64_ENCODED_PASSWORD = "cGFzc3dvcmQ=";
public void testToLongArrayConstructor()
{
@@ -57,11 +57,11 @@ public class HashedUserTest extends TestCase
{
try
{
- HashedUser user = new HashedUser(new String[]{USERNAME, HASHED_PASSWORD});
+ HashedUser user = new HashedUser(new String[]{USERNAME, B64_ENCODED_PASSWORD});
assertEquals("Username incorrect", USERNAME, user.getName());
int index = 0;
- char[] hash = HASHED_PASSWORD.toCharArray();
+ char[] hash = B64_ENCODED_PASSWORD.toCharArray();
try
{
diff --git a/qpid/java/broker/src/test/java/org/apache/qpid/server/security/auth/database/PlainPasswordFilePrincipalDatabaseTest.java b/qpid/java/broker/src/test/java/org/apache/qpid/server/security/auth/database/PlainPasswordFilePrincipalDatabaseTest.java
new file mode 100644
index 0000000000..20b8d0a7b4
--- /dev/null
+++ b/qpid/java/broker/src/test/java/org/apache/qpid/server/security/auth/database/PlainPasswordFilePrincipalDatabaseTest.java
@@ -0,0 +1,396 @@
+/*
+ *
+ * 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.security.auth.database;
+
+import junit.framework.TestCase;
+
+import javax.security.auth.login.AccountNotFoundException;
+
+import org.apache.qpid.server.security.auth.sasl.UsernamePrincipal;
+
+import java.io.BufferedReader;
+import java.io.BufferedWriter;
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileReader;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.security.Principal;
+import java.util.List;
+import java.util.regex.Pattern;
+
+public class PlainPasswordFilePrincipalDatabaseTest extends TestCase
+{
+
+ private static final String TEST_COMMENT = "# Test Comment";
+ private static final String TEST_PASSWORD = "testPassword";
+ private static final char[] TEST_PASSWORD_CHARS = TEST_PASSWORD.toCharArray();
+ private static final String TEST_USERNAME = "testUser";
+
+ private Principal _principal = new UsernamePrincipal(TEST_USERNAME);
+ private PlainPasswordFilePrincipalDatabase _database;
+
+ public void setUp() throws Exception
+ {
+ _database = new PlainPasswordFilePrincipalDatabase();
+ }
+
+ // ******* Test Methods ********** //
+
+ public void testCreatePrincipal()
+ {
+ File testFile = createPasswordFile(1, 0);
+
+ loadPasswordFile(testFile);
+
+ final String CREATED_PASSWORD = "guest";
+ final String CREATED_USERNAME = "createdUser";
+
+ Principal principal = new Principal()
+ {
+ public String getName()
+ {
+ return CREATED_USERNAME;
+ }
+ };
+
+ assertTrue("New user not created.", _database.createPrincipal(principal, CREATED_PASSWORD.toCharArray()));
+
+ loadPasswordFile(testFile);
+
+ assertNotNull("Created User was not saved", _database.getUser(CREATED_USERNAME));
+
+ assertFalse("Duplicate user created.", _database.createPrincipal(principal, CREATED_PASSWORD.toCharArray()));
+
+ testFile.delete();
+ }
+
+ public void testCreatePrincipalIsSavedToFile()
+ {
+
+ File testFile = createPasswordFile(1, 0);
+
+ loadPasswordFile(testFile);
+
+ Principal principal = new Principal()
+ {
+ public String getName()
+ {
+ return TEST_USERNAME;
+ }
+ };
+
+ _database.createPrincipal(principal, TEST_PASSWORD_CHARS);
+
+ try
+ {
+ BufferedReader reader = new BufferedReader(new FileReader(testFile));
+
+ assertTrue("File has no content", reader.ready());
+
+ assertEquals("Comment line has been corrupted.", TEST_COMMENT, reader.readLine());
+
+ assertTrue("File is missing user data.", reader.ready());
+
+ String userLine = reader.readLine();
+
+ String[] result = Pattern.compile(":").split(userLine);
+
+ assertEquals("User line not complete '" + userLine + "'", 2, result.length);
+
+ assertEquals("Username not correct,", TEST_USERNAME, result[0]);
+ assertEquals("Password not correct,", TEST_PASSWORD, result[1]);
+
+ assertFalse("File has more content", reader.ready());
+
+ }
+ catch (IOException e)
+ {
+ fail("Unable to valdate file contents due to:" + e.getMessage());
+ }
+ testFile.delete();
+ }
+
+ public void testDeletePrincipal()
+ {
+ File testFile = createPasswordFile(1, 1);
+
+ loadPasswordFile(testFile);
+
+ Principal user = _database.getUser(TEST_USERNAME + "0");
+ assertNotNull("Generated user not present.", user);
+
+ try
+ {
+ _database.deletePrincipal(user);
+ }
+ catch (AccountNotFoundException e)
+ {
+ fail("User should be present" + e.getMessage());
+ }
+
+ try
+ {
+ _database.deletePrincipal(user);
+ fail("User should not be present");
+ }
+ catch (AccountNotFoundException e)
+ {
+ //pass
+ }
+
+ loadPasswordFile(testFile);
+
+ try
+ {
+ _database.deletePrincipal(user);
+ fail("User should not be present");
+ }
+ catch (AccountNotFoundException e)
+ {
+ //pass
+ }
+
+ assertNull("Deleted user still present.", _database.getUser(TEST_USERNAME + "0"));
+
+ testFile.delete();
+ }
+
+ public void testGetUsers()
+ {
+ int USER_COUNT = 10;
+ File testFile = createPasswordFile(1, USER_COUNT);
+
+ loadPasswordFile(testFile);
+
+ Principal user = _database.getUser("MISSING_USERNAME");
+ assertNull("Missing user present.", user);
+
+ List<Principal> users = _database.getUsers();
+
+ assertNotNull("Users list is null.", users);
+
+ assertEquals(USER_COUNT, users.size());
+
+ boolean[] verify = new boolean[USER_COUNT];
+ for (int i = 0; i < USER_COUNT; i++)
+ {
+ Principal principal = users.get(i);
+
+ assertNotNull("Generated user not present.", principal);
+
+ String name = principal.getName();
+
+ int id = Integer.parseInt(name.substring(TEST_USERNAME.length()));
+
+ assertFalse("Duplicated username retrieve", verify[id]);
+ verify[id] = true;
+ }
+
+ for (int i = 0; i < USER_COUNT; i++)
+ {
+ assertTrue("User " + i + " missing", verify[i]);
+ }
+
+ testFile.delete();
+ }
+
+ public void testUpdatePasswordIsSavedToFile()
+ {
+
+ File testFile = createPasswordFile(1, 1);
+
+ loadPasswordFile(testFile);
+
+ Principal testUser = _database.getUser(TEST_USERNAME + "0");
+
+ assertNotNull(testUser);
+
+ String NEW_PASSWORD = "NewPassword";
+ try
+ {
+ _database.updatePassword(testUser, NEW_PASSWORD.toCharArray());
+ }
+ catch (AccountNotFoundException e)
+ {
+ fail(e.toString());
+ }
+
+ try
+ {
+ BufferedReader reader = new BufferedReader(new FileReader(testFile));
+
+ assertTrue("File has no content", reader.ready());
+
+ assertEquals("Comment line has been corrupted.", TEST_COMMENT, reader.readLine());
+
+ assertTrue("File is missing user data.", reader.ready());
+
+ String userLine = reader.readLine();
+
+ String[] result = Pattern.compile(":").split(userLine);
+
+ assertEquals("User line not complete '" + userLine + "'", 2, result.length);
+
+ assertEquals("Username not correct,", TEST_USERNAME + "0", result[0]);
+ assertEquals("New Password not correct,", NEW_PASSWORD, result[1]);
+
+ assertFalse("File has more content", reader.ready());
+
+ }
+ catch (IOException e)
+ {
+ fail("Unable to valdate file contents due to:" + e.getMessage());
+ }
+ testFile.delete();
+ }
+
+ public void testSetPasswordFileWithMissingFile()
+ {
+ try
+ {
+ _database.setPasswordFile("DoesntExist");
+ }
+ catch (FileNotFoundException fnfe)
+ {
+ assertTrue(fnfe.getMessage(), fnfe.getMessage().startsWith("Cannot find password file"));
+ }
+ catch (IOException e)
+ {
+ fail("Password File was not created." + e.getMessage());
+ }
+
+ }
+
+ public void testSetPasswordFileWithReadOnlyFile()
+ {
+
+ File testFile = createPasswordFile(0, 0);
+
+ testFile.setReadOnly();
+
+ try
+ {
+ _database.setPasswordFile(testFile.toString());
+ }
+ catch (FileNotFoundException fnfe)
+ {
+ assertTrue(fnfe.getMessage().startsWith("Cannot read password file "));
+ }
+ catch (IOException e)
+ {
+ fail("Password File was not created." + e.getMessage());
+ }
+
+ testFile.delete();
+ }
+
+ private void createUserPrincipal() throws IOException
+ {
+ File testFile = createPasswordFile(0, 0);
+ loadPasswordFile(testFile);
+
+ _database.createPrincipal(_principal, TEST_PASSWORD_CHARS);
+ Principal newPrincipal = _database.getUser(TEST_USERNAME);
+ assertNotNull(newPrincipal);
+ assertEquals(_principal.getName(), newPrincipal.getName());
+ }
+
+ public void testVerifyPassword() throws IOException, AccountNotFoundException
+ {
+ createUserPrincipal();
+ assertFalse(_database.verifyPassword(TEST_USERNAME, new char[]{}));
+ assertFalse(_database.verifyPassword(TEST_USERNAME, "massword".toCharArray()));
+ assertTrue(_database.verifyPassword(TEST_USERNAME, TEST_PASSWORD_CHARS));
+
+ try
+ {
+ _database.verifyPassword("made.up.username", TEST_PASSWORD_CHARS);
+ fail("Should not have been able to verify this non-existant users password.");
+ }
+ catch (AccountNotFoundException e)
+ {
+ // pass
+ }
+ }
+
+ public void testUpdatePassword() throws IOException, AccountNotFoundException
+ {
+ createUserPrincipal();
+ char[] newPwd = "newpassword".toCharArray();
+ _database.updatePassword(_principal, newPwd);
+ assertFalse(_database.verifyPassword(TEST_USERNAME, TEST_PASSWORD_CHARS));
+ assertTrue(_database.verifyPassword(TEST_USERNAME, newPwd));
+ }
+
+
+
+ // *********** Utility Methods ******** //
+
+ private File createPasswordFile(int commentLines, int users)
+ {
+ try
+ {
+ File testFile = File.createTempFile(this.getClass().getName(),"tmp");
+ testFile.deleteOnExit();
+
+ BufferedWriter writer = new BufferedWriter(new FileWriter(testFile));
+
+ for (int i = 0; i < commentLines; i++)
+ {
+ writer.write(TEST_COMMENT);
+ writer.newLine();
+ }
+
+ for (int i = 0; i < users; i++)
+ {
+ writer.write(TEST_USERNAME + i + ":" + TEST_PASSWORD);
+ writer.newLine();
+ }
+
+ writer.flush();
+ writer.close();
+
+ return testFile;
+
+ }
+ catch (IOException e)
+ {
+ fail("Unable to create test password file." + e.getMessage());
+ }
+
+ return null;
+ }
+
+ private void loadPasswordFile(File file)
+ {
+ try
+ {
+ _database.setPasswordFile(file.toString());
+ }
+ catch (IOException e)
+ {
+ fail("Password File was not created." + e.getMessage());
+ }
+ }
+
+
+}
diff --git a/qpid/java/broker/src/test/java/org/apache/qpid/server/security/auth/database/PlainUserTest.java b/qpid/java/broker/src/test/java/org/apache/qpid/server/security/auth/database/PlainUserTest.java
new file mode 100644
index 0000000000..7f0843d46e
--- /dev/null
+++ b/qpid/java/broker/src/test/java/org/apache/qpid/server/security/auth/database/PlainUserTest.java
@@ -0,0 +1,78 @@
+/*
+ *
+ * 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.security.auth.database;
+
+import junit.framework.TestCase;
+
+/*
+ Note PlainUser is mainly tested by PlainPFPDTest, this is just to catch the extra methods
+ */
+public class PlainUserTest extends TestCase
+{
+
+ String USERNAME = "username";
+ String PASSWORD = "password";
+
+ public void testTooLongArrayConstructor()
+ {
+ try
+ {
+ PlainUser user = new PlainUser(new String[]{USERNAME, PASSWORD, USERNAME});
+ fail("Error expected");
+ }
+ catch (IllegalArgumentException e)
+ {
+ assertEquals("User Data should be length 2, username, password", e.getMessage());
+ }
+ }
+
+ public void testStringArrayConstructor()
+ {
+ PlainUser user = new PlainUser(new String[]{USERNAME, PASSWORD});
+ assertEquals("Username incorrect", USERNAME, user.getName());
+ int index = 0;
+
+ char[] password = PASSWORD.toCharArray();
+
+ try
+ {
+ for (byte c : user.getPasswordBytes())
+ {
+ assertEquals("Password incorrect", password[index], (char) c);
+ index++;
+ }
+ }
+ catch (Exception e)
+ {
+ fail(e.getMessage());
+ }
+
+ password = PASSWORD.toCharArray();
+
+ index=0;
+ for (char c : user.getPassword())
+ {
+ assertEquals("Password incorrect", password[index], c);
+ index++;
+ }
+ }
+}
+
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 7722eae116..33d8ac0160 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
@@ -21,6 +21,8 @@
package org.apache.qpid.server.store;
import junit.framework.TestCase;
+
+import org.apache.qpid.server.configuration.VirtualHostConfiguration;
import org.apache.qpid.server.exchange.DirectExchange;
import org.apache.qpid.server.exchange.Exchange;
import org.apache.qpid.server.exchange.ExchangeType;
@@ -102,7 +104,7 @@ public class MessageStoreTest extends TestCase
try
{
- _virtualHost = new VirtualHost(virtualHostName, configuration, null);
+ _virtualHost = new VirtualHost(new VirtualHostConfiguration(getClass().getName(), configuration));
ApplicationRegistry.getInstance().getVirtualHostRegistry().registerVirtualHost(_virtualHost);
}
catch (Exception 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 a5b65b527c..0a30d855b3 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
@@ -28,6 +28,7 @@ import org.apache.qpid.framing.abstraction.ContentChunk;
import org.apache.qpid.server.queue.MessageMetaData;
import org.apache.qpid.server.queue.AMQQueue;
import org.apache.qpid.server.virtualhost.VirtualHost;
+import org.apache.qpid.server.configuration.VirtualHostConfiguration;
import org.apache.qpid.server.exchange.Exchange;
import org.apache.qpid.server.transactionlog.TransactionLog;
import org.apache.qpid.server.routing.RoutingTable;
@@ -47,7 +48,7 @@ public class SkeletonMessageStore implements TransactionLog , RoutingTable
{
}
- public void configure(VirtualHost virtualHost, String base, Configuration config) throws Exception
+ public void configure(VirtualHost virtualHost, String base, VirtualHostConfiguration config) throws Exception
{
//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/TestReferenceCounting.java b/qpid/java/broker/src/test/java/org/apache/qpid/server/store/TestReferenceCounting.java
index 48d69c5bad..5a4c435e59 100644
--- a/qpid/java/broker/src/test/java/org/apache/qpid/server/store/TestReferenceCounting.java
+++ b/qpid/java/broker/src/test/java/org/apache/qpid/server/store/TestReferenceCounting.java
@@ -34,7 +34,7 @@ import org.apache.qpid.server.queue.AMQMessage;
*/
public class TestReferenceCounting extends TestCase
{
- private TestMemoryMessageStore _store;
+ private TestableMemoryMessageStore _store;
private StoreContext _storeContext = new StoreContext();
@@ -42,7 +42,7 @@ public class TestReferenceCounting extends TestCase
protected void setUp() throws Exception
{
super.setUp();
- _store = new TestMemoryMessageStore();
+ _store = new TestableMemoryMessageStore();
}
/**
@@ -54,19 +54,9 @@ public class TestReferenceCounting extends TestCase
MessagePublishInfo info = new MessagePublishInfoImpl();
- final long messageId = _store.getNewMessageId();
-
AMQMessage message = (MessageFactory.getInstance()).createMessage(_store, true);
message.setPublishAndContentHeaderBody(_storeContext, info, chb);
- message = message.takeReference();
-
- // we call routing complete to set up the handle
- // message.routingComplete(_store, _storeContext, new MessageHandleFactory());
-
-
- assertEquals(1, _store.getMessageMetaDataMap().size());
- message.decrementReference(_storeContext);
assertEquals(1, _store.getMessageMetaDataMap().size());
}
@@ -84,16 +74,10 @@ public class TestReferenceCounting extends TestCase
MessagePublishInfo info = new MessagePublishInfoImpl();
- final Long messageId = _store.getNewMessageId();
final ContentHeaderBody chb = createPersistentContentHeader();
AMQMessage message = (MessageFactory.getInstance()).createMessage(_store, true);
message.setPublishAndContentHeaderBody(_storeContext, info, chb);
- message = message.takeReference();
-
- assertEquals(1, _store.getMessageMetaDataMap().size());
- message = message.takeReference();
- message.decrementReference(_storeContext);
assertEquals(1, _store.getMessageMetaDataMap().size());
}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/management/ManagementConfiguration.java b/qpid/java/broker/src/test/java/org/apache/qpid/server/store/TestTransactionLog.java
index 042f626e8b..bb051693c3 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/management/ManagementConfiguration.java
+++ b/qpid/java/broker/src/test/java/org/apache/qpid/server/store/TestTransactionLog.java
@@ -7,9 +7,9 @@
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
- *
+ *
* http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
@@ -18,13 +18,14 @@
* under the License.
*
*/
-package org.apache.qpid.server.management;
+package org.apache.qpid.server.store;
+
+import org.apache.qpid.server.queue.AMQQueue;
-import org.apache.qpid.configuration.Configured;
+import java.util.Map;
+import java.util.List;
-public class ManagementConfiguration
+public interface TestTransactionLog
{
- @Configured(path = "management.enabled",
- defaultValue = "true")
- public boolean enabled;
+ public List<AMQQueue> getMessageReferenceMap(Long messageID);
}
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 9146fe88ae..456e816a52 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
@@ -23,22 +23,29 @@ package org.apache.qpid.server.store;
import org.apache.qpid.AMQException;
import org.apache.qpid.server.queue.AMQQueue;
import org.apache.qpid.server.queue.MessageMetaData;
-import org.apache.qpid.framing.ContentBody;
+import org.apache.qpid.server.routing.RoutingTable;
+import org.apache.qpid.server.transactionlog.TransactionLog;
+import org.apache.qpid.server.virtualhost.VirtualHost;
+import org.apache.qpid.server.exchange.Exchange;
+import org.apache.qpid.server.configuration.VirtualHostConfiguration;
import org.apache.qpid.framing.abstraction.ContentChunk;
+import org.apache.qpid.framing.AMQShortString;
+import org.apache.qpid.framing.FieldTable;
+import org.apache.commons.configuration.Configuration;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.HashMap;
import java.util.List;
+import java.util.Map;
/**
* Adds some extra methods to the memory message store for testing purposes.
*/
-public class TestableMemoryMessageStore extends MemoryMessageStore
+public class TestableMemoryMessageStore implements TestTransactionLog, TransactionLog, RoutingTable
{
MemoryMessageStore _mms = null;
- private HashMap<Long, AMQQueue> _messages = new HashMap<Long, AMQQueue>();
public TestableMemoryMessageStore(MemoryMessageStore mms)
{
@@ -47,46 +54,122 @@ public class TestableMemoryMessageStore extends MemoryMessageStore
public TestableMemoryMessageStore()
{
- _metaDataMap = new ConcurrentHashMap<Long, MessageMetaData>();
- _contentBodyMap = new ConcurrentHashMap<Long, List<ContentChunk>>();
+ _mms = new MemoryMessageStore();
+ _mms.configure();
}
public ConcurrentMap<Long, MessageMetaData> getMessageMetaDataMap()
{
- if (_mms != null)
- {
- return _mms._metaDataMap;
- }
- else
- {
- return _metaDataMap;
- }
+ return _mms._metaDataMap;
}
public ConcurrentMap<Long, List<ContentChunk>> getContentBodyMap()
{
- if (_mms != null)
- {
- return _mms._contentBodyMap;
- }
- else
- {
- return _contentBodyMap;
- }
+ return _mms._contentBodyMap;
}
-
- public void enqueueMessage(StoreContext context, final AMQQueue queue, Long messageId) throws AMQException
+
+ public List<AMQQueue> getMessageReferenceMap(Long messageId)
+ {
+ return _mms._messageEnqueueMap.get(messageId);
+ }
+
+ public void configure(VirtualHost virtualHost, String base, VirtualHostConfiguration config) throws Exception
+ {
+ _mms.configure(virtualHost,base,config);
+ }
+
+ public void close() throws Exception
+ {
+ _mms.close();
+ }
+
+ public void createExchange(Exchange exchange) throws AMQException
+ {
+ _mms.createExchange(exchange);
+ }
+
+ public void removeExchange(Exchange exchange) throws AMQException
+ {
+ _mms.removeExchange(exchange);
+ }
+
+ public void bindQueue(Exchange exchange, AMQShortString routingKey, AMQQueue queue, FieldTable args) throws AMQException
+ {
+ _mms.bindQueue(exchange,routingKey,queue,args);
+ }
+
+ public void unbindQueue(Exchange exchange, AMQShortString routingKey, AMQQueue queue, FieldTable args) throws AMQException
+ {
+ _mms.unbindQueue(exchange,routingKey,queue,args);
+ }
+
+ public void createQueue(AMQQueue queue) throws AMQException
+ {
+ _mms.createQueue(queue);
+ }
+
+ public void createQueue(AMQQueue queue, FieldTable arguments) throws AMQException
+ {
+ _mms.createQueue(queue,arguments);
+ }
+
+ public void removeQueue(AMQQueue queue) throws AMQException
+ {
+ _mms.removeQueue(queue);
+ }
+
+ public void enqueueMessage(StoreContext context, AMQQueue queue, Long messageId) throws AMQException
+ {
+ _mms.enqueueMessage(context,queue,messageId);
+ }
+
+ public void dequeueMessage(StoreContext context, AMQQueue queue, Long messageId) throws AMQException
+ {
+ _mms.dequeueMessage(context,queue,messageId);
+ }
+
+ public void beginTran(StoreContext context) throws AMQException
+ {
+ _mms.beginTran(context);
+ }
+
+ public void commitTran(StoreContext context) throws AMQException
+ {
+ _mms.commitTran(context);
+ }
+
+ public void abortTran(StoreContext context) throws AMQException
+ {
+ _mms.abortTran(context);
+ }
+
+ public boolean inTran(StoreContext context)
+ {
+ return _mms.inTran(context);
+ }
+
+ public void storeContentBodyChunk(StoreContext context, Long messageId, int index, ContentChunk contentBody, boolean lastContentBody) throws AMQException
+ {
+ _mms.storeContentBodyChunk(context,messageId,index,contentBody,lastContentBody);
+ }
+
+ public void storeMessageMetaData(StoreContext context, Long messageId, MessageMetaData messageMetaData) throws AMQException
+ {
+ _mms.storeMessageMetaData(context,messageId,messageMetaData);
+ }
+
+ public MessageMetaData getMessageMetaData(StoreContext context, Long messageId) throws AMQException
{
- getMessages().put(messageId, queue);
+ return _mms.getMessageMetaData(context,messageId);
}
- public void dequeueMessage(StoreContext context, final AMQQueue queue, Long messageId) throws AMQException
+ public ContentChunk getContentBodyChunk(StoreContext context, Long messageId, int index) throws AMQException
{
- getMessages().remove(messageId);
+ return _mms.getContentBodyChunk(context,messageId,index);
}
- public HashMap<Long, AMQQueue> getMessages()
+ public boolean isPersistent()
{
- return _messages;
+ return _mms.isPersistent();
}
}
diff --git a/qpid/java/broker/src/test/java/org/apache/qpid/server/subscription/MockSubscription.java b/qpid/java/broker/src/test/java/org/apache/qpid/server/subscription/MockSubscription.java
index 33fd669d5c..ab0870144b 100644
--- a/qpid/java/broker/src/test/java/org/apache/qpid/server/subscription/MockSubscription.java
+++ b/qpid/java/broker/src/test/java/org/apache/qpid/server/subscription/MockSubscription.java
@@ -30,10 +30,13 @@ import org.apache.qpid.framing.AMQShortString;
import org.apache.qpid.server.AMQChannel;
import org.apache.qpid.server.queue.AMQQueue;
import org.apache.qpid.server.queue.QueueEntry;
+import org.apache.qpid.server.queue.AMQMessage;
import org.apache.qpid.server.queue.QueueEntry.SubscriptionAcquiredState;
+import org.apache.log4j.Logger;
public class MockSubscription implements Subscription
{
+ private static final Logger _logger = Logger.getLogger(MockSubscription.class);
private boolean _closed = false;
private AMQShortString tag = new AMQShortString("mocktag");
@@ -41,8 +44,12 @@ public class MockSubscription implements Subscription
private StateListener _listener = null;
private QueueEntry lastSeen = null;
private State _state = State.ACTIVE;
- private ArrayList<QueueEntry> messages = new ArrayList<QueueEntry>();
+ private ArrayList<QueueEntry> _queueEntries = new ArrayList<QueueEntry>();
private final Lock _stateChangeLock = new ReentrantLock();
+ private ArrayList<AMQMessage> _messages = new ArrayList<AMQMessage>();
+
+
+
public void close()
{
@@ -136,10 +143,14 @@ public class MockSubscription implements Subscription
{
}
- public void send(QueueEntry msg) throws AMQException
+ public void send(QueueEntry entry) throws AMQException
{
- lastSeen = msg;
- messages.add(msg);
+ _logger.info("Sending Message(" + entry.debugIdentity() + ") to subscription:" + this);
+
+ lastSeen = entry;
+ _queueEntries.add(entry);
+ _messages.add(entry.getMessage());
+ entry.setDeliveredToSubscription();
}
public boolean setLastSeenEntry(QueueEntry expected, QueueEntry newValue)
@@ -173,8 +184,14 @@ public class MockSubscription implements Subscription
return false;
}
- public ArrayList<QueueEntry> getMessages()
+ public ArrayList<QueueEntry> getQueueEntries()
{
- return messages;
+ return _queueEntries;
}
+
+ public ArrayList<AMQMessage> getMessages()
+ {
+ return _messages;
+ }
+
}
diff --git a/qpid/java/broker/src/test/java/org/apache/qpid/server/txn/TxnBufferTest.java b/qpid/java/broker/src/test/java/org/apache/qpid/server/txn/TxnBufferTest.java
index ca6644d141..26802b4210 100644
--- a/qpid/java/broker/src/test/java/org/apache/qpid/server/txn/TxnBufferTest.java
+++ b/qpid/java/broker/src/test/java/org/apache/qpid/server/txn/TxnBufferTest.java
@@ -22,8 +22,8 @@ package org.apache.qpid.server.txn;
import junit.framework.TestCase;
import org.apache.qpid.AMQException;
-import org.apache.qpid.server.store.TestMemoryMessageStore;
import org.apache.qpid.server.store.StoreContext;
+import org.apache.qpid.server.store.TestableMemoryMessageStore;
import org.apache.qpid.server.transactionlog.TransactionLog;
import java.util.LinkedList;
@@ -194,7 +194,7 @@ public class TxnBufferTest extends TestCase
}
}
- class MockStore extends TestMemoryMessageStore
+ class MockStore extends TestableMemoryMessageStore
{
final Object BEGIN = "BEGIN";
final Object ABORT = "ABORT";
diff --git a/qpid/java/broker/src/test/java/org/apache/qpid/server/util/InternalBrokerBaseCase.java b/qpid/java/broker/src/test/java/org/apache/qpid/server/util/InternalBrokerBaseCase.java
index d150faf94a..cdc7eabf04 100644
--- a/qpid/java/broker/src/test/java/org/apache/qpid/server/util/InternalBrokerBaseCase.java
+++ b/qpid/java/broker/src/test/java/org/apache/qpid/server/util/InternalBrokerBaseCase.java
@@ -21,11 +21,14 @@
package org.apache.qpid.server.util;
import junit.framework.TestCase;
+
+import org.apache.commons.configuration.PropertiesConfiguration;
import org.apache.qpid.server.registry.ApplicationRegistry;
import org.apache.qpid.server.registry.IApplicationRegistry;
import org.apache.qpid.server.queue.AMQQueue;
import org.apache.qpid.server.queue.AMQQueueFactory;
import org.apache.qpid.framing.abstraction.MessagePublishInfoImpl;
+import org.apache.qpid.server.configuration.ServerConfiguration;
import org.apache.qpid.server.exchange.Exchange;
import org.apache.qpid.server.protocol.InternalTestProtocolSession;
import org.apache.qpid.server.AMQChannel;
@@ -58,7 +61,9 @@ public class InternalBrokerBaseCase extends TestCase
public void setUp() throws Exception
{
super.setUp();
- _registry = new TestApplicationRegistry();
+ PropertiesConfiguration configuration = new PropertiesConfiguration();
+ configuration.setProperty("virtualhosts.virtualhost.test.store.class", TestableMemoryMessageStore.class.getName());
+ _registry = new TestApplicationRegistry(new ServerConfiguration(configuration));
ApplicationRegistry.initialise(_registry);
_virtualHost = _registry.getVirtualHostRegistry().getVirtualHost("test");
diff --git a/qpid/java/broker/src/test/java/org/apache/qpid/server/util/TestApplicationRegistry.java b/qpid/java/broker/src/test/java/org/apache/qpid/server/util/TestApplicationRegistry.java
index 2605ed0d11..22bd3b5aab 100644
--- a/qpid/java/broker/src/test/java/org/apache/qpid/server/util/TestApplicationRegistry.java
+++ b/qpid/java/broker/src/test/java/org/apache/qpid/server/util/TestApplicationRegistry.java
@@ -20,7 +20,11 @@
*/
package org.apache.qpid.server.util;
+import org.apache.commons.configuration.ConfigurationException;
import org.apache.commons.configuration.MapConfiguration;
+import org.apache.commons.configuration.PropertiesConfiguration;
+import org.apache.qpid.server.configuration.ServerConfiguration;
+import org.apache.qpid.server.configuration.VirtualHostConfiguration;
import org.apache.qpid.server.exchange.ExchangeFactory;
import org.apache.qpid.server.exchange.ExchangeRegistry;
import org.apache.qpid.server.management.NoopManagedObjectRegistry;
@@ -52,9 +56,17 @@ public class TestApplicationRegistry extends ApplicationRegistry
private VirtualHost _vHost;
- public TestApplicationRegistry()
+ private ServerConfiguration _config;
+
+ public TestApplicationRegistry() throws ConfigurationException
+ {
+ super(new ServerConfiguration(new PropertiesConfiguration()));
+ }
+
+ public TestApplicationRegistry(ServerConfiguration config) throws ConfigurationException
{
- super(new MapConfiguration(new HashMap()));
+ super(config);
+ _config = config;
}
public void initialise() throws Exception
@@ -65,7 +77,7 @@ public class TestApplicationRegistry extends ApplicationRegistry
_databaseManager = new PropertiesPrincipalDatabaseManager("default", users);
- _accessManager = new ACLManager(_configuration, _pluginManager, AllowAll.FACTORY);
+ _accessManager = new ACLManager(_configuration.getSecurityConfiguration(), _pluginManager, AllowAll.FACTORY);
_authenticationManager = new PrincipalDatabaseAuthenticationManager(null, null);
@@ -75,7 +87,9 @@ public class TestApplicationRegistry extends ApplicationRegistry
_virtualHostRegistry = new VirtualHostRegistry();
- _vHost = new VirtualHost("test", _transactionLog);
+ PropertiesConfiguration vhostProps = new PropertiesConfiguration();
+ VirtualHostConfiguration hostConfig = new VirtualHostConfiguration("test", vhostProps);
+ _vHost = new VirtualHost(hostConfig, _transactionLog);
_virtualHostRegistry.registerVirtualHost(_vHost);
@@ -83,7 +97,6 @@ public class TestApplicationRegistry extends ApplicationRegistry
_exchangeFactory = _vHost.getExchangeFactory();
_exchangeRegistry = _vHost.getExchangeRegistry();
- _configuration.addProperty("heartbeat.delay", 10 * 60); // 10 minutes
}
public QueueRegistry getQueueRegistry()
diff --git a/qpid/java/broker/src/test/java/org/apache/qpid/server/virtualhost/VirtualhostInitRoutingTableFromTransactionLogTest.java b/qpid/java/broker/src/test/java/org/apache/qpid/server/virtualhost/VirtualhostInitRoutingTableFromTransactionLogTest.java
index ba19fd5d5e..1274b99880 100644
--- a/qpid/java/broker/src/test/java/org/apache/qpid/server/virtualhost/VirtualhostInitRoutingTableFromTransactionLogTest.java
+++ b/qpid/java/broker/src/test/java/org/apache/qpid/server/virtualhost/VirtualhostInitRoutingTableFromTransactionLogTest.java
@@ -22,6 +22,7 @@ package org.apache.qpid.server.virtualhost;
import junit.framework.TestCase;
import org.apache.commons.configuration.PropertiesConfiguration;
+import org.apache.qpid.server.configuration.VirtualHostConfiguration;
public class VirtualhostInitRoutingTableFromTransactionLogTest extends TestCase
{
@@ -35,7 +36,7 @@ public class VirtualhostInitRoutingTableFromTransactionLogTest extends TestCase
VirtualHost _virtualHost = null;
try
{
- _virtualHost = new VirtualHost("test", env);
+ _virtualHost = new VirtualHost(new VirtualHostConfiguration("test", env));
assertNotNull(_virtualHost.getTransactionLog());
assertNotNull(_virtualHost.getRoutingTable());
diff --git a/qpid/java/build.deps b/qpid/java/build.deps
index 7b06c379b3..d62e414639 100644
--- a/qpid/java/build.deps
+++ b/qpid/java/build.deps
@@ -1,9 +1,11 @@
backport-util-concurrent=lib/backport-util-concurrent-2.2.jar
+commons-beanutils-core=lib/commons-beanutils-core-1.8.0.jar
commons-cli=lib/commons-cli-1.0.jar
commons-codec=lib/commons-codec-1.3.jar
commons-collections=lib/commons-collections-3.2.jar
-commons-configuration=lib/commons-configuration-1.2.jar
+commons-configuration=lib/commons-configuration-1.6.jar
+commons-digester=lib/commons-digester-1.8.1.jar
commons-lang=lib/commons-lang-2.2.jar
commons-logging=lib/commons-logging-1.0.4.jar
commons-pool=lib/commons-pool-1.4.jar
@@ -71,7 +73,7 @@ geronimo-servlet=lib/geronimo-servlet_2.5_spec-1.2.jar
felix.libs=${osgi-core} ${felix-framework}
common.libs=${slf4j-api} ${backport-util-concurrent} ${mina-core} \
- ${mina-filter-ssl} ${commons-codec} ${commons-lang} ${commons-collections} \
+ ${mina-filter-ssl} ${commons-beanutils-core} ${commons-digester} ${commons-codec} ${commons-lang} ${commons-collections} \
${commons-configuration}
client.libs=${common.libs} ${geronimo-jms}
tools.libs=${client.libs}
@@ -90,7 +92,6 @@ integrationtests.libs=${systests.libs}
client-example.libs=${client.libs}
testkit.libs=${client.libs}
-
ibm-icu=lib/com.ibm.icu_3.8.1.v20080530.jar
ecl-core-jface=lib/org.eclipse.jface_3.4.1.M20080827-2000.jar
ecl-core-jface-databinding=lib/org.eclipse.jface.databinding_1.2.1.M20080827-0800a.jar
@@ -112,30 +113,41 @@ ecl-swt=lib/org.eclipse.swt_3.4.1.v3449c.jar
ecl-ui=lib/org.eclipse.ui_3.4.1.M20080910-0800.jar
ecl-ui-forms=lib/org.eclipse.ui.forms_3.3.101.v20080708_34x.jar
ecl-ui-workbench=lib/org.eclipse.ui.workbench_3.4.1.M20080827-0800a.jar
+apache-commons-codec=lib/org.apache.commons.codec_1.3.0.v20080530-1600.jar
ecl-swt-win32-win32-x86=lib/org.eclipse.swt.win32.win32.x86_3.4.1.v3449c.jar
ecl-equinox-launcher-win32-win32-x86=lib/org.eclipse.equinox.launcher.win32.win32.x86_1.0.101.R34x_v20080731/**
ecl-swt-linux-gtk-x86=lib/org.eclipse.swt.gtk.linux.x86_3.4.1.v3449c.jar
ecl-equinox-launcher-linux-gtk-x86=lib/org.eclipse.equinox.launcher.gtk.linux.x86_1.0.101.R34x_v20080805/**
+ecl-swt-linux-gtk-x86_64=lib/org.eclipse.swt.gtk.linux.x86_64_3.4.1.v3449c.jar
+ecl-equinox-launcher-linux-gtk-x86_64=lib/org.eclipse.equinox.launcher.gtk.linux.x86_64_1.0.101.R34x_v20080731/**
ecl-swt-macosx-carbon=lib/org.eclipse.swt.carbon.macosx_3.4.1.v3449c.jar
ecl-equinox-launcher-macosx-carbon=lib/org.eclipse.equinox.launcher.carbon.macosx_1.0.101.R34x_v20080731/**
+ecl-swt-solaris-gtk-sparc=lib/org.eclipse.swt.gtk.solaris.sparc_3.4.1.v3449c.jar
+ecl-equinox-launcher-solaris-gtk-sparc=lib/org.eclipse.equinox.launcher.gtk.solaris.sparc_1.0.101.R34x_v20080731/**
management-eclipse-plugin-win32-win32-x86.libs=${management-eclipse-plugin.core-libs} \
${ecl-swt-win32-win32-x86} ${ecl-equinox-launcher-win32-win32-x86}
management-eclipse-plugin-linux-gtk-x86.libs=${management-eclipse-plugin.core-libs} \
${ecl-swt-linux-gtk-x86} ${ecl-equinox-launcher-linux-gtk-x86}
+management-eclipse-plugin-linux-gtk-x86_64.libs=${management-eclipse-plugin.core-libs} \
+ ${ecl-swt-linux-gtk-x86_64} ${ecl-equinox-launcher-linux-gtk-x86_64}
management-eclipse-plugin-macosx.libs=${management-eclipse-plugin.core-libs} \
${ecl-swt-macosx-carbon} ${ecl-equinox-launcher-macosx-carbon}
+management-eclipse-plugin-solaris-gtk-sparc.libs=${management-eclipse-plugin.core-libs} \
+ ${ecl-swt-solaris-gtk-sparc} ${ecl-equinox-launcher-solaris-gtk-sparc}
management-eclipse-plugin.core-libs=${ibm-icu} ${ecl-core-jface} ${ecl-core-jface-databinding} \
${ecl-core-commands} ${ecl-core-contenttype} ${ecl-core-databinding} ${ecl-core-expressions} \
${ecl-core-jobs} ${ecl-core-runtime} ${ecl-core-runtime-compat-registry} ${ecl-equinox-app} \
${ecl-equinox-common} ${ecl-equinox-launcher} ${ecl-equinox-prefs} ${ecl-equinox-registry} \
- ${ecl-help} ${ecl-osgi} ${ecl-swt} ${ecl-ui} ${ecl-ui-forms} ${ecl-ui-workbench}
+ ${ecl-help} ${ecl-osgi} ${ecl-swt} ${ecl-ui} ${ecl-ui-forms} ${ecl-ui-workbench} ${apache-commons-codec}
management-eclipse-plugin.platform-libs=${ecl-equinox-launcher-win32-win32-x86} \
${ecl-equinox-launcher-linux-gtk-x86} ${ecl-equinox-launcher-macosx-carbon} \
- ${ecl-swt-win32-win32-x86} ${ecl-swt-linux-gtk-x86} ${ecl-swt-macosx-carbon}
+ ${ecl-swt-win32-win32-x86} ${ecl-swt-linux-gtk-x86} ${ecl-swt-macosx-carbon} \
+ ${ecl-swt-linux-gtk-x86_64} ${ecl-equinox-launcher-linux-gtk-x86_64} \
+ ${ecl-swt-solaris-gtk-sparc} ${ecl-equinox-launcher-solaris-gtk-sparc}
management-eclipse-plugin.libs=${management-eclipse-plugin.core-libs} ${management-eclipse-plugin.platform-libs}
diff --git a/qpid/java/client/example/bin/verify_all b/qpid/java/client/example/bin/verify_all
index 0212e7d819..3c8db42dcc 100644
--- a/qpid/java/client/example/bin/verify_all
+++ b/qpid/java/client/example/bin/verify_all
@@ -19,12 +19,13 @@
#
export QPID_SRC_HOME=$(cd "$(dirname $0)/../../../.."; pwd)
-export CPP=$QPID_SRC_HOME/cpp/examples/examples
+export CPP=$QPID_SRC_HOME/cpp/examples
export PYTHON=$QPID_SRC_HOME/python/examples
export JAVA=$QPID_SRC_HOME/java/client/example/src/main/java/org/apache/qpid/example/jmsexample
-export AMQP_SPEC=$QPID_SRC_HOME/specs/amqp.0-10.xml
+export AMQP_SPEC=$QPID_SRC_HOME/specs/amqp.0-10-qpid-errata.xml
export PYTHONPATH=$QPID_SRC_HOME/python/
+export LOG4J=file://$QPID_SRC_HOME/java/client/example/src/main/java/log4j.xml
trap cleanup EXIT
@@ -56,4 +57,3 @@ do
$verify $script
stop_broker
done
-
diff --git a/qpid/java/client/example/src/main/java/README.txt b/qpid/java/client/example/src/main/java/README.txt
index c8fe6a76ad..c9367b706d 100644
--- a/qpid/java/client/example/src/main/java/README.txt
+++ b/qpid/java/client/example/src/main/java/README.txt
@@ -13,5 +13,5 @@ QPID_SAMPLE
This is the parent directory of the directory in which you find the runSample.sh
(Ex:- $QPID_SRC_HOME/java/client/example/src/main)
-default: /usr/share/doc/rhm-0.2
+default: $PWD
diff --git a/qpid/java/client/example/src/main/java/org/apache/qpid/example/amqpexample/direct/Listener.java b/qpid/java/client/example/src/main/java/org/apache/qpid/example/amqpexample/direct/Listener.java
index 93bb097268..1ac3e85f7a 100755
--- a/qpid/java/client/example/src/main/java/org/apache/qpid/example/amqpexample/direct/Listener.java
+++ b/qpid/java/client/example/src/main/java/org/apache/qpid/example/amqpexample/direct/Listener.java
@@ -42,6 +42,8 @@ public class Listener implements SessionListener
public void opened(Session ssn) {}
+ public void resumed(Session ssn) {}
+
public void message(Session ssn, MessageTransfer xfr)
{
System.out.println("Message: " + xfr);
diff --git a/qpid/java/client/example/src/main/java/org/apache/qpid/example/amqpexample/fanout/Listener.java b/qpid/java/client/example/src/main/java/org/apache/qpid/example/amqpexample/fanout/Listener.java
index 4c72ce75a5..21f9c43cd2 100755
--- a/qpid/java/client/example/src/main/java/org/apache/qpid/example/amqpexample/fanout/Listener.java
+++ b/qpid/java/client/example/src/main/java/org/apache/qpid/example/amqpexample/fanout/Listener.java
@@ -42,6 +42,8 @@ public class Listener implements SessionListener
public void opened(Session ssn) {}
+ public void resumed(Session ssn) {}
+
public void message(Session ssn, MessageTransfer xfr)
{
System.out.println("Message: " + xfr);
diff --git a/qpid/java/client/example/src/main/java/org/apache/qpid/example/amqpexample/headers/Listener.java b/qpid/java/client/example/src/main/java/org/apache/qpid/example/amqpexample/headers/Listener.java
index aa1c9b0a41..dff49228a1 100644
--- a/qpid/java/client/example/src/main/java/org/apache/qpid/example/amqpexample/headers/Listener.java
+++ b/qpid/java/client/example/src/main/java/org/apache/qpid/example/amqpexample/headers/Listener.java
@@ -32,6 +32,8 @@ public class Listener implements SessionListener
public void opened(Session ssn) {}
+ public void resumed(Session ssn) {}
+
public void message(Session ssn, MessageTransfer xfr)
{
String body = xfr.getBodyString();
diff --git a/qpid/java/client/example/src/main/java/org/apache/qpid/example/amqpexample/lvq/Listener.java b/qpid/java/client/example/src/main/java/org/apache/qpid/example/amqpexample/lvq/Listener.java
index b930062813..e17d3eef9f 100644
--- a/qpid/java/client/example/src/main/java/org/apache/qpid/example/amqpexample/lvq/Listener.java
+++ b/qpid/java/client/example/src/main/java/org/apache/qpid/example/amqpexample/lvq/Listener.java
@@ -44,6 +44,8 @@ public class Listener implements SessionListener
public void opened(Session ssn) {}
+ public void resumed(Session ssn) {}
+
public void message(Session ssn, MessageTransfer xfr)
{
String body = xfr.getBodyString();
diff --git a/qpid/java/client/example/src/main/java/org/apache/qpid/example/amqpexample/pubsub/TopicListener.java b/qpid/java/client/example/src/main/java/org/apache/qpid/example/amqpexample/pubsub/TopicListener.java
index 5e6d3c6f69..dd9307ca84 100755
--- a/qpid/java/client/example/src/main/java/org/apache/qpid/example/amqpexample/pubsub/TopicListener.java
+++ b/qpid/java/client/example/src/main/java/org/apache/qpid/example/amqpexample/pubsub/TopicListener.java
@@ -40,6 +40,8 @@ public class TopicListener implements SessionListener
public void opened(Session ssn) {}
+ public void resumed(Session ssn) {}
+
public void message(Session ssn, MessageTransfer xfr)
{
DeliveryProperties dp = xfr.getHeader().get(DeliveryProperties.class);
diff --git a/qpid/java/client/example/src/main/java/org/apache/qpid/example/jmsexample/direct/verify b/qpid/java/client/example/src/main/java/org/apache/qpid/example/jmsexample/direct/verify
index 66b4b3c54e..7f81a3a57b 100644
--- a/qpid/java/client/example/src/main/java/org/apache/qpid/example/jmsexample/direct/verify
+++ b/qpid/java/client/example/src/main/java/org/apache/qpid/example/jmsexample/direct/verify
@@ -23,11 +23,11 @@ cpp=$CPP/direct
direct_consumer_java()
{
-java -Dlog4j.configuration=file://"$JAVA"/log4j.xml -cp "$CLASSPATH" org.apache.qpid.example.jmsexample.direct.Consumer
+java -Dlog4j.configuration=$LOG4J -cp "$CLASSPATH" org.apache.qpid.example.jmsexample.direct.Consumer
}
direct_producer_java(){
-java -Dlog4j.configuration=file://"$JAVA"/log4j.xml -cp "$CLASSPATH" org.apache.qpid.example.jmsexample.direct.Producer
+java -Dlog4j.configuration=$LOG4J -cp "$CLASSPATH" org.apache.qpid.example.jmsexample.direct.Producer
}
clients $cpp/declare_queues direct_producer_java direct_consumer_java
diff --git a/qpid/java/client/example/src/main/java/org/apache/qpid/example/jmsexample/direct/verify_cpp_java b/qpid/java/client/example/src/main/java/org/apache/qpid/example/jmsexample/direct/verify_cpp_java
index d581c4c1aa..a22162e075 100644
--- a/qpid/java/client/example/src/main/java/org/apache/qpid/example/jmsexample/direct/verify_cpp_java
+++ b/qpid/java/client/example/src/main/java/org/apache/qpid/example/jmsexample/direct/verify_cpp_java
@@ -2,7 +2,7 @@
cpp=$CPP/direct
direct_consumer_java(){
-java -Dlog4j.configuration=file://"$JAVA"/log4j.xml -cp "$CLASSPATH" org.apache.qpid.example.jmsexample.direct.Consumer
+java -Dlog4j.configuration=$LOG4J -cp "$CLASSPATH" org.apache.qpid.example.jmsexample.direct.Consumer
}
clients $cpp/declare_queues $cpp/direct_producer direct_consumer_java
diff --git a/qpid/java/client/example/src/main/java/org/apache/qpid/example/jmsexample/direct/verify_java_cpp b/qpid/java/client/example/src/main/java/org/apache/qpid/example/jmsexample/direct/verify_java_cpp
index 573cac6986..dc4b349808 100644
--- a/qpid/java/client/example/src/main/java/org/apache/qpid/example/jmsexample/direct/verify_java_cpp
+++ b/qpid/java/client/example/src/main/java/org/apache/qpid/example/jmsexample/direct/verify_java_cpp
@@ -2,7 +2,7 @@
cpp=$CPP/direct
direct_producer_java(){
-java -Dlog4j.configuration=file://"$JAVA"/log4j.xml -cp "$CLASSPATH" org.apache.qpid.example.jmsexample.direct.Producer
+java -Dlog4j.configuration=$LOG4J -cp "$CLASSPATH" org.apache.qpid.example.jmsexample.direct.Producer
}
clients $cpp/declare_queues direct_producer_java $cpp/listener
diff --git a/qpid/java/client/example/src/main/java/org/apache/qpid/example/jmsexample/direct/verify_java_python b/qpid/java/client/example/src/main/java/org/apache/qpid/example/jmsexample/direct/verify_java_python
index 61c033e969..befa34d650 100644
--- a/qpid/java/client/example/src/main/java/org/apache/qpid/example/jmsexample/direct/verify_java_python
+++ b/qpid/java/client/example/src/main/java/org/apache/qpid/example/jmsexample/direct/verify_java_python
@@ -1,8 +1,8 @@
# See https://svn.apache.org/repos/asf/incubator/qpid/trunk/qpid/bin/verify
-py=$PYTHON_EXAMPLES/direct
+py=$PYTHON/direct
direct_producer_java(){
-java -Dlog4j.configuration=file://"$JAVA"/log4j.xml -cp "$CLASSPATH" org.apache.qpid.example.jmsexample.direct.Producer
+java -Dlog4j.configuration=$LOG4J -cp "$CLASSPATH" org.apache.qpid.example.jmsexample.direct.Producer
}
clients $py/declare_queues.py direct_producer_java $py/direct_consumer.py
diff --git a/qpid/java/client/example/src/main/java/org/apache/qpid/example/jmsexample/direct/verify_python_java b/qpid/java/client/example/src/main/java/org/apache/qpid/example/jmsexample/direct/verify_python_java
index 4182331f3f..b22b44b9a6 100644
--- a/qpid/java/client/example/src/main/java/org/apache/qpid/example/jmsexample/direct/verify_python_java
+++ b/qpid/java/client/example/src/main/java/org/apache/qpid/example/jmsexample/direct/verify_python_java
@@ -1,8 +1,8 @@
# See https://svn.apache.org/repos/asf/incubator/qpid/trunk/qpid/bin/verify
-py=$PYTHON_EXAMPLES/direct
+py=$PYTHON/direct
direct_consumer_java(){
-java -Dlog4j.configuration=file://"$JAVA"/log4j.xml -cp "$CLASSPATH" org.apache.qpid.example.jmsexample.direct.Consumer
+java -Dlog4j.configuration=$LOG4J -cp "$CLASSPATH" org.apache.qpid.example.jmsexample.direct.Consumer
}
clients $py/declare_queues.py $py/direct_producer.py direct_consumer_java
diff --git a/qpid/java/client/example/src/main/java/org/apache/qpid/example/jmsexample/fanout/verify b/qpid/java/client/example/src/main/java/org/apache/qpid/example/jmsexample/fanout/verify
index 6617e37e85..98c866da99 100644
--- a/qpid/java/client/example/src/main/java/org/apache/qpid/example/jmsexample/fanout/verify
+++ b/qpid/java/client/example/src/main/java/org/apache/qpid/example/jmsexample/fanout/verify
@@ -22,11 +22,11 @@
cpp=$CPP/fanout
fanout_listener_java(){
-java -Dlog4j.configuration=file://"$JAVA"/log4j.xml -cp "$CLASSPATH" org.apache.qpid.example.jmsexample.fanout.Listener $1
+java -Dlog4j.configuration=$LOG4J -cp "$CLASSPATH" org.apache.qpid.example.jmsexample.fanout.Listener $1
}
fanout_producer_java(){
-java -Dlog4j.configuration=file://"$JAVA"/log4j.xml -cp "$CLASSPATH" org.apache.qpid.example.jmsexample.fanout.Producer
+java -Dlog4j.configuration=$LOG4J -cp "$CLASSPATH" org.apache.qpid.example.jmsexample.fanout.Producer
}
background "can receive messages" fanout_listener_java fanoutQueue1
diff --git a/qpid/java/client/example/src/main/java/org/apache/qpid/example/jmsexample/fanout/verify_cpp_java b/qpid/java/client/example/src/main/java/org/apache/qpid/example/jmsexample/fanout/verify_cpp_java
index de057ea3b1..ab8d37a0d8 100644
--- a/qpid/java/client/example/src/main/java/org/apache/qpid/example/jmsexample/fanout/verify_cpp_java
+++ b/qpid/java/client/example/src/main/java/org/apache/qpid/example/jmsexample/fanout/verify_cpp_java
@@ -3,7 +3,7 @@
cpp=$CPP/fanout
fanout_listener_java(){
-java -Dlog4j.configuration=file://"$JAVA"/log4j.xml -cp "$CLASSPATH" org.apache.qpid.example.jmsexample.fanout.Listener $1
+java -Dlog4j.configuration=$LOG4J -cp "$CLASSPATH" org.apache.qpid.example.jmsexample.fanout.Listener $1
}
background "can receive messages" fanout_listener_java fanoutQueue1
diff --git a/qpid/java/client/example/src/main/java/org/apache/qpid/example/jmsexample/fanout/verify_java_cpp b/qpid/java/client/example/src/main/java/org/apache/qpid/example/jmsexample/fanout/verify_java_cpp
index dab6114572..df923e6354 100644
--- a/qpid/java/client/example/src/main/java/org/apache/qpid/example/jmsexample/fanout/verify_java_cpp
+++ b/qpid/java/client/example/src/main/java/org/apache/qpid/example/jmsexample/fanout/verify_java_cpp
@@ -3,7 +3,7 @@
cpp=$CPP/fanout
fanout_producer_java(){
-java -Dlog4j.configuration=file://"$JAVA"/log4j.xml -cp "$CLASSPATH" org.apache.qpid.example.jmsexample.fanout.Producer
+java -Dlog4j.configuration=$LOG4J -cp "$CLASSPATH" org.apache.qpid.example.jmsexample.fanout.Producer
}
background "Listening" $cpp/listener
diff --git a/qpid/java/client/example/src/main/java/org/apache/qpid/example/jmsexample/fanout/verify_java_python b/qpid/java/client/example/src/main/java/org/apache/qpid/example/jmsexample/fanout/verify_java_python
index 1641d88354..5f8701882d 100644
--- a/qpid/java/client/example/src/main/java/org/apache/qpid/example/jmsexample/fanout/verify_java_python
+++ b/qpid/java/client/example/src/main/java/org/apache/qpid/example/jmsexample/fanout/verify_java_python
@@ -1,9 +1,9 @@
# See https://svn.apache.org/repos/asf/incubator/qpid/trunk/qpid/bin/verify
# The JMS producer doesn't create qeueues so utilising the c++ declare_queues
-py=$PYTHON_EXAMPLES/fanout
+py=$PYTHON/fanout
fanout_producer_java(){
-java -Dlog4j.configuration=file://"$JAVA"/log4j.xml -cp "$CLASSPATH" org.apache.qpid.example.jmsexample.fanout.Producer
+java -Dlog4j.configuration=$LOG4J -cp "$CLASSPATH" org.apache.qpid.example.jmsexample.fanout.Producer
}
background "Subscribed" $py/fanout_consumer.py
diff --git a/qpid/java/client/example/src/main/java/org/apache/qpid/example/jmsexample/fanout/verify_python_java b/qpid/java/client/example/src/main/java/org/apache/qpid/example/jmsexample/fanout/verify_python_java
index 0f05663985..72f263fd3d 100644
--- a/qpid/java/client/example/src/main/java/org/apache/qpid/example/jmsexample/fanout/verify_python_java
+++ b/qpid/java/client/example/src/main/java/org/apache/qpid/example/jmsexample/fanout/verify_python_java
@@ -1,9 +1,9 @@
# See https://svn.apache.org/repos/asf/incubator/qpid/trunk/qpid/bin/verify
# The JMS producer doesn't create qeueues so utilising the c++ declare_queues
-py=$PYTHON_EXAMPLES/fanout
+py=$PYTHON/fanout
fanout_listener_java(){
-java -Dlog4j.configuration=file://"$JAVA"/log4j.xml -cp "$CLASSPATH" org.apache.qpid.example.jmsexample.fanout.Listener $1
+java -Dlog4j.configuration=$LOG4J -cp "$CLASSPATH" org.apache.qpid.example.jmsexample.fanout.Listener $1
}
background "can receive messages" fanout_listener_java fanoutQueue1
diff --git a/qpid/java/client/example/src/main/java/org/apache/qpid/example/jmsexample/pubsub/verify b/qpid/java/client/example/src/main/java/org/apache/qpid/example/jmsexample/pubsub/verify
index 588a086752..363af252ad 100644
--- a/qpid/java/client/example/src/main/java/org/apache/qpid/example/jmsexample/pubsub/verify
+++ b/qpid/java/client/example/src/main/java/org/apache/qpid/example/jmsexample/pubsub/verify
@@ -21,11 +21,11 @@
cpp=$CPP/pub-sub
topic_listener_java(){
-java -Dlog4j.configuration=file://"$JAVA"/log4j.xml -cp "$CLASSPATH" org.apache.qpid.example.jmsexample.pubsub.Listener
+java -Dlog4j.configuration=$LOG4J -cp "$CLASSPATH" org.apache.qpid.example.jmsexample.pubsub.Listener
}
topic_publisher_java(){
-java -Dlog4j.configuration=file://"$JAVA"/log4j.xml -cp "$CLASSPATH" org.apache.qpid.example.jmsexample.pubsub.Publisher
+java -Dlog4j.configuration=$LOG4J -cp "$CLASSPATH" org.apache.qpid.example.jmsexample.pubsub.Publisher
}
background "can receive messages" topic_listener_java
diff --git a/qpid/java/client/example/src/main/java/org/apache/qpid/example/jmsexample/pubsub/verify_cpp_java b/qpid/java/client/example/src/main/java/org/apache/qpid/example/jmsexample/pubsub/verify_cpp_java
index 9276b3e21b..e73c164b77 100644
--- a/qpid/java/client/example/src/main/java/org/apache/qpid/example/jmsexample/pubsub/verify_cpp_java
+++ b/qpid/java/client/example/src/main/java/org/apache/qpid/example/jmsexample/pubsub/verify_cpp_java
@@ -2,7 +2,7 @@
cpp=$CPP/pub-sub
topic_listener_java(){
-java -Dlog4j.configuration=file://"$JAVA"/log4j.xml -cp "$CLASSPATH" org.apache.qpid.example.jmsexample.pubsub.Listener
+java -Dlog4j.configuration=$LOG4J -cp "$CLASSPATH" org.apache.qpid.example.jmsexample.pubsub.Listener
}
background "can receive messages" topic_listener_java
diff --git a/qpid/java/client/example/src/main/java/org/apache/qpid/example/jmsexample/pubsub/verify_java_cpp b/qpid/java/client/example/src/main/java/org/apache/qpid/example/jmsexample/pubsub/verify_java_cpp
index af22b3b82c..0b877566d3 100644
--- a/qpid/java/client/example/src/main/java/org/apache/qpid/example/jmsexample/pubsub/verify_java_cpp
+++ b/qpid/java/client/example/src/main/java/org/apache/qpid/example/jmsexample/pubsub/verify_java_cpp
@@ -2,7 +2,7 @@
cpp=$CPP/pub-sub
topic_publisher_java(){
-java -Dlog4j.configuration=file://"$JAVA"/log4j.xml -cp "$CLASSPATH" org.apache.qpid.example.jmsexample.pubsub.Publisher
+java -Dlog4j.configuration=$LOG4J -cp "$CLASSPATH" org.apache.qpid.example.jmsexample.pubsub.Publisher
}
background "Listening" $cpp/topic_listener
diff --git a/qpid/java/client/example/src/main/java/org/apache/qpid/example/jmsexample/pubsub/verify_java_python b/qpid/java/client/example/src/main/java/org/apache/qpid/example/jmsexample/pubsub/verify_java_python
index 3758e0f014..1340fe79eb 100644
--- a/qpid/java/client/example/src/main/java/org/apache/qpid/example/jmsexample/pubsub/verify_java_python
+++ b/qpid/java/client/example/src/main/java/org/apache/qpid/example/jmsexample/pubsub/verify_java_python
@@ -1,8 +1,8 @@
# See https://svn.apache.org/repos/asf/incubator/qpid/trunk/qpid/bin/verify
-py=$PYTHON_EXAMPLES/pubsub
+py=$PYTHON/pubsub
topic_publisher_java(){
-java -Dlog4j.configuration=file://"$JAVA"/log4j.xml -cp "$CLASSPATH" org.apache.qpid.example.jmsexample.pubsub.Publisher
+java -Dlog4j.configuration=$LOG4J -cp "$CLASSPATH" org.apache.qpid.example.jmsexample.pubsub.Publisher
}
background "Queues created" $py/topic_subscriber.py
diff --git a/qpid/java/client/example/src/main/java/org/apache/qpid/example/jmsexample/pubsub/verify_python_java b/qpid/java/client/example/src/main/java/org/apache/qpid/example/jmsexample/pubsub/verify_python_java
index c2b516f376..b7fba2b3e0 100644
--- a/qpid/java/client/example/src/main/java/org/apache/qpid/example/jmsexample/pubsub/verify_python_java
+++ b/qpid/java/client/example/src/main/java/org/apache/qpid/example/jmsexample/pubsub/verify_python_java
@@ -1,8 +1,8 @@
# See https://svn.apache.org/repos/asf/incubator/qpid/trunk/qpid/bin/verify
-py=$PYTHON_EXAMPLES/pubsub
+py=$PYTHON/pubsub
topic_listener_java(){
-java -Dlog4j.configuration=file://"$JAVA"/log4j.xml -cp "$CLASSPATH" org.apache.qpid.example.jmsexample.pubsub.Listener
+java -Dlog4j.configuration=$LOG4J -cp "$CLASSPATH" org.apache.qpid.example.jmsexample.pubsub.Listener
}
background "can receive messages" topic_listener_java
diff --git a/qpid/java/client/example/src/main/java/org/apache/qpid/example/jmsexample/requestResponse/verify b/qpid/java/client/example/src/main/java/org/apache/qpid/example/jmsexample/requestResponse/verify
index 79f22aa88a..c6caa7239e 100644
--- a/qpid/java/client/example/src/main/java/org/apache/qpid/example/jmsexample/requestResponse/verify
+++ b/qpid/java/client/example/src/main/java/org/apache/qpid/example/jmsexample/requestResponse/verify
@@ -21,11 +21,11 @@
cpp=$CPP/pub-sub
client_java(){
-java -Dlog4j.configuration=file://"$JAVA"/log4j.xml -cp "$CLASSPATH" org.apache.qpid.example.jmsexample.requestResponse.Client
+java -Dlog4j.configuration=$LOG4J -cp "$CLASSPATH" org.apache.qpid.example.jmsexample.requestResponse.Client
}
server_java(){
-java -Dlog4j.configuration=file://"$JAVA"/log4j.xml -cp "$CLASSPATH" org.apache.qpid.example.jmsexample.requestResponse.Server
+java -Dlog4j.configuration=$LOG4J -cp "$CLASSPATH" org.apache.qpid.example.jmsexample.requestResponse.Server
}
background "can receive messages" server_java
diff --git a/qpid/java/client/example/src/main/java/org/apache/qpid/example/jmsexample/requestResponse/verify_cpp_java b/qpid/java/client/example/src/main/java/org/apache/qpid/example/jmsexample/requestResponse/verify_cpp_java
index 6ef1b3b7e3..c0e788e373 100644
--- a/qpid/java/client/example/src/main/java/org/apache/qpid/example/jmsexample/requestResponse/verify_cpp_java
+++ b/qpid/java/client/example/src/main/java/org/apache/qpid/example/jmsexample/requestResponse/verify_cpp_java
@@ -3,7 +3,7 @@ cpp=$CPP/request-response
client_java()
{
-java -Dlog4j.configuration=file://"$JAVA"/log4j.xml -cp "$CLASSPATH" org.apache.qpid.example.jmsexample.requestResponse.Client
+java -Dlog4j.configuration=$LOG4J -cp "$CLASSPATH" org.apache.qpid.example.jmsexample.requestResponse.Client
}
background "Waiting" $cpp/server
diff --git a/qpid/java/client/example/src/main/java/org/apache/qpid/example/jmsexample/requestResponse/verify_java_cpp b/qpid/java/client/example/src/main/java/org/apache/qpid/example/jmsexample/requestResponse/verify_java_cpp
index a1c5aa325d..14a8c28000 100644
--- a/qpid/java/client/example/src/main/java/org/apache/qpid/example/jmsexample/requestResponse/verify_java_cpp
+++ b/qpid/java/client/example/src/main/java/org/apache/qpid/example/jmsexample/requestResponse/verify_java_cpp
@@ -2,7 +2,7 @@
cpp=$CPP/request-response
server_java(){
-java -Dlog4j.configuration=file://"$JAVA"/log4j.xml -cp "$CLASSPATH" org.apache.qpid.example.jmsexample.requestResponse.Server
+java -Dlog4j.configuration=$LOG4J -cp "$CLASSPATH" org.apache.qpid.example.jmsexample.requestResponse.Server
}
background "can receive messages" server_java
diff --git a/qpid/java/client/example/src/main/java/org/apache/qpid/example/jmsexample/requestResponse/verify_java_python b/qpid/java/client/example/src/main/java/org/apache/qpid/example/jmsexample/requestResponse/verify_java_python
index 0760952527..2d2ec2fc04 100644
--- a/qpid/java/client/example/src/main/java/org/apache/qpid/example/jmsexample/requestResponse/verify_java_python
+++ b/qpid/java/client/example/src/main/java/org/apache/qpid/example/jmsexample/requestResponse/verify_java_python
@@ -1,8 +1,8 @@
# See https://svn.apache.org/repos/asf/incubator/qpid/trunk/qpid/bin/verify
-py=$PYTHON_EXAMPLES/request-response
+py=$PYTHON/request-response
server_java(){
-java -Dlog4j.configuration=file://"$JAVA"/log4j.xml -cp "$CLASSPATH" org.apache.qpid.example.jmsexample.requestResponse.Server
+java -Dlog4j.configuration=$LOG4J -cp "$CLASSPATH" org.apache.qpid.example.jmsexample.requestResponse.Server
}
background "can receive messages" server_java
diff --git a/qpid/java/client/example/src/main/java/org/apache/qpid/example/jmsexample/requestResponse/verify_python_java b/qpid/java/client/example/src/main/java/org/apache/qpid/example/jmsexample/requestResponse/verify_python_java
index 6ea526e914..bcedf168e3 100644
--- a/qpid/java/client/example/src/main/java/org/apache/qpid/example/jmsexample/requestResponse/verify_python_java
+++ b/qpid/java/client/example/src/main/java/org/apache/qpid/example/jmsexample/requestResponse/verify_python_java
@@ -1,8 +1,8 @@
# See https://svn.apache.org/repos/asf/incubator/qpid/trunk/qpid/bin/verify
-py=$PYTHON_EXAMPLES/request-response
+py=$PYTHON/request-response
client_java(){
-java -Dlog4j.configuration=file://"$JAVA"/log4j.xml -cp "$CLASSPATH" org.apache.qpid.example.jmsexample.requestResponse.Client
+java -Dlog4j.configuration=$LOG4J -cp "$CLASSPATH" org.apache.qpid.example.jmsexample.requestResponse.Client
}
background "Request server running" $py/server.py
diff --git a/qpid/java/client/example/src/main/java/runSample.sh b/qpid/java/client/example/src/main/java/runSample.sh
index e330fb0c36..66338556a5 100755
--- a/qpid/java/client/example/src/main/java/runSample.sh
+++ b/qpid/java/client/example/src/main/java/runSample.sh
@@ -43,7 +43,7 @@ if test "'x$QPID_SAMPLE'" != "'x'"
then
QPID_SAMPLE=$QPID_SAMPLE
else
- QPID_SAMPLE="/usr/share/doc/rhm-0.2"
+ QPID_SAMPLE=$PWD
fi
echo "Using QPID_SAMPLE: $QPID_SAMPLE"
diff --git a/qpid/java/client/src/main/java/org/apache/qpid/client/AMQConnection.java b/qpid/java/client/src/main/java/org/apache/qpid/client/AMQConnection.java
index 6c9fcc0f4c..5c48d73e43 100644
--- a/qpid/java/client/src/main/java/org/apache/qpid/client/AMQConnection.java
+++ b/qpid/java/client/src/main/java/org/apache/qpid/client/AMQConnection.java
@@ -268,6 +268,13 @@ public class AMQConnection extends Closeable implements Connection, QueueConnect
//Indicates whether persistent messages are synchronized
private boolean _syncPersistence;
+ //Indicates whether we need to sync on every message ack
+ private boolean _syncAck;
+
+ //Indicates the sync publish options (persistent|all)
+ //By default it's async publish
+ private String _syncPublish = "";
+
/**
* @param broker brokerdetails
* @param username username
@@ -348,25 +355,53 @@ public class AMQConnection extends Closeable implements Connection, QueueConnect
public AMQConnection(ConnectionURL connectionURL, SSLConfiguration sslConfig) throws AMQException
{
// set this connection maxPrefetch
- if (connectionURL.getOption(ConnectionURL.AMQ_MAXPREFETCH) != null)
+ if (connectionURL.getOption(ConnectionURL.OPTIONS_MAXPREFETCH) != null)
{
- _maxPrefetch = Integer.parseInt(connectionURL.getOption(ConnectionURL.AMQ_MAXPREFETCH));
+ _maxPrefetch = Integer.parseInt(connectionURL.getOption(ConnectionURL.OPTIONS_MAXPREFETCH));
}
else
{
// use the defaul value set for all connections
_maxPrefetch = Integer.parseInt(System.getProperties().getProperty(ClientProperties.MAX_PREFETCH_PROP_NAME,
- ClientProperties.MAX_PREFETCH_DEFAULT));
+ ClientProperties.MAX_PREFETCH_DEFAULT));
}
- if (connectionURL.getOption(ConnectionURL.AMQ_SYNC_PERSISTENCE) != null)
+ if (connectionURL.getOption(ConnectionURL.OPTIONS_SYNC_PERSISTENCE) != null)
{
- _syncPersistence = Boolean.parseBoolean(connectionURL.getOption(ConnectionURL.AMQ_SYNC_PERSISTENCE));
+ _syncPersistence =
+ Boolean.parseBoolean(connectionURL.getOption(ConnectionURL.OPTIONS_SYNC_PERSISTENCE));
+ _logger.warn("sync_persistence is a deprecated property, " +
+ "please use sync_publish={persistent|all} instead");
}
else
{
// use the defaul value set for all connections
_syncPersistence = Boolean.getBoolean(ClientProperties.SYNC_PERSISTENT_PROP_NAME);
+ if (_syncPersistence)
+ {
+ _logger.warn("sync_persistence is a deprecated property, " +
+ "please use sync_publish={persistent|all} instead");
+ }
+ }
+
+ if (connectionURL.getOption(ConnectionURL.OPTIONS_SYNC_ACK) != null)
+ {
+ _syncAck = Boolean.parseBoolean(connectionURL.getOption(ConnectionURL.OPTIONS_SYNC_ACK));
+ }
+ else
+ {
+ // use the defaul value set for all connections
+ _syncAck = Boolean.getBoolean(ClientProperties.SYNC_ACK_PROP_NAME);
+ }
+
+ if (connectionURL.getOption(ConnectionURL.OPTIONS_SYNC_PUBLISH) != null)
+ {
+ _syncPublish = connectionURL.getOption(ConnectionURL.OPTIONS_SYNC_PUBLISH);
+ }
+ else
+ {
+ // use the defaul value set for all connections
+ _syncPublish = System.getProperty((ClientProperties.SYNC_ACK_PROP_NAME),_syncPublish);
}
_failoverPolicy = new FailoverPolicy(connectionURL, this);
@@ -1469,6 +1504,19 @@ public class AMQConnection extends Closeable implements Connection, QueueConnect
return _syncPersistence;
}
+ /**
+ * Indicates whether we need to sync on every message ack
+ */
+ public boolean getSyncAck()
+ {
+ return _syncAck;
+ }
+
+ public String getSyncPublish()
+ {
+ return _syncPublish;
+ }
+
public void setIdleTimeout(long l)
{
_delegate.setIdleTimeout(l);
diff --git a/qpid/java/client/src/main/java/org/apache/qpid/client/AMQConnectionDelegate_0_10.java b/qpid/java/client/src/main/java/org/apache/qpid/client/AMQConnectionDelegate_0_10.java
index 29f1aec2f5..c2fb05d94e 100644
--- a/qpid/java/client/src/main/java/org/apache/qpid/client/AMQConnectionDelegate_0_10.java
+++ b/qpid/java/client/src/main/java/org/apache/qpid/client/AMQConnectionDelegate_0_10.java
@@ -239,12 +239,6 @@ public class AMQConnectionDelegate_0_10 implements AMQConnectionDelegate, Connec
{
_conn.failoverPrep();
_qpidConnection.resume();
-
- if (_conn.firePreResubscribe())
- {
- _conn.resubscribeSessions();
- }
-
_conn.fireFailoverComplete();
return;
}
diff --git a/qpid/java/client/src/main/java/org/apache/qpid/client/AMQQueueBrowser.java b/qpid/java/client/src/main/java/org/apache/qpid/client/AMQQueueBrowser.java
index 08fd49286b..d96544adf8 100644
--- a/qpid/java/client/src/main/java/org/apache/qpid/client/AMQQueueBrowser.java
+++ b/qpid/java/client/src/main/java/org/apache/qpid/client/AMQQueueBrowser.java
@@ -22,14 +22,12 @@ package org.apache.qpid.client;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import org.apache.qpid.AMQException;
import javax.jms.IllegalStateException;
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.Queue;
import javax.jms.QueueBrowser;
-
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.concurrent.atomic.AtomicBoolean;
@@ -90,38 +88,11 @@ public class AMQQueueBrowser implements QueueBrowser
{
checkState();
final BasicMessageConsumer consumer =
- (BasicMessageConsumer) _session.createBrowserConsumer(_queue, _messageSelector, false);
+ (BasicMessageConsumer) _session.createBrowserConsumer(_queue, _messageSelector, false);
_consumers.add(consumer);
- return new Enumeration()
- {
-
- Message _nextMessage = consumer == null ? null : consumer.receive(1000);
-
- public boolean hasMoreElements()
- {
- _logger.info("QB:hasMoreElements:" + (_nextMessage != null));
- return (_nextMessage != null);
- }
-
- public Object nextElement()
- {
- Message msg = _nextMessage;
- try
- {
- _logger.info("QB:nextElement about to receive");
- _nextMessage = consumer.receive(1000);
- _logger.info("QB:nextElement received:" + _nextMessage);
- }
- catch (JMSException e)
- {
- _logger.warn("Exception caught while queue browsing", e);
- _nextMessage = null;
- }
- return msg;
- }
- };
+ return new QueueBrowserEnumeration(consumer);
}
public void close() throws JMSException
@@ -134,4 +105,39 @@ public class AMQQueueBrowser implements QueueBrowser
_consumers.clear();
}
+ private class QueueBrowserEnumeration implements Enumeration
+ {
+ Message _nextMessage;
+ private BasicMessageConsumer _consumer;
+
+ public QueueBrowserEnumeration(BasicMessageConsumer consumer) throws JMSException
+ {
+ _nextMessage = consumer == null ? null : consumer.receiveBrowse();
+ _logger.info("QB:created with first element:" + _nextMessage);
+ _consumer = consumer;
+ }
+
+ public boolean hasMoreElements()
+ {
+ _logger.info("QB:hasMoreElements:" + (_nextMessage != null));
+ return (_nextMessage != null);
+ }
+
+ public Object nextElement()
+ {
+ Message msg = _nextMessage;
+ try
+ {
+ _logger.info("QB:nextElement about to receive");
+ _nextMessage = _consumer.receiveBrowse();
+ _logger.info("QB:nextElement received:" + _nextMessage);
+ }
+ catch (JMSException e)
+ {
+ _logger.warn("Exception caught while queue browsing", e);
+ _nextMessage = null;
+ }
+ return msg;
+ }
+ }
}
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 733bee2d81..b632c56708 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
@@ -196,13 +196,13 @@ public abstract class AMQSession<C extends BasicMessageConsumer, P extends Basic
* The default value for immediate flag used by producers created by this session is false. That is, a consumer does
* not need to be attached to a queue.
*/
- protected static final boolean DEFAULT_IMMEDIATE = false;
+ protected static final boolean DEFAULT_IMMEDIATE = Boolean.parseBoolean(System.getProperty("qpid.default_immediate", "false"));
/**
* The default value for mandatory flag used by producers created by this session is true. That is, server will not
* silently drop messages where no queue is connected to the exchange for the message.
*/
- protected static final boolean DEFAULT_MANDATORY = true;
+ protected static final boolean DEFAULT_MANDATORY = Boolean.parseBoolean(System.getProperty("qpid.default_mandatory", "true"));
/** System property to enable strict AMQP compliance. */
public static final String STRICT_AMQP = "STRICT_AMQP";
@@ -575,12 +575,19 @@ public abstract class AMQSession<C extends BasicMessageConsumer, P extends Basic
public void bindQueue(final AMQShortString queueName, final AMQShortString routingKey, final FieldTable arguments,
final AMQShortString exchangeName, final AMQDestination destination) throws AMQException
{
+ bindQueue(queueName, routingKey, arguments, exchangeName, destination, false);
+ }
+
+ public void bindQueue(final AMQShortString queueName, final AMQShortString routingKey, final FieldTable arguments,
+ final AMQShortString exchangeName, final AMQDestination destination,
+ final boolean nowait) throws AMQException
+ {
/*new FailoverRetrySupport<Object, AMQException>(new FailoverProtectedOperation<Object, AMQException>()*/
new FailoverNoopSupport<Object, AMQException>(new FailoverProtectedOperation<Object, AMQException>()
{
public Object execute() throws AMQException, FailoverException
{
- sendQueueBind(queueName, routingKey, arguments, exchangeName, destination);
+ sendQueueBind(queueName, routingKey, arguments, exchangeName, destination, nowait);
return null;
}
}, _connection).execute();
@@ -595,7 +602,8 @@ public abstract class AMQSession<C extends BasicMessageConsumer, P extends Basic
}
public abstract void sendQueueBind(final AMQShortString queueName, final AMQShortString routingKey, final FieldTable arguments,
- final AMQShortString exchangeName, AMQDestination destination) throws AMQException, FailoverException;
+ final AMQShortString exchangeName, AMQDestination destination,
+ final boolean nowait) throws AMQException, FailoverException;
/**
* Closes the session.
@@ -1007,6 +1015,7 @@ public abstract class AMQSession<C extends BasicMessageConsumer, P extends Basic
}
catch (URISyntaxException urlse)
{
+ _logger.error("", urlse);
JMSException jmse = new JMSException(urlse.getReason());
jmse.setLinkedException(urlse);
@@ -1815,6 +1824,11 @@ public abstract class AMQSession<C extends BasicMessageConsumer, P extends Basic
void failoverPrep()
{
startDispatcherIfNecessary();
+ syncDispatchQueue();
+ }
+
+ void syncDispatchQueue()
+ {
final CountDownLatch signal = new CountDownLatch(1);
_queue.add(new Dispatchable() {
public void dispatch(AMQSession ssn)
@@ -1828,7 +1842,7 @@ public abstract class AMQSession<C extends BasicMessageConsumer, P extends Basic
}
catch (InterruptedException e)
{
- // pass
+ throw new RuntimeException(e);
}
}
@@ -1859,6 +1873,11 @@ public abstract class AMQSession<C extends BasicMessageConsumer, P extends Basic
_inRecovery = inRecovery;
}
+ boolean isStarted()
+ {
+ return _startedAtLeastOnce.get();
+ }
+
/**
* Starts the session, which ensures that it is not suspended and that its event dispatcher is running.
*
@@ -2281,7 +2300,13 @@ public abstract class AMQSession<C extends BasicMessageConsumer, P extends Basic
* @todo Be aware of possible changes to parameter order as versions change.
*/
protected AMQShortString declareQueue(final AMQDestination amqd, final AMQProtocolHandler protocolHandler,
- final boolean noLocal)
+ final boolean noLocal) throws AMQException
+ {
+ return declareQueue(amqd, protocolHandler, noLocal, false);
+ }
+
+ protected AMQShortString declareQueue(final AMQDestination amqd, final AMQProtocolHandler protocolHandler,
+ final boolean noLocal, final boolean nowait)
throws AMQException
{
/*return new FailoverRetrySupport<AMQShortString, AMQException>(*/
@@ -2296,14 +2321,15 @@ public abstract class AMQSession<C extends BasicMessageConsumer, P extends Basic
amqd.setQueueName(protocolHandler.generateQueueName());
}
- sendQueueDeclare(amqd, protocolHandler);
+ sendQueueDeclare(amqd, protocolHandler, nowait);
return amqd.getAMQQueueName();
}
}, _connection).execute();
}
- public abstract void sendQueueDeclare(final AMQDestination amqd, final AMQProtocolHandler protocolHandler) throws AMQException, FailoverException;
+ public abstract void sendQueueDeclare(final AMQDestination amqd, final AMQProtocolHandler protocolHandler,
+ final boolean nowait) throws AMQException, FailoverException;
/**
* Undeclares the specified queue.
@@ -2416,14 +2442,14 @@ public abstract class AMQSession<C extends BasicMessageConsumer, P extends Basic
AMQProtocolHandler protocolHandler = getProtocolHandler();
- declareExchange(amqd, protocolHandler, false);
+ declareExchange(amqd, protocolHandler, nowait);
- AMQShortString queueName = declareQueue(amqd, protocolHandler, consumer.isNoLocal());
+ AMQShortString queueName = declareQueue(amqd, protocolHandler, consumer.isNoLocal(), nowait);
// store the consumer queue name
consumer.setQueuename(queueName);
- bindQueue(queueName, amqd.getRoutingKey(), consumer.getArguments(), amqd.getExchangeName(), amqd);
+ bindQueue(queueName, amqd.getRoutingKey(), consumer.getArguments(), amqd.getExchangeName(), amqd, nowait);
// If IMMEDIATE_PREFETCH is not required then suspsend the channel to delay prefetch
if (!_immediatePrefetch)
@@ -2455,11 +2481,7 @@ public abstract class AMQSession<C extends BasicMessageConsumer, P extends Basic
try
{
- consumeFromQueue(consumer, queueName, protocolHandler, nowait, consumer.getMessageSelector());
- }
- catch (JMSException e) // thrown by getMessageSelector
- {
- throw new AMQException(null, e.getMessage(), e);
+ consumeFromQueue(consumer, queueName, protocolHandler, nowait, consumer._messageSelector);
}
catch (FailoverException e)
{
@@ -2531,8 +2553,9 @@ public abstract class AMQSession<C extends BasicMessageConsumer, P extends Basic
for (C consumer : consumers)
{
- consumer.failedOver();
+ consumer.failedOverPre();
registerConsumer(consumer, true);
+ consumer.failedOverPost();
}
}
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 45b74f317e..34457d745f 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
@@ -52,9 +52,12 @@ import static org.apache.qpid.transport.Option.*;
import javax.jms.*;
import javax.jms.IllegalStateException;
+import java.util.Date;
import java.util.HashMap;
import java.util.UUID;
import java.util.Map;
+import java.util.Timer;
+import java.util.TimerTask;
/**
* This is a 0.10 Session
@@ -68,6 +71,8 @@ public class AMQSession_0_10 extends AMQSession<BasicMessageConsumer_0_10, Basic
*/
private static final Logger _logger = LoggerFactory.getLogger(AMQSession_0_10.class);
+ private static Timer timer = new Timer("ack-flusher", true);
+
/**
* The underlying QpidSession
@@ -83,6 +88,8 @@ public class AMQSession_0_10 extends AMQSession<BasicMessageConsumer_0_10, Basic
// a ref on the qpid connection
protected org.apache.qpid.transport.Connection _qpidConnection;
+ private long maxAckDelay = Long.getLong("qpid.session.max_ack_delay", 1000);
+ private TimerTask flushTask = null;
private RangeSet unacked = new RangeSet();
private int unackedCount = 0;
@@ -119,6 +126,25 @@ public class AMQSession_0_10 extends AMQSession<BasicMessageConsumer_0_10, Basic
{
_qpidSession.txSelect();
}
+
+ if (maxAckDelay > 0)
+ {
+ flushTask = new TimerTask()
+ {
+ public void run()
+ {
+ try
+ {
+ flushAcknowledgments(true);
+ }
+ catch (Throwable t)
+ {
+ _logger.error("error flushing acks", t);
+ }
+ }
+ };
+ timer.schedule(flushTask, new Date(), maxAckDelay);
+ }
}
/**
@@ -142,14 +168,20 @@ public class AMQSession_0_10 extends AMQSession<BasicMessageConsumer_0_10, Basic
private void addUnacked(int id)
{
- unacked.add(id);
- unackedCount++;
+ synchronized (unacked)
+ {
+ unacked.add(id);
+ unackedCount++;
+ }
}
private void clearUnacked()
{
- unacked.clear();
- unackedCount = 0;
+ synchronized (unacked)
+ {
+ unacked.clear();
+ unackedCount = 0;
+ }
}
//------- overwritten methods of class AMQSession
@@ -196,24 +228,37 @@ public class AMQSession_0_10 extends AMQSession<BasicMessageConsumer_0_10, Basic
long prefetch = getAMQConnection().getMaxPrefetch();
- if (unackedCount >= prefetch/2 || _acknowledgeMode != org.apache.qpid.jms.Session.NO_ACKNOWLEDGE)
+ if (unackedCount >= prefetch/2 || maxAckDelay <= 0)
{
flushAcknowledgments();
- }
+ }
}
void flushAcknowledgments()
{
- if (unackedCount > 0)
+ flushAcknowledgments(false);
+ }
+
+ void flushAcknowledgments(boolean setSyncBit)
+ {
+ synchronized (unacked)
{
- messageAcknowledge
- (unacked, _acknowledgeMode != org.apache.qpid.jms.Session.NO_ACKNOWLEDGE);
- clearUnacked();
+ if (unackedCount > 0)
+ {
+ messageAcknowledge
+ (unacked, _acknowledgeMode != org.apache.qpid.jms.Session.NO_ACKNOWLEDGE,setSyncBit);
+ clearUnacked();
+ }
}
}
void messageAcknowledge(RangeSet ranges, boolean accept)
{
+ messageAcknowledge(ranges,accept,false);
+ }
+
+ void messageAcknowledge(RangeSet ranges, boolean accept,boolean setSyncBit)
+ {
Session ssn = getQpidSession();
for (Range range : ranges)
{
@@ -222,7 +267,7 @@ public class AMQSession_0_10 extends AMQSession<BasicMessageConsumer_0_10, Basic
ssn.flushProcessed(accept ? BATCH : NONE);
if (accept)
{
- ssn.messageAccept(ranges);
+ ssn.messageAccept(ranges, UNRELIABLE,setSyncBit? SYNC : NONE);
}
}
@@ -237,7 +282,8 @@ public class AMQSession_0_10 extends AMQSession<BasicMessageConsumer_0_10, Basic
* @param arguments 0_8 specific
*/
public void sendQueueBind(final AMQShortString queueName, final AMQShortString routingKey,
- final FieldTable arguments, final AMQShortString exchangeName, final AMQDestination destination)
+ final FieldTable arguments, final AMQShortString exchangeName,
+ final AMQDestination destination, final boolean nowait)
throws AMQException, FailoverException
{
Map args = FiledTableSupport.convertToMap(arguments);
@@ -252,9 +298,12 @@ public class AMQSession_0_10 extends AMQSession<BasicMessageConsumer_0_10, Basic
_logger.debug("Binding queue : " + queueName.toString() + " exchange: " + exchangeName.toString() + " using binding key " + rk.asString());
getQpidSession().exchangeBind(queueName.toString(), exchangeName.toString(), rk.toString(), args);
}
- // We need to sync so that we get notify of an error.
- getQpidSession().sync();
- getCurrentException();
+ if (!nowait)
+ {
+ // We need to sync so that we get notify of an error.
+ getQpidSession().sync();
+ getCurrentException();
+ }
}
@@ -267,6 +316,10 @@ public class AMQSession_0_10 extends AMQSession<BasicMessageConsumer_0_10, Basic
*/
public void sendClose(long timeout) throws AMQException, FailoverException
{
+ if (flushTask != null)
+ {
+ flushTask.cancel();
+ }
flushAcknowledgments();
getQpidSession().sync();
getQpidSession().close();
@@ -462,18 +515,24 @@ public class AMQSession_0_10 extends AMQSession<BasicMessageConsumer_0_10, Basic
{
getQpidSession().messageSetFlowMode(consumerTag, MessageFlowMode.WINDOW);
}
- getQpidSession().messageFlow(consumerTag, MessageCreditUnit.BYTE, 0xFFFFFFFF);
+ getQpidSession().messageFlow(consumerTag, MessageCreditUnit.BYTE, 0xFFFFFFFF,
+ Option.UNRELIABLE);
// We need to sync so that we get notify of an error.
// only if not immediat prefetch
- if(prefetch() && (consumer.isStrated() || _immediatePrefetch))
+ if(prefetch() && (isStarted() || _immediatePrefetch))
{
// set the flow
getQpidSession().messageFlow(consumerTag,
MessageCreditUnit.MESSAGE,
- getAMQConnection().getMaxPrefetch());
+ getAMQConnection().getMaxPrefetch(),
+ Option.UNRELIABLE);
+ }
+
+ if (!nowait)
+ {
+ getQpidSession().sync();
+ getCurrentException();
}
- getQpidSession().sync();
- getCurrentException();
}
/**
@@ -501,14 +560,18 @@ public class AMQSession_0_10 extends AMQSession<BasicMessageConsumer_0_10, Basic
null,
name.toString().startsWith("amq.")? Option.PASSIVE:Option.NONE);
// We need to sync so that we get notify of an error.
- getQpidSession().sync();
- getCurrentException();
+ if (!nowait)
+ {
+ getQpidSession().sync();
+ getCurrentException();
+ }
}
/**
* Declare a queue with the given queueName
*/
- public void sendQueueDeclare(final AMQDestination amqd, final AMQProtocolHandler protocolHandler)
+ public void sendQueueDeclare(final AMQDestination amqd, final AMQProtocolHandler protocolHandler,
+ final boolean nowait)
throws AMQException, FailoverException
{
// do nothing this is only used by 0_8
@@ -518,7 +581,7 @@ public class AMQSession_0_10 extends AMQSession<BasicMessageConsumer_0_10, Basic
* Declare a queue with the given queueName
*/
public AMQShortString send0_10QueueDeclare(final AMQDestination amqd, final AMQProtocolHandler protocolHandler,
- final boolean noLocal)
+ final boolean noLocal, final boolean nowait)
throws AMQException, FailoverException
{
AMQShortString res;
@@ -542,9 +605,12 @@ public class AMQSession_0_10 extends AMQSession<BasicMessageConsumer_0_10, Basic
amqd.isDurable() ? Option.DURABLE : Option.NONE,
!amqd.isDurable() && amqd.isExclusive() ? Option.EXCLUSIVE : Option.NONE);
// passive --> false
- // We need to sync so that we get notify of an error.
- getQpidSession().sync();
- getCurrentException();
+ if (!nowait)
+ {
+ // We need to sync so that we get notify of an error.
+ getQpidSession().sync();
+ getCurrentException();
+ }
return res;
}
@@ -570,7 +636,8 @@ public class AMQSession_0_10 extends AMQSession<BasicMessageConsumer_0_10, Basic
{
for (BasicMessageConsumer consumer : _consumers.values())
{
- getQpidSession().messageStop(String.valueOf(consumer.getConsumerTag()));
+ getQpidSession().messageStop(String.valueOf(consumer.getConsumerTag()),
+ Option.UNRELIABLE);
}
}
else
@@ -586,17 +653,20 @@ public class AMQSession_0_10 extends AMQSession<BasicMessageConsumer_0_10, Basic
if (consumer.getMessageListener() != null)
{
getQpidSession().messageFlow(consumerTag,
- MessageCreditUnit.MESSAGE, 1);
+ MessageCreditUnit.MESSAGE, 1,
+ Option.UNRELIABLE);
}
}
else
{
getQpidSession()
.messageFlow(consumerTag, MessageCreditUnit.MESSAGE,
- getAMQConnection().getMaxPrefetch());
+ getAMQConnection().getMaxPrefetch(),
+ Option.UNRELIABLE);
}
getQpidSession()
- .messageFlow(consumerTag, MessageCreditUnit.BYTE, 0xFFFFFFFF);
+ .messageFlow(consumerTag, MessageCreditUnit.BYTE, 0xFFFFFFFF,
+ Option.UNRELIABLE);
}
catch (Exception e)
{
@@ -661,6 +731,19 @@ public class AMQSession_0_10 extends AMQSession<BasicMessageConsumer_0_10, Basic
public void opened(Session ssn) {}
+ public void resumed(Session ssn)
+ {
+ _qpidConnection = ssn.getConnection();
+ try
+ {
+ resubscribe();
+ }
+ catch (AMQException e)
+ {
+ throw new RuntimeException(e);
+ }
+ }
+
public void message(Session ssn, MessageTransfer xfr)
{
messageReceived(new UnprocessedMessage_0_10(xfr));
@@ -677,7 +760,7 @@ public class AMQSession_0_10 extends AMQSession<BasicMessageConsumer_0_10, Basic
public void closed(Session ssn) {}
protected AMQShortString declareQueue(final AMQDestination amqd, final AMQProtocolHandler protocolHandler,
- final boolean noLocal)
+ final boolean noLocal, final boolean nowait)
throws AMQException
{
/*return new FailoverRetrySupport<AMQShortString, AMQException>(*/
@@ -692,39 +775,16 @@ public class AMQSession_0_10 extends AMQSession<BasicMessageConsumer_0_10, Basic
String binddingKey = "";
for(AMQShortString key : amqd.getBindingKeys())
{
- binddingKey = binddingKey + "_" + key.toString();
+ binddingKey = binddingKey + "_" + key.toString();
}
amqd.setQueueName(new AMQShortString( binddingKey + "@"
+ amqd.getExchangeName().toString() + "_" + UUID.randomUUID()));
}
- return send0_10QueueDeclare(amqd, protocolHandler, noLocal);
+ return send0_10QueueDeclare(amqd, protocolHandler, noLocal, nowait);
}
}, _connection).execute();
}
-
- void start() throws AMQException
- {
- super.start();
- for(BasicMessageConsumer c: _consumers.values())
- {
- c.start();
- }
- }
-
-
- void stop() throws AMQException
- {
- super.stop();
- for(BasicMessageConsumer c: _consumers.values())
- {
- c.stop();
- }
- }
-
-
-
-
public TopicSubscriber createDurableSubscriber(Topic topic, String name) throws JMSException
{
@@ -800,14 +860,14 @@ public class AMQSession_0_10 extends AMQSession<BasicMessageConsumer_0_10, Basic
/**
* Store non committed messages for this session
* With 0.10 messages are consumed with window mode, we must send a completion
- * before the window size is reached so credits don't dry up.
+ * before the window size is reached so credits don't dry up.
* @param id
*/
@Override protected void addDeliveredMessage(long id)
{
_txRangeSet.add((int) id);
_txSize++;
- // this is a heuristic, we may want to have that configurable
+ // this is a heuristic, we may want to have that configurable
if (_connection.getMaxPrefetch() == 1 ||
_connection.getMaxPrefetch() != 0 && _txSize % (_connection.getMaxPrefetch() / 2) == 0)
{
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 6451ae60be..ff8631c12e 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
@@ -106,7 +106,8 @@ public final class AMQSession_0_8 extends AMQSession<BasicMessageConsumer_0_8, B
}
public void sendQueueBind(final AMQShortString queueName, final AMQShortString routingKey, final FieldTable arguments,
- final AMQShortString exchangeName, final AMQDestination dest) throws AMQException, FailoverException
+ final AMQShortString exchangeName, final AMQDestination dest,
+ final boolean nowait) throws AMQException, FailoverException
{
getProtocolHandler().syncWrite(getProtocolHandler().getMethodRegistry().createQueueBindBody
(getTicket(),queueName,exchangeName,routingKey,false,arguments).
@@ -300,13 +301,14 @@ public final class AMQSession_0_8 extends AMQSession<BasicMessageConsumer_0_8, B
{
ExchangeDeclareBody body = getMethodRegistry().createExchangeDeclareBody(getTicket(),name,type,
name.toString().startsWith("amq."),
- false,false,false,nowait,null);
+ false,false,false,false,null);
AMQFrame exchangeDeclare = body.generateFrame(_channelId);
protocolHandler.syncWrite(exchangeDeclare, ExchangeDeclareOkBody.class);
}
- public void sendQueueDeclare(final AMQDestination amqd, final AMQProtocolHandler protocolHandler) throws AMQException, FailoverException
+ public void sendQueueDeclare(final AMQDestination amqd, final AMQProtocolHandler protocolHandler,
+ final boolean nowait) throws AMQException, FailoverException
{
QueueDeclareBody body = getMethodRegistry().createQueueDeclareBody(getTicket(),amqd.getAMQQueueName(),false,amqd.isDurable(),amqd.isExclusive(),amqd.isAutoDelete(),false,null);
diff --git a/qpid/java/client/src/main/java/org/apache/qpid/client/BasicMessageConsumer.java b/qpid/java/client/src/main/java/org/apache/qpid/client/BasicMessageConsumer.java
index 76422c6297..2bb443a090 100644
--- a/qpid/java/client/src/main/java/org/apache/qpid/client/BasicMessageConsumer.java
+++ b/qpid/java/client/src/main/java/org/apache/qpid/client/BasicMessageConsumer.java
@@ -441,7 +441,9 @@ public abstract class BasicMessageConsumer<U> extends Closeable implements Messa
o = _synchronousQueue.take();
}
return o;
- }
+ }
+
+ abstract Message receiveBrowse() throws JMSException;
public Message receiveNoWait() throws JMSException
{
@@ -1037,23 +1039,6 @@ public abstract class BasicMessageConsumer<U> extends Closeable implements Messa
_synchronousQueue.clear();
}
- public void start()
- {
- // do nothing as this is a 0_10 feature
- }
-
-
- public void stop()
- {
- // do nothing as this is a 0_10 feature
- }
-
- public boolean isStrated()
- {
- // do nothing as this is a 0_10 feature
- return false;
- }
-
public AMQShortString getQueuename()
{
return _queuename;
@@ -1070,10 +1055,13 @@ public abstract class BasicMessageConsumer<U> extends Closeable implements Messa
}
/** to be called when a failover has occured */
- public void failedOver()
+ public void failedOverPre()
{
clearReceiveQueue();
// TGM FIXME: think this should just be removed
// clearUnackedMessages();
}
+
+ public void failedOverPost() {}
+
}
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 7d535643c0..8b17dcf91f 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
@@ -31,6 +31,7 @@ import org.apache.qpid.filter.JMSSelectorFilter;
import javax.jms.InvalidSelectorException;
import javax.jms.JMSException;
+import javax.jms.Message;
import javax.jms.MessageListener;
import java.util.Iterator;
import java.util.concurrent.atomic.AtomicBoolean;
@@ -148,7 +149,8 @@ public class BasicMessageConsumer_0_10 extends BasicMessageConsumer<UnprocessedM
if (isMessageListenerSet() && ! getSession().prefetch())
{
_0_10session.getQpidSession().messageFlow(getConsumerTagString(),
- MessageCreditUnit.MESSAGE, 1);
+ MessageCreditUnit.MESSAGE, 1,
+ Option.UNRELIABLE);
}
_logger.debug("messageOk, trying to notify");
super.notifyMessage(jmsMessage);
@@ -246,7 +248,8 @@ public class BasicMessageConsumer_0_10 extends BasicMessageConsumer<UnprocessedM
if(! getSession().prefetch())
{
_0_10session.getQpidSession().messageFlow(getConsumerTagString(),
- MessageCreditUnit.MESSAGE, 1);
+ MessageCreditUnit.MESSAGE, 1,
+ Option.UNRELIABLE);
}
}
// now we need to acquire this message if needed
@@ -258,9 +261,7 @@ public class BasicMessageConsumer_0_10 extends BasicMessageConsumer<UnprocessedM
_logger.debug("filterMessage - trying to acquire message");
}
messageOk = acquireMessage(message);
- _logger.debug("filterMessage - *************************************");
_logger.debug("filterMessage - message acquire status : " + messageOk);
- _logger.debug("filterMessage - *************************************");
}
return messageOk;
}
@@ -335,7 +336,8 @@ public class BasicMessageConsumer_0_10 extends BasicMessageConsumer<UnprocessedM
if (messageListener != null && ! getSession().prefetch())
{
_0_10session.getQpidSession().messageFlow(getConsumerTagString(),
- MessageCreditUnit.MESSAGE, 1);
+ MessageCreditUnit.MESSAGE, 1,
+ Option.UNRELIABLE);
}
if (messageListener != null && !_synchronousQueue.isEmpty())
{
@@ -349,26 +351,16 @@ public class BasicMessageConsumer_0_10 extends BasicMessageConsumer<UnprocessedM
}
}
- public boolean isStrated()
+ public void failedOverPost()
{
- return _isStarted;
- }
-
- public void start()
- {
- _isStarted = true;
- if (_syncReceive.get())
+ if (_0_10session.isStarted() && _syncReceive.get())
{
- _0_10session.getQpidSession().messageFlow(getConsumerTagString(),
- MessageCreditUnit.MESSAGE, 1);
+ _0_10session.getQpidSession().messageFlow
+ (getConsumerTagString(), MessageCreditUnit.MESSAGE, 1,
+ Option.UNRELIABLE);
}
}
- public void stop()
- {
- _isStarted = false;
- }
-
/**
* When messages are not prefetched we need to request a message from the
* broker.
@@ -380,16 +372,35 @@ public class BasicMessageConsumer_0_10 extends BasicMessageConsumer<UnprocessedM
*/
public Object getMessageFromQueue(long l) throws InterruptedException
{
- if (isStrated() && ! getSession().prefetch() && _synchronousQueue.isEmpty())
- {
- _0_10session.getQpidSession().messageFlow(getConsumerTagString(),
- MessageCreditUnit.MESSAGE, 1);
- }
if (! getSession().prefetch())
{
_syncReceive.set(true);
}
+ if (_0_10session.isStarted() && ! getSession().prefetch() && _synchronousQueue.isEmpty())
+ {
+ _0_10session.getQpidSession().messageFlow(getConsumerTagString(),
+ MessageCreditUnit.MESSAGE, 1,
+ Option.UNRELIABLE);
+ }
Object o = super.getMessageFromQueue(l);
+ if (o == null && _0_10session.isStarted())
+ {
+ _0_10session.getQpidSession().messageFlush
+ (getConsumerTagString(), Option.UNRELIABLE, Option.SYNC);
+ _0_10session.getQpidSession().sync();
+ _0_10session.getQpidSession().messageFlow
+ (getConsumerTagString(), MessageCreditUnit.BYTE,
+ 0xFFFFFFFF, Option.UNRELIABLE);
+ if (getSession().prefetch())
+ {
+ _0_10session.getQpidSession().messageFlow
+ (getConsumerTagString(), MessageCreditUnit.MESSAGE,
+ _0_10session.getAMQConnection().getMaxPrefetch(),
+ Option.UNRELIABLE);
+ }
+ _0_10session.syncDispatchQueue();
+ o = super.getMessageFromQueue(-1);
+ }
if (! getSession().prefetch())
{
_syncReceive.set(false);
@@ -404,6 +415,19 @@ public class BasicMessageConsumer_0_10 extends BasicMessageConsumer<UnprocessedM
{
_session.acknowledgeMessage(msg.getDeliveryTag(), false);
}
+
+ if (_acknowledgeMode == org.apache.qpid.jms.Session.AUTO_ACKNOWLEDGE &&
+ !_session.isInRecovery() &&
+ _session.getAMQConnection().getSyncAck())
+ {
+ ((AMQSession_0_10) getSession()).flushAcknowledgments();
+ ((AMQSession_0_10) getSession()).getQpidSession().sync();
+ }
+ }
+
+ Message receiveBrowse() throws JMSException
+ {
+ return receiveNoWait();
}
}
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 494a8fb43d..308f04f082 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
@@ -22,6 +22,7 @@ package org.apache.qpid.client;
import javax.jms.InvalidSelectorException;
import javax.jms.JMSException;
+import javax.jms.Message;
import org.apache.qpid.AMQException;
import org.apache.qpid.QpidException;
@@ -38,9 +39,9 @@ public class BasicMessageConsumer_0_8 extends BasicMessageConsumer<UnprocessedMe
protected final Logger _logger = LoggerFactory.getLogger(getClass());
protected BasicMessageConsumer_0_8(int channelId, AMQConnection connection, AMQDestination destination,
- String messageSelector, boolean noLocal, MessageFactoryRegistry messageFactory, AMQSession session,
- AMQProtocolHandler protocolHandler, FieldTable arguments, int prefetchHigh, int prefetchLow,
- boolean exclusive, int acknowledgeMode, boolean noConsume, boolean autoClose) throws JMSException
+ String messageSelector, boolean noLocal, MessageFactoryRegistry messageFactory, AMQSession session,
+ AMQProtocolHandler protocolHandler, FieldTable arguments, int prefetchHigh, int prefetchLow,
+ boolean exclusive, int acknowledgeMode, boolean noConsume, boolean autoClose) throws JMSException
{
super(channelId, connection, destination,messageSelector,noLocal,messageFactory,session,
protocolHandler, arguments, prefetchHigh, prefetchLow, exclusive,
@@ -73,13 +74,18 @@ public class BasicMessageConsumer_0_8 extends BasicMessageConsumer<UnprocessedMe
}
}
- public AbstractJMSMessage createJMSMessageFromUnprocessedMessage(AMQMessageDelegateFactory delegateFactory, UnprocessedMessage_0_8 messageFrame)throws Exception
- {
+ public AbstractJMSMessage createJMSMessageFromUnprocessedMessage(AMQMessageDelegateFactory delegateFactory, UnprocessedMessage_0_8 messageFrame)throws Exception
+ {
return _messageFactory.createMessage(messageFrame.getDeliveryTag(),
- messageFrame.isRedelivered(), messageFrame.getExchange(),
- messageFrame.getRoutingKey(), messageFrame.getContentHeader(), messageFrame.getBodies());
+ messageFrame.isRedelivered(), messageFrame.getExchange(),
+ messageFrame.getRoutingKey(), messageFrame.getContentHeader(), messageFrame.getBodies());
+
+ }
+ Message receiveBrowse() throws JMSException
+ {
+ return receive();
}
}
diff --git a/qpid/java/client/src/main/java/org/apache/qpid/client/BasicMessageProducer.java b/qpid/java/client/src/main/java/org/apache/qpid/client/BasicMessageProducer.java
index 954a3bc28f..5ff6066ddc 100644
--- a/qpid/java/client/src/main/java/org/apache/qpid/client/BasicMessageProducer.java
+++ b/qpid/java/client/src/main/java/org/apache/qpid/client/BasicMessageProducer.java
@@ -46,6 +46,8 @@ import org.slf4j.LoggerFactory;
public abstract class BasicMessageProducer extends Closeable implements org.apache.qpid.jms.MessageProducer
{
+ enum PublishMode { ASYNC_PUBLISH_ALL, SYNC_PUBLISH_PERSISTENT, SYNC_PUBLISH_ALL };
+
protected final Logger _logger = LoggerFactory.getLogger(getClass());
private AMQConnection _connection;
@@ -120,6 +122,8 @@ public abstract class BasicMessageProducer extends Closeable implements org.apac
protected String _userID; // ref user id used in the connection.
private static final ContentBody[] NO_CONTENT_BODIES = new ContentBody[0];
+
+ protected PublishMode publishMode = PublishMode.ASYNC_PUBLISH_ALL;
protected BasicMessageProducer(AMQConnection connection, AMQDestination destination, boolean transacted, int channelId,
AMQSession session, AMQProtocolHandler protocolHandler, long producerId, boolean immediate, boolean mandatory,
@@ -141,6 +145,26 @@ public abstract class BasicMessageProducer extends Closeable implements org.apac
_mandatory = mandatory;
_waitUntilSent = waitUntilSent;
_userID = connection.getUsername();
+ setPublishMode();
+ }
+
+ void setPublishMode()
+ {
+ // Publish mode could be configured at destination level as well.
+ // Will add support for this when we provide a more robust binding URL
+
+ String syncPub = _connection.getSyncPublish();
+ // Support for deprecated option sync_persistence
+ if (syncPub.equals("persistent") || _connection.getSyncPersistence())
+ {
+ publishMode = PublishMode.SYNC_PUBLISH_PERSISTENT;
+ }
+ else if (syncPub.equals("all"))
+ {
+ publishMode = PublishMode.SYNC_PUBLISH_ALL;
+ }
+
+ _logger.info("MessageProducer " + toString() + " using publish mode : " + publishMode);
}
void resubscribe() throws AMQException
diff --git a/qpid/java/client/src/main/java/org/apache/qpid/client/BasicMessageProducer_0_10.java b/qpid/java/client/src/main/java/org/apache/qpid/client/BasicMessageProducer_0_10.java
index 4e5077f0cd..b8c5fc8faf 100644
--- a/qpid/java/client/src/main/java/org/apache/qpid/client/BasicMessageProducer_0_10.java
+++ b/qpid/java/client/src/main/java/org/apache/qpid/client/BasicMessageProducer_0_10.java
@@ -151,9 +151,13 @@ public class BasicMessageProducer_0_10 extends BasicMessageProducer
((AMQSession_0_10) getSession()).getQpidSession();
// if true, we need to sync the delivery of this message
- boolean sync = (deliveryMode == DeliveryMode.PERSISTENT &&
- getSession().getAMQConnection().getSyncPersistence());
+ boolean sync = false;
+ sync = ( (publishMode == PublishMode.SYNC_PUBLISH_ALL) ||
+ (publishMode == PublishMode.SYNC_PUBLISH_PERSISTENT &&
+ deliveryMode == DeliveryMode.PERSISTENT)
+ );
+
org.apache.mina.common.ByteBuffer data = message.getData();
ByteBuffer buffer = data == null ? ByteBuffer.allocate(0) : data.buf().slice();
diff --git a/qpid/java/client/src/main/java/org/apache/qpid/client/configuration/ClientProperties.java b/qpid/java/client/src/main/java/org/apache/qpid/client/configuration/ClientProperties.java
index 986154cda8..3627618e68 100644
--- a/qpid/java/client/src/main/java/org/apache/qpid/client/configuration/ClientProperties.java
+++ b/qpid/java/client/src/main/java/org/apache/qpid/client/configuration/ClientProperties.java
@@ -47,6 +47,19 @@ public class ClientProperties
*/
public static final String SYNC_PERSISTENT_PROP_NAME = "sync_persistence";
+ /**
+ * When true a sync command is sent after sending a message ack.
+ * type: boolean
+ */
+ public static final String SYNC_ACK_PROP_NAME = "sync_ack";
+
+ /**
+ * sync_publish property - {persistent|all}
+ * If set to 'persistent',then persistent messages will be publish synchronously
+ * If set to 'all', then all messages regardless of the delivery mode will be
+ * published synchronously.
+ */
+ public static final String SYNC_PUBLISH_PROP_NAME = "sync_publish";
/**
* This value will be used in the following settings
diff --git a/qpid/java/client/src/main/java/org/apache/qpid/client/message/AbstractBytesMessage.java b/qpid/java/client/src/main/java/org/apache/qpid/client/message/AbstractBytesMessage.java
index c0d51fa726..234212c301 100644
--- a/qpid/java/client/src/main/java/org/apache/qpid/client/message/AbstractBytesMessage.java
+++ b/qpid/java/client/src/main/java/org/apache/qpid/client/message/AbstractBytesMessage.java
@@ -31,6 +31,7 @@ import org.apache.mina.common.ByteBuffer;
import org.apache.qpid.AMQException;
import org.apache.qpid.framing.AMQShortString;
import org.apache.qpid.framing.BasicContentHeaderProperties;
+import org.apache.qpid.transport.util.Functions;
/**
* @author Apache Software Foundation
@@ -84,53 +85,19 @@ public abstract class AbstractBytesMessage extends AbstractJMSMessage
}
public String toBodyString() throws JMSException
- {
+ {
checkReadable();
try
{
- return getText();
+ return Functions.str(_data.buf(), 100);
}
- catch (IOException e)
+ catch (Exception e)
{
JMSException jmse = new JMSException(e.toString());
jmse.setLinkedException(e);
throw jmse;
}
- }
-
- /**
- * We reset the stream before and after reading the data. This means that toString() will always output
- * the entire message and also that the caller can then immediately start reading as if toString() had
- * never been called.
- *
- * @return
- * @throws IOException
- */
- private String getText() throws IOException
- {
- // this will use the default platform encoding
- if (_data == null)
- {
- return null;
- }
-
- int pos = _data.position();
- _data.rewind();
- // one byte left is for the end of frame marker
- if (_data.remaining() == 0)
- {
- // this is really redundant since pos must be zero
- _data.position(pos);
-
- return null;
- }
- else
- {
- String data = _data.getString(Charset.forName("UTF8").newDecoder());
- _data.position(pos);
-
- return data;
- }
+
}
/**
diff --git a/qpid/java/client/src/main/java/org/apache/qpid/client/message/AbstractJMSMessage.java b/qpid/java/client/src/main/java/org/apache/qpid/client/message/AbstractJMSMessage.java
index 0700ce5d23..60c6048e43 100644
--- a/qpid/java/client/src/main/java/org/apache/qpid/client/message/AbstractJMSMessage.java
+++ b/qpid/java/client/src/main/java/org/apache/qpid/client/message/AbstractJMSMessage.java
@@ -367,13 +367,14 @@ public abstract class AbstractJMSMessage implements org.apache.qpid.jms.Message
try
{
StringBuffer buf = new StringBuffer("Body:\n");
+
buf.append(toBodyString());
buf.append("\nJMS Correlation ID: ").append(getJMSCorrelationID());
buf.append("\nJMS timestamp: ").append(getJMSTimestamp());
buf.append("\nJMS expiration: ").append(getJMSExpiration());
buf.append("\nJMS priority: ").append(getJMSPriority());
buf.append("\nJMS delivery mode: ").append(getJMSDeliveryMode());
- //buf.append("\nJMS reply to: ").append(String.valueOf(getJMSReplyTo()));
+ buf.append("\nJMS reply to: ").append(getReplyToString());
buf.append("\nJMS Redelivered: ").append(_redelivered);
buf.append("\nJMS Destination: ").append(getJMSDestination());
buf.append("\nJMS Type: ").append(getJMSType());
@@ -392,7 +393,7 @@ public abstract class AbstractJMSMessage implements org.apache.qpid.jms.Message
while(propertyNames.hasMoreElements())
{
String propertyName = (String) propertyNames.nextElement();
- buf.append(propertyName).append(":\t").append(getObjectProperty(propertyName));
+ buf.append("\t").append(propertyName).append(" = ").append(getObjectProperty(propertyName)).append("\n");
}
}
@@ -401,7 +402,9 @@ public abstract class AbstractJMSMessage implements org.apache.qpid.jms.Message
}
catch (JMSException e)
{
- return e.toString();
+ e.printStackTrace();
+
+ throw new RuntimeException(e);
}
}
diff --git a/qpid/java/client/src/main/java/org/apache/qpid/client/message/JMSBytesMessage.java b/qpid/java/client/src/main/java/org/apache/qpid/client/message/JMSBytesMessage.java
index cd9d7ccf8b..8681dae2bd 100644
--- a/qpid/java/client/src/main/java/org/apache/qpid/client/message/JMSBytesMessage.java
+++ b/qpid/java/client/src/main/java/org/apache/qpid/client/message/JMSBytesMessage.java
@@ -381,10 +381,4 @@ public class JMSBytesMessage extends AbstractBytesMessage implements BytesMessag
throw new MessageFormatException("Only primitives plus byte arrays and String are valid types");
}
}
-
- public String toString()
- {
- return String.valueOf(System.identityHashCode(this));
- }
-
}
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 39b9597af1..56e9a5dc73 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
@@ -25,8 +25,6 @@ import java.io.InputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
-import java.nio.charset.CharacterCodingException;
-import java.nio.charset.Charset;
import javax.jms.JMSException;
import javax.jms.MessageFormatException;
@@ -35,8 +33,6 @@ import javax.jms.ObjectMessage;
import org.apache.mina.common.ByteBuffer;
import org.apache.qpid.AMQException;
-import org.apache.qpid.framing.AMQShortString;
-import org.apache.qpid.framing.BasicContentHeaderProperties;
public class JMSObjectMessage extends AbstractJMSMessage implements ObjectMessage
{
@@ -157,7 +153,7 @@ public class JMSObjectMessage extends AbstractJMSMessage implements ObjectMessag
}
finally
{
- _data.rewind();
+ // _data.rewind();
close(in);
}
}
diff --git a/qpid/java/client/src/main/java/org/apache/qpid/client/message/JMSTextMessage.java b/qpid/java/client/src/main/java/org/apache/qpid/client/message/JMSTextMessage.java
index c290149cef..f83ae6ace0 100644
--- a/qpid/java/client/src/main/java/org/apache/qpid/client/message/JMSTextMessage.java
+++ b/qpid/java/client/src/main/java/org/apache/qpid/client/message/JMSTextMessage.java
@@ -100,6 +100,7 @@ public class JMSTextMessage extends AbstractJMSMessage implements javax.jms.Text
if (encoding == null || encoding.equalsIgnoreCase("UTF-8"))
{
_data = ByteBuffer.wrap(Strings.toUTF8(text));
+ setEncoding("UTF-8");
}
else
{
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 d1b3baff6c..a7d41e2cde 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
@@ -48,6 +48,7 @@ public class MessageFactoryRegistry
private final Map<String, MessageFactory> _mimeStringToFactoryMap = new HashMap<String, MessageFactory>();
private final Map<AMQShortString, MessageFactory> _mimeShortStringToFactoryMap =
new HashMap<AMQShortString, MessageFactory>();
+ private final MessageFactory _default = new JMSBytesMessageFactory();
/**
* Construct a new registry with the default message factories registered
@@ -63,7 +64,7 @@ public class MessageFactoryRegistry
mf.registerFactory(JMSBytesMessage.MIME_TYPE, new JMSBytesMessageFactory());
mf.registerFactory(JMSObjectMessage.MIME_TYPE, new JMSObjectMessageFactory());
mf.registerFactory(JMSStreamMessage.MIME_TYPE, new JMSStreamMessageFactory());
- mf.registerFactory(null, new JMSBytesMessageFactory());
+ mf.registerFactory(null, mf._default);
return mf;
}
@@ -113,12 +114,10 @@ public class MessageFactoryRegistry
MessageFactory mf = _mimeShortStringToFactoryMap.get(contentTypeShortString);
if (mf == null)
{
- throw new AMQException(null, "Unsupport MIME type of " + properties.getContentTypeAsString(), null);
- }
- else
- {
- return mf.createMessage(deliveryTag, redelivered, contentHeader, exchange, routingKey, bodies);
+ mf = _default;
}
+
+ return mf.createMessage(deliveryTag, redelivered, contentHeader, exchange, routingKey, bodies);
}
public AbstractJMSMessage createMessage(MessageTransfer transfer) throws AMQException, JMSException
@@ -138,22 +137,20 @@ public class MessageFactoryRegistry
MessageFactory mf = _mimeStringToFactoryMap.get(messageType);
if (mf == null)
{
- throw new AMQException(null, "Unsupport MIME type of " + messageType, null);
+ mf = _default;
}
- else
+
+ boolean redelivered = false;
+ DeliveryProperties deliverProps;
+ if((deliverProps = transfer.getHeader().get(DeliveryProperties.class)) != null)
{
- boolean redelivered = false;
- DeliveryProperties deliverProps;
- if((deliverProps = transfer.getHeader().get(DeliveryProperties.class)) != null)
- {
- redelivered = deliverProps.getRedelivered();
- }
- return mf.createMessage(transfer.getId(),
- redelivered,
- mprop == null? new MessageProperties():mprop,
- deliverProps == null? new DeliveryProperties():deliverProps,
- transfer.getBody());
+ redelivered = deliverProps.getRedelivered();
}
+ return mf.createMessage(transfer.getId(),
+ redelivered,
+ mprop == null? new MessageProperties():mprop,
+ deliverProps == null? new DeliveryProperties():deliverProps,
+ transfer.getBody());
}
@@ -167,11 +164,9 @@ public class MessageFactoryRegistry
MessageFactory mf = _mimeStringToFactoryMap.get(mimeType);
if (mf == null)
{
- throw new AMQException(null, "Unsupport MIME type of " + mimeType, null);
- }
- else
- {
- return mf.createMessage(delegateFactory);
+ mf = _default;
}
+
+ return mf.createMessage(delegateFactory);
}
}
diff --git a/qpid/java/client/src/main/java/org/apache/qpid/client/url/URLParser.java b/qpid/java/client/src/main/java/org/apache/qpid/client/url/URLParser.java
index fab95f754c..f3f74dd332 100644
--- a/qpid/java/client/src/main/java/org/apache/qpid/client/url/URLParser.java
+++ b/qpid/java/client/src/main/java/org/apache/qpid/client/url/URLParser.java
@@ -58,22 +58,31 @@ public class URLParser
if ((connection.getHost() == null) || connection.getHost().equals(""))
{
- String uid = AMQConnectionFactory.getUniqueClientID();
- if (uid == null)
- {
- throw URLHelper.parseError(-1, "Client Name not specified", fullURL);
+ String tmp = connection.getAuthority();
+ // hack to read a clientid such as "my_clientID"
+ if (tmp != null && tmp.indexOf('@') < tmp.length()-1)
+ {
+ _url.setClientName(tmp.substring(tmp.indexOf('@')+1,tmp.length()));
}
else
{
- _url.setClientName(uid);
+ String uid = AMQConnectionFactory.getUniqueClientID();
+ if (uid == null)
+ {
+ throw URLHelper.parseError(-1, "Client Name not specified", fullURL);
+ }
+ else
+ {
+ _url.setClientName(uid);
+ }
}
- }
+ }
else
{
_url.setClientName(connection.getHost());
}
-
+
String userInfo = connection.getUserInfo();
if (userInfo == null)
diff --git a/qpid/java/client/src/main/java/org/apache/qpid/jms/ConnectionURL.java b/qpid/java/client/src/main/java/org/apache/qpid/jms/ConnectionURL.java
index da8cd4f750..03ab967c36 100644
--- a/qpid/java/client/src/main/java/org/apache/qpid/jms/ConnectionURL.java
+++ b/qpid/java/client/src/main/java/org/apache/qpid/jms/ConnectionURL.java
@@ -33,9 +33,11 @@ import java.util.List;
*/
public interface ConnectionURL
{
- public static final String AMQ_SYNC_PERSISTENCE = "sync_persistence";
- public static final String AMQ_MAXPREFETCH = "maxprefetch";
public static final String AMQ_PROTOCOL = "amqp";
+ public static final String OPTIONS_SYNC_PERSISTENCE = "sync_persistence";
+ public static final String OPTIONS_MAXPREFETCH = "maxprefetch";
+ public static final String OPTIONS_SYNC_ACK = "sync_ack";
+ public static final String OPTIONS_SYNC_PUBLISH = "sync_publish";
public static final String OPTIONS_BROKERLIST = "brokerlist";
public static final String OPTIONS_FAILOVER = "failover";
public static final String OPTIONS_FAILOVER_CYCLE = "cyclecount";
diff --git a/qpid/java/client/src/main/java/org/apache/qpid/jms/failover/FailoverExchangeMethod.java b/qpid/java/client/src/main/java/org/apache/qpid/jms/failover/FailoverExchangeMethod.java
index 6f945687cf..e05a7ab6e2 100644
--- a/qpid/java/client/src/main/java/org/apache/qpid/jms/failover/FailoverExchangeMethod.java
+++ b/qpid/java/client/src/main/java/org/apache/qpid/jms/failover/FailoverExchangeMethod.java
@@ -20,6 +20,7 @@
*/
package org.apache.qpid.jms.failover;
+import java.net.InetAddress;
import java.util.ArrayList;
import java.util.List;
@@ -52,7 +53,7 @@ import org.slf4j.LoggerFactory;
* from the list.
*/
-public class FailoverExchangeMethod extends FailoverRoundRobinServers implements FailoverMethod, MessageListener
+public class FailoverExchangeMethod implements FailoverMethod, MessageListener
{
private static final Logger _logger = LoggerFactory.getLogger(FailoverExchangeMethod.class);
@@ -65,17 +66,29 @@ public class FailoverExchangeMethod extends FailoverRoundRobinServers implements
/** The session used to subscribe to failover exchange */
private Session _ssn;
- private BrokerDetails _orginalBrokerDetail;
+ private BrokerDetails _originalBrokerDetail;
+
+ /** The index into the hostDetails array of the broker to which we are connected */
+ private int _currentBrokerIndex = 0;
+
+ /** The broker currently selected **/
+ private BrokerDetails _currentBrokerDetail;
+
+ /** Array of BrokerDetail used to make connections. */
+ private ConnectionURL _connectionDetails;
+
+ /** Denotes the number of failed attempts **/
+ private int _failedAttemps = 0;
public FailoverExchangeMethod(ConnectionURL connectionDetails, AMQConnection conn)
{
- super(connectionDetails);
- _orginalBrokerDetail = _connectionDetails.getBrokerDetails(0);
+ _connectionDetails = connectionDetails;
+ _originalBrokerDetail = _connectionDetails.getBrokerDetails(0);
// This is not safe to use until attainConnection is called, as this ref will not initialized fully.
// The reason being this constructor is called inside the AMWConnection constructor.
// It would be best if we find a way to pass this ref after AMQConnection is fully initialized.
- _conn = conn;
+ _conn = conn;
}
private void subscribeForUpdates() throws JMSException
@@ -96,6 +109,17 @@ public class FailoverExchangeMethod extends FailoverRoundRobinServers implements
public void onMessage(Message m)
{
_logger.info("Failover exchange notified cluster membership change");
+
+ String currentBrokerIP = "";
+ try
+ {
+ currentBrokerIP = InetAddress.getByName(_currentBrokerDetail.getHost()).getHostAddress();
+ }
+ catch(Exception e)
+ {
+ _logger.warn("Unable to resolve current broker host name",e);
+ }
+
List<BrokerDetails> brokerList = new ArrayList<BrokerDetails>();
try
{
@@ -109,15 +133,22 @@ public class FailoverExchangeMethod extends FailoverRoundRobinServers implements
for (String url:urls)
{
String[] tokens = url.split(":");
- if (tokens[0].equalsIgnoreCase(_orginalBrokerDetail.getTransport()))
+ if (tokens[0].equalsIgnoreCase(_originalBrokerDetail.getTransport()))
{
BrokerDetails broker = new AMQBrokerDetails();
broker.setTransport(tokens[0]);
broker.setHost(tokens[1]);
broker.setPort(Integer.parseInt(tokens[2]));
- broker.setProperties(_orginalBrokerDetail.getProperties());
- broker.setSSLConfiguration(_orginalBrokerDetail.getSSLConfiguration());
+ broker.setProperties(_originalBrokerDetail.getProperties());
+ broker.setSSLConfiguration(_originalBrokerDetail.getSSLConfiguration());
brokerList.add(broker);
+
+ if (currentBrokerIP.equals(broker.getHost()) &&
+ _currentBrokerDetail.getPort() == broker.getPort())
+ {
+ _currentBrokerIndex = brokerList.indexOf(broker);
+ }
+
break;
}
}
@@ -132,13 +163,20 @@ public class FailoverExchangeMethod extends FailoverRoundRobinServers implements
{
_connectionDetails.setBrokerDetails(brokerList);
}
+
+ _logger.info("============================================================");
+ _logger.info("Updated cluster membership details " + _connectionDetails);
+ _logger.info("============================================================");
}
public void attainedConnection()
{
- super.attainedConnection();
try
{
+ _failedAttemps = 0;
+ _logger.info("============================================================");
+ _logger.info("Attained connection ");
+ _logger.info("============================================================");
subscribeForUpdates();
}
catch (JMSException e)
@@ -151,17 +189,92 @@ public class FailoverExchangeMethod extends FailoverRoundRobinServers implements
{
synchronized (_brokerListLock)
{
- return super.getCurrentBrokerDetails();
+ return _connectionDetails.getBrokerDetails(_currentBrokerIndex);
}
- }
-
+ }
+
public BrokerDetails getNextBrokerDetails()
{
synchronized(_brokerListLock)
{
- return super.getNextBrokerDetails();
+ if (_currentBrokerIndex == (_connectionDetails.getBrokerCount() - 1))
+ {
+ _currentBrokerIndex = 0;
+ }
+ else
+ {
+ _currentBrokerIndex++;
+ }
+
+ BrokerDetails broker = _connectionDetails.getBrokerDetails(_currentBrokerIndex);
+
+ // When the broker list is updated it will include the current broker as well
+ // There is no point trying it again, so trying the next one.
+ if (_currentBrokerDetail != null &&
+ broker.getHost().equals(_currentBrokerDetail.getHost()) &&
+ broker.getPort() == _currentBrokerDetail.getPort())
+ {
+ return getNextBrokerDetails();
+ }
+
+ String delayStr = broker.getProperty(BrokerDetails.OPTIONS_CONNECT_DELAY);
+ if (delayStr != null)
+ {
+ Long delay = Long.parseLong(delayStr);
+ _logger.info("Delay between connect retries:" + delay);
+ try
+ {
+ Thread.sleep(delay);
+ }
+ catch (InterruptedException ie)
+ {
+ return null;
+ }
+ }
+ else
+ {
+ _logger.info("No delay between connect retries, use tcp://host:port?connectdelay='value' to enable.");
+ }
+
+ _failedAttemps ++;
+ _currentBrokerDetail = broker;
+ return broker;
}
}
+
+ public boolean failoverAllowed()
+ {
+ // We allow to Failover provided
+ // our broker list is not empty and
+ // we haven't gone through all of them
+
+ boolean b = _connectionDetails.getBrokerCount() > 0 &&
+ _failedAttemps <= _connectionDetails.getBrokerCount();
+
+
+ _logger.info("============================================================");
+ _logger.info(toString());
+ _logger.info("FailoverAllowed " + b);
+ _logger.info("============================================================");
+
+ return b;
+ }
+
+ public void reset()
+ {
+ _failedAttemps = 0;
+ }
+
+ public void setBroker(BrokerDetails broker)
+ {
+ // not sure if this method is needed
+ }
+
+ public void setRetries(int maxRetries)
+ {
+ // no max retries we keep trying as long
+ // as we get updates
+ }
public String methodName()
{
@@ -172,7 +285,24 @@ public class FailoverExchangeMethod extends FailoverRoundRobinServers implements
{
StringBuffer sb = new StringBuffer();
sb.append("FailoverExchange:\n");
- sb.append(super.toString());
+ sb.append("\n Current Broker Index:");
+ sb.append(_currentBrokerIndex);
+ sb.append("\n Failed Attempts:");
+ sb.append(_failedAttemps);
+ sb.append("\n Orignal broker details:");
+ sb.append(_originalBrokerDetail).append("\n");
+ sb.append("\n -------- Broker List -----------\n");
+ for (int i = 0; i < _connectionDetails.getBrokerCount(); i++)
+ {
+ if (i == _currentBrokerIndex)
+ {
+ sb.append(">");
+ }
+
+ sb.append(_connectionDetails.getBrokerDetails(i));
+ sb.append("\n");
+ }
+ sb.append("--------------------------------\n");
return sb.toString();
}
}
diff --git a/qpid/java/client/src/main/java/org/apache/qpid/jms/failover/FailoverRoundRobinServers.java b/qpid/java/client/src/main/java/org/apache/qpid/jms/failover/FailoverRoundRobinServers.java
index 7190344f59..c7d8c69fff 100644
--- a/qpid/java/client/src/main/java/org/apache/qpid/jms/failover/FailoverRoundRobinServers.java
+++ b/qpid/java/client/src/main/java/org/apache/qpid/jms/failover/FailoverRoundRobinServers.java
@@ -30,7 +30,7 @@ public class FailoverRoundRobinServers implements FailoverMethod
private static final Logger _logger = LoggerFactory.getLogger(FailoverRoundRobinServers.class);
/** The default number of times to cycle through all servers */
- public static final int DEFAULT_CYCLE_RETRIES = 0;
+ public static final int DEFAULT_CYCLE_RETRIES = 1;
/** The default number of times to retry each server */
public static final int DEFAULT_SERVER_RETRIES = 0;
@@ -66,6 +66,8 @@ public class FailoverRoundRobinServers implements FailoverMethod
String cycleRetries = _connectionDetails.getFailoverOption(ConnectionURL.OPTIONS_FAILOVER_CYCLE);
+ _cycleRetries = DEFAULT_CYCLE_RETRIES;
+
if (cycleRetries != null)
{
try
@@ -74,7 +76,7 @@ public class FailoverRoundRobinServers implements FailoverMethod
}
catch (NumberFormatException nfe)
{
- _cycleRetries = DEFAULT_CYCLE_RETRIES;
+ _logger.warn("Cannot set cycle Retries, " + cycleRetries + " is not a number. Using default: " + DEFAULT_CYCLE_RETRIES);
}
}
@@ -93,8 +95,8 @@ public class FailoverRoundRobinServers implements FailoverMethod
public boolean failoverAllowed()
{
- return ((_currentCycleRetries < _cycleRetries) || (_currentServerRetry < _serverRetries)
- || (_currentBrokerIndex < (_connectionDetails.getBrokerCount() - 1)));
+ return ((_currentCycleRetries < _cycleRetries) || (_currentServerRetry < _serverRetries));
+ //|| (_currentBrokerIndex <= (_connectionDetails.getBrokerCount() - 1)));
}
public void attainedConnection()
diff --git a/qpid/java/client/src/main/java/org/apache/qpid/nclient/JMSTestCase.java b/qpid/java/client/src/main/java/org/apache/qpid/nclient/JMSTestCase.java
deleted file mode 100644
index e19058881e..0000000000
--- a/qpid/java/client/src/main/java/org/apache/qpid/nclient/JMSTestCase.java
+++ /dev/null
@@ -1,135 +0,0 @@
-/*
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- *
- */
-package org.apache.qpid.nclient;
-
-import java.util.Enumeration;
-
-import javax.jms.ExceptionListener;
-import javax.jms.JMSException;
-import javax.jms.Message;
-import javax.jms.MessageListener;
-import javax.jms.Queue;
-import javax.jms.QueueBrowser;
-
-import org.apache.qpid.client.AMQConnection;
-import org.apache.qpid.client.AMQQueue;
-import org.apache.qpid.client.AMQTopic;
-import org.apache.qpid.framing.AMQShortString;
-
-public class JMSTestCase
-{
-
- public static void main(String[] args)
- {
-
- try
- {
- javax.jms.Connection con = new AMQConnection("qpid:password=pass;username=name@tcp:localhost:5672");
- con.start();
-
- javax.jms.Session ssn = con.createSession(false, 1);
-
- javax.jms.Destination dest = new AMQQueue(new AMQShortString("direct"),"test");
- javax.jms.MessageProducer prod = ssn.createProducer(dest);
- QueueBrowser browser = ssn.createBrowser((Queue)dest, "Test = 'test'");
-
- javax.jms.TextMessage msg = ssn.createTextMessage();
- msg.setStringProperty("TEST", "test");
- msg.setText("Should get this");
- prod.send(msg);
-
- javax.jms.TextMessage msg2 = ssn.createTextMessage();
- msg2.setStringProperty("TEST", "test2");
- msg2.setText("Shouldn't get this");
- prod.send(msg2);
-
-
- Enumeration enu = browser.getEnumeration();
- for (;enu.hasMoreElements();)
- {
- System.out.println(enu.nextElement());
- System.out.println("\n");
- }
-
- javax.jms.MessageConsumer cons = ssn.createConsumer(dest, "Test = 'test'");
- javax.jms.TextMessage m = null; // (javax.jms.TextMessage)cons.receive();
- cons.setMessageListener(new MessageListener()
- {
- public void onMessage(Message m)
- {
- javax.jms.TextMessage m2 = (javax.jms.TextMessage)m;
- try
- {
- System.out.println("headers : " + m2.toString());
- System.out.println("m : " + m2.getText());
- System.out.println("\n\n");
- }
- catch(Exception e)
- {
- e.printStackTrace();
- }
- }
-
- });
-
- con.setExceptionListener(new ExceptionListener()
- {
- public void onException(JMSException e)
- {
- e.printStackTrace();
- }
- });
-
- System.out.println("Waiting");
- while (m == null)
- {
-
- }
-
- System.out.println("Exiting");
-
- /*javax.jms.TextMessage msg = ssn.createTextMessage();
- msg.setText("This is a test message");
- msg.setBooleanProperty("targetMessage", false);
- prod.send(msg);
-
- msg.setBooleanProperty("targetMessage", true);
- prod.send(msg);
-
- javax.jms.TextMessage m = (javax.jms.TextMessage)cons.receiveNoWait();
-
- if (m == null)
- {
- System.out.println("message is null");
- }
- else
- {
- System.out.println("message is not null" + m);
- }*/
-
- }
- catch(Exception e)
- {
- e.printStackTrace();
- }
- }
-
-}
diff --git a/qpid/java/client/src/test/java/org/apache/qpid/test/unit/client/connectionurl/ConnectionURLTest.java b/qpid/java/client/src/test/java/org/apache/qpid/test/unit/client/connectionurl/ConnectionURLTest.java
index d05e90823c..7400b524fd 100644
--- a/qpid/java/client/src/test/java/org/apache/qpid/test/unit/client/connectionurl/ConnectionURLTest.java
+++ b/qpid/java/client/src/test/java/org/apache/qpid/test/unit/client/connectionurl/ConnectionURLTest.java
@@ -375,6 +375,19 @@ public class ConnectionURLTest extends TestCase
assertTrue(connectionurl.getBrokerCount() == 1);
}
+ public void testClientIDWithUnderscore() throws URLSyntaxException
+ {
+ String url = "amqp://user:pass@client_id/test?brokerlist='tcp://localhost:5672'";
+
+ ConnectionURL connectionurl = new AMQConnectionURL(url);
+
+ assertTrue(connectionurl.getUsername().equals("user"));
+ assertTrue(connectionurl.getPassword().equals("pass"));
+ assertTrue(connectionurl.getVirtualHost().equals("/test"));
+ assertTrue(connectionurl.getClientName().equals("client_id"));
+
+ assertTrue(connectionurl.getBrokerCount() == 1);
+ }
public void testWrongOptionSeparatorInOptions()
{
diff --git a/qpid/java/client/src/test/java/org/apache/qpid/test/unit/client/message/BytesMessageTest.java b/qpid/java/client/src/test/java/org/apache/qpid/test/unit/client/message/BytesMessageTest.java
index bbabf0b57d..65013e7e6d 100644
--- a/qpid/java/client/src/test/java/org/apache/qpid/test/unit/client/message/BytesMessageTest.java
+++ b/qpid/java/client/src/test/java/org/apache/qpid/test/unit/client/message/BytesMessageTest.java
@@ -559,7 +559,7 @@ public class BytesMessageTest extends TestCase
JMSBytesMessage bm = TestMessageHelper.newJMSBytesMessage();
bm.reset();
String result = bm.toBodyString();
- assertNull(result);
+ assertEquals("\"\"", result);
}
public static junit.framework.Test suite()
diff --git a/qpid/java/client/src/test/java/org/apache/qpid/test/unit/client/message/StreamMessageTest.java b/qpid/java/client/src/test/java/org/apache/qpid/test/unit/client/message/StreamMessageTest.java
index 802f1e6c2e..085dd81079 100644
--- a/qpid/java/client/src/test/java/org/apache/qpid/test/unit/client/message/StreamMessageTest.java
+++ b/qpid/java/client/src/test/java/org/apache/qpid/test/unit/client/message/StreamMessageTest.java
@@ -435,7 +435,7 @@ public class StreamMessageTest extends TestCase
JMSStreamMessage bm = TestMessageHelper.newJMSStreamMessage();
bm.reset();
String result = bm.toBodyString();
- assertNull(result);
+ assertEquals("\"\"", result);
}
private void checkConversionsFail(StreamMessage sm, int[] conversions) throws JMSException
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 a881f6a822..566a222897 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
@@ -44,7 +44,9 @@ public class TestAMQSession extends AMQSession<BasicMessageConsumer_0_8, BasicMe
}
- public void sendQueueBind(AMQShortString queueName, AMQShortString routingKey, FieldTable arguments, AMQShortString exchangeName, AMQDestination destination) throws AMQException, FailoverException
+ public void sendQueueBind(AMQShortString queueName, AMQShortString routingKey, FieldTable arguments,
+ AMQShortString exchangeName, AMQDestination destination,
+ boolean nowait) throws AMQException, FailoverException
{
}
@@ -129,7 +131,8 @@ public class TestAMQSession extends AMQSession<BasicMessageConsumer_0_8, BasicMe
}
- public void sendQueueDeclare(AMQDestination amqd, AMQProtocolHandler protocolHandler) throws AMQException, FailoverException
+ public void sendQueueDeclare(AMQDestination amqd, AMQProtocolHandler protocolHandler,
+ boolean nowait) throws AMQException, FailoverException
{
}
diff --git a/qpid/java/common.xml b/qpid/java/common.xml
index e9e007c8ef..511cdc6a10 100644
--- a/qpid/java/common.xml
+++ b/qpid/java/common.xml
@@ -23,7 +23,7 @@
<dirname property="project.root" file="${ant.file.common}"/>
<property name="project.name" value="qpid"/>
- <property name="project.version" value="M4"/>
+ <property name="project.version" value="0.5"/>
<property name="project.namever" value="${project.name}-${project.version}"/>
<property name="resources" location="${project.root}/resources"/>
diff --git a/qpid/java/common/Composite.tpl b/qpid/java/common/Composite.tpl
index 17cf846d8c..c46d0a12cc 100644
--- a/qpid/java/common/Composite.tpl
+++ b/qpid/java/common/Composite.tpl
@@ -145,6 +145,7 @@ if options or base == "Method":
if base == "Method":
out(""" case SYNC: this.setSync(true); break;
case BATCH: this.setBatch(true); break;
+ case UNRELIABLE: this.setUnreliable(true); break;
""")
out(""" case NONE: break;
default: throw new IllegalArgumentException("invalid option: " + _options[i]);
diff --git a/qpid/java/common/Option.tpl b/qpid/java/common/Option.tpl
index 776b211ad5..c22b35b999 100644
--- a/qpid/java/common/Option.tpl
+++ b/qpid/java/common/Option.tpl
@@ -37,5 +37,6 @@ for c in composites:
options[option] = None
out(" $option,\n")}
BATCH,
+ UNRELIABLE,
NONE
}
diff --git a/qpid/java/common/src/main/java/org/apache/qpid/ToyClient.java b/qpid/java/common/src/main/java/org/apache/qpid/ToyClient.java
index 3491af8cd2..5b2db10613 100644
--- a/qpid/java/common/src/main/java/org/apache/qpid/ToyClient.java
+++ b/qpid/java/common/src/main/java/org/apache/qpid/ToyClient.java
@@ -37,6 +37,8 @@ class ToyClient implements SessionListener
{
public void opened(Session ssn) {}
+ public void resumed(Session ssn) {}
+
public void exception(Session ssn, SessionException exc)
{
exc.printStackTrace();
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 adaf2ccd37..e0f239b566 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
@@ -74,7 +74,7 @@ public class Connection extends ConnectionInvoker
final private Map<Integer,Session> channels = new HashMap<Integer,Session>();
private State state = NEW;
- private Object lock = new Object();
+ final private Object lock = new Object();
private long timeout = 60000;
private ConnectionListener listener = new DefaultConnectionListener();
private ConnectionException error = null;
@@ -164,7 +164,7 @@ public class Connection extends ConnectionInvoker
public void connect(String host, int port, String vhost, String username, String password, boolean ssl)
{
- connect(host, port, vhost, username, password, false,"PLAIN");
+ connect(host, port, vhost, username, password, ssl,"PLAIN");
}
public void connect(String host, int port, String vhost, String username, String password, boolean ssl,String saslMechs)
diff --git a/qpid/java/common/src/main/java/org/apache/qpid/transport/Echo.java b/qpid/java/common/src/main/java/org/apache/qpid/transport/Echo.java
index c1031c9a1c..0e969464ab 100644
--- a/qpid/java/common/src/main/java/org/apache/qpid/transport/Echo.java
+++ b/qpid/java/common/src/main/java/org/apache/qpid/transport/Echo.java
@@ -37,6 +37,8 @@ public class Echo implements SessionListener
public void opened(Session ssn) {}
+ public void resumed(Session ssn) {}
+
public void message(Session ssn, MessageTransfer xfr)
{
int id = xfr.getId();
diff --git a/qpid/java/common/src/main/java/org/apache/qpid/transport/Method.java b/qpid/java/common/src/main/java/org/apache/qpid/transport/Method.java
index 09cfd119be..611c742fb1 100644
--- a/qpid/java/common/src/main/java/org/apache/qpid/transport/Method.java
+++ b/qpid/java/common/src/main/java/org/apache/qpid/transport/Method.java
@@ -48,6 +48,7 @@ public abstract class Method extends Struct implements ProtocolEvent
private boolean idSet = false;
private boolean sync = false;
private boolean batch = false;
+ private boolean unreliable = false;
public final int getId()
{
@@ -90,6 +91,16 @@ public abstract class Method extends Struct implements ProtocolEvent
this.batch = value;
}
+ public final boolean isUnreliable()
+ {
+ return unreliable;
+ }
+
+ final void setUnreliable(boolean value)
+ {
+ this.unreliable = value;
+ }
+
public abstract boolean hasPayload();
public Header getHeader()
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 f94edcc655..3dca4fc44e 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
@@ -53,13 +53,15 @@ public class Session extends SessionInvoker
private static final Logger log = Logger.get(Session.class);
- enum State { NEW, DETACHED, OPEN, CLOSING, CLOSED }
+ enum State { NEW, DETACHED, RESUMING, OPEN, CLOSING, CLOSED }
class DefaultSessionListener implements SessionListener
{
public void opened(Session ssn) {}
+ public void resumed(Session ssn) {}
+
public void message(Session ssn, MessageTransfer xfr)
{
log.info("message: %s", xfr);
@@ -107,6 +109,8 @@ public class Session extends SessionInvoker
private volatile boolean flowControl = false;
private Semaphore credit = new Semaphore(0);
+ private Thread resumer = null;
+
Session(Connection connection, Binary name, long expiry)
{
this.connection = connection;
@@ -234,15 +238,21 @@ public class Session extends SessionInvoker
for (int i = maxComplete + 1; lt(i, commandsOut); i++)
{
Method m = commands[mod(i, commands.length)];
- if (m != null)
+ if (m == null)
{
- sessionCommandPoint(m.getId(), 0);
- send(m);
+ m = new ExecutionSync();
+ m.setId(i);
}
+ sessionCommandPoint(m.getId(), 0);
+ send(m);
}
sessionCommandPoint(commandsOut, 0);
sessionFlush(COMPLETED);
+ resumer = Thread.currentThread();
+ state = RESUMING;
+ listener.resumed(this);
+ resumer = null;
}
}
@@ -384,7 +394,15 @@ public class Session extends SessionInvoker
{
copy = processed.copy();
}
- sessionCompleted(copy, options);
+
+ synchronized (commands)
+ {
+ if (state == DETACHED || state == CLOSING)
+ {
+ return;
+ }
+ sessionCompleted(copy, options);
+ }
}
void knownComplete(RangeSet kc)
@@ -484,12 +502,25 @@ public class Session extends SessionInvoker
synchronized (commands)
{
+ if (state == DETACHED && m.isUnreliable())
+ {
+ Thread current = Thread.currentThread();
+ if (!current.equals(resumer))
+ {
+ return;
+ }
+ }
+
if (state != OPEN && state != CLOSED)
{
- Waiter w = new Waiter(commands, timeout);
- while (w.hasTime() && (state != OPEN && state != CLOSED))
+ Thread current = Thread.currentThread();
+ if (!current.equals(resumer))
{
- w.await();
+ Waiter w = new Waiter(commands, timeout);
+ while (w.hasTime() && (state != OPEN && state != CLOSED))
+ {
+ w.await();
+ }
}
}
@@ -497,8 +528,24 @@ public class Session extends SessionInvoker
{
case OPEN:
break;
+ case RESUMING:
+ Thread current = Thread.currentThread();
+ if (!current.equals(resumer))
+ {
+ throw new SessionException
+ ("timed out waiting for resume to finish");
+ }
+ break;
case CLOSED:
- throw new SessionClosedException();
+ ExecutionException exc = getException();
+ if (exc != null)
+ {
+ throw new SessionException(exc);
+ }
+ else
+ {
+ throw new SessionClosedException();
+ }
default:
throw new SessionException
(String.format
@@ -512,9 +559,9 @@ public class Session extends SessionInvoker
if (isFull(next))
{
Waiter w = new Waiter(commands, timeout);
- while (w.hasTime() && isFull(next))
+ while (w.hasTime() && isFull(next) && state != CLOSED)
{
- if (state == OPEN)
+ if (state == OPEN || state == RESUMING)
{
try
{
@@ -538,6 +585,19 @@ public class Session extends SessionInvoker
}
}
+ if (state == CLOSED)
+ {
+ ExecutionException exc = getException();
+ if (exc != null)
+ {
+ throw new SessionException(exc);
+ }
+ else
+ {
+ throw new SessionClosedException();
+ }
+ }
+
if (isFull(next))
{
throw new SessionException("timed out waiting for completion");
@@ -547,7 +607,7 @@ public class Session extends SessionInvoker
{
sessionCommandPoint(0, 0);
}
- if (expiry > 0)
+ if (expiry > 0 && !m.isUnreliable())
{
commands[mod(next, commands.length)] = m;
commandBytes += m.getBodySize();
@@ -815,9 +875,9 @@ public class Session extends SessionInvoker
{
throw new SessionException("close() timed out");
}
-
- connection.removeSession(this);
}
+
+ connection.removeSession(this);
}
public void exception(Throwable t)
@@ -829,7 +889,7 @@ public class Session extends SessionInvoker
{
synchronized (commands)
{
- if (expiry == 0)
+ if (expiry == 0 || getException() != null)
{
state = CLOSED;
}
diff --git a/qpid/java/common/src/main/java/org/apache/qpid/transport/SessionListener.java b/qpid/java/common/src/main/java/org/apache/qpid/transport/SessionListener.java
index 63690177f9..eb650eb9ed 100644
--- a/qpid/java/common/src/main/java/org/apache/qpid/transport/SessionListener.java
+++ b/qpid/java/common/src/main/java/org/apache/qpid/transport/SessionListener.java
@@ -31,6 +31,8 @@ public interface SessionListener
void opened(Session session);
+ void resumed(Session session);
+
void message(Session ssn, MessageTransfer xfr);
void exception(Session session, SessionException exception);
diff --git a/qpid/java/common/src/main/java/org/apache/qpid/transport/Sink.java b/qpid/java/common/src/main/java/org/apache/qpid/transport/Sink.java
index 622993effb..88870284f6 100644
--- a/qpid/java/common/src/main/java/org/apache/qpid/transport/Sink.java
+++ b/qpid/java/common/src/main/java/org/apache/qpid/transport/Sink.java
@@ -87,6 +87,8 @@ public class Sink implements SessionListener
public void opened(Session ssn) {}
+ public void resumed(Session ssn) {}
+
public void message(Session ssn, MessageTransfer xfr)
{
count++;
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 532c19ec18..d18a0f64db 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
@@ -59,12 +59,23 @@ public final class BBEncoder extends AbstractEncoder
return slice;
}
+ public ByteBuffer buffer()
+ {
+ int pos = out.position();
+ out.position(segment);
+ ByteBuffer slice = out.slice();
+ slice.limit(pos - segment);
+ out.position(pos);
+ return slice;
+ }
+
private void grow(int size)
{
ByteBuffer old = out;
int capacity = old.capacity();
out = ByteBuffer.allocate(Math.max(capacity + size, 2*capacity));
out.order(ByteOrder.BIG_ENDIAN);
+ old.flip();
out.put(old);
}
diff --git a/qpid/java/common/src/main/java/org/apache/qpid/util/FileUtils.java b/qpid/java/common/src/main/java/org/apache/qpid/util/FileUtils.java
index 3e13259ee3..e4bfb9c664 100644
--- a/qpid/java/common/src/main/java/org/apache/qpid/util/FileUtils.java
+++ b/qpid/java/common/src/main/java/org/apache/qpid/util/FileUtils.java
@@ -252,16 +252,16 @@ public class FileUtils
{
for (File subFile : file.listFiles())
{
- success = delete(subFile, true) & success ;
+ success = delete(subFile, true) && success;
}
- return file.delete();
+ return success && file.delete();
}
return false;
}
- return success && file.delete();
+ return file.delete();
}
diff --git a/qpid/java/common/src/main/java/org/apache/qpid/util/PropertiesUtils.java b/qpid/java/common/src/main/java/org/apache/qpid/util/PropertiesUtils.java
deleted file mode 100644
index d90e3b1a17..0000000000
--- a/qpid/java/common/src/main/java/org/apache/qpid/util/PropertiesUtils.java
+++ /dev/null
@@ -1,200 +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.util;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.net.URL;
-import java.util.Iterator;
-import java.util.Properties;
-
-/**
- * PropertiesHelper defines some static methods which are useful when working with properties
- * files.
- *
- * <p><table id="crc"><caption>CRC Card</caption>
- * <tr><th> Responsibilities <th> Collaborations
- * <tr><td> Read properties from an input stream
- * <tr><td> Read properties from a file
- * <tr><td> Read properties from a URL
- * <tr><td> Read properties given a path to a file
- * <tr><td> Trim any whitespace from property values
- * </table>
- */
-public class PropertiesUtils
-{
- /** Used for logging. */
- private static final Logger log = LoggerFactory.getLogger(PropertiesUtils.class);
-
- /**
- * Get properties from an input stream.
- *
- * @param is The input stream.
- *
- * @return The properties loaded from the input stream.
- *
- * @throws IOException If the is an I/O error reading from the stream.
- */
- public static Properties getProperties(InputStream is) throws IOException
- {
- log.debug("getProperties(InputStream): called");
-
- // Create properties object laoded from input stream
- Properties properties = new Properties();
-
- properties.load(is);
-
- return properties;
- }
-
- /**
- * Get properties from a file.
- *
- * @param file The file.
- *
- * @return The properties loaded from the file.
- *
- * @throws IOException If there is an I/O error reading from the file.
- */
- public static Properties getProperties(File file) throws IOException
- {
- log.debug("getProperties(File): called");
-
- // Open the file as an input stream
- InputStream is = new FileInputStream(file);
-
- // Create properties object loaded from the stream
- Properties properties = getProperties(is);
-
- // Close the file
- is.close();
-
- return properties;
- }
-
- /**
- * Get properties from a url.
- *
- * @param url The URL.
- *
- * @return The properties loaded from the url.
- *
- * @throws IOException If there is an I/O error reading from the URL.
- */
- public static Properties getProperties(URL url) throws IOException
- {
- log.debug("getProperties(URL): called");
-
- // Open the URL as an input stream
- InputStream is = url.openStream();
-
- // Create properties object loaded from the stream
- Properties properties = getProperties(is);
-
- // Close the url
- is.close();
-
- return properties;
- }
-
- /**
- * Get properties from a path name. The path name may refer to either a file or a URL.
- *
- * @param pathname The path name.
- *
- * @return The properties loaded from the file or URL.
- *
- * @throws IOException If there is an I/O error reading from the URL or file named by the path.
- */
- public static Properties getProperties(String pathname) throws IOException
- {
- log.debug("getProperties(String): called");
-
- // Check that the path is not null
- if (pathname == null)
- {
- return null;
- }
-
- // Check if the path is a URL
- if (isURL(pathname))
- {
- // The path is a URL
- return getProperties(new URL(pathname));
- }
- else
- {
- // Assume the path is a file name
- return getProperties(new File(pathname));
- }
- }
-
- /**
- * Trims whitespace from property values. This method returns a new set of properties
- * the same as the properties specified as an argument but with any white space removed by
- * the {@link java.lang.String#trim} method.
- *
- * @param properties The properties to trim whitespace from.
- *
- * @return The white space trimmed properties.
- */
- public static Properties trim(Properties properties)
- {
- Properties trimmedProperties = new Properties();
-
- // Loop over all the properties
- for (Iterator i = properties.keySet().iterator(); i.hasNext();)
- {
- String next = (String) i.next();
- String nextValue = properties.getProperty(next);
-
- // Trim the value if it is not null
- if (nextValue != null)
- {
- nextValue.trim();
- }
-
- // Store the trimmed value in the trimmed properties
- trimmedProperties.setProperty(next, nextValue);
- }
-
- return trimmedProperties;
- }
-
- /**
- * Helper method. Guesses whether a string is a URL or not. A String is considered to be a url if it begins with
- * http:, ftp:, or uucp:.
- *
- * @param name The string to test for being a URL.
- *
- * @return True if the string is a URL and false if not.
- */
- private static boolean isURL(String name)
- {
- return (name.toLowerCase().startsWith("http:") || name.toLowerCase().startsWith("ftp:")
- || name.toLowerCase().startsWith("uucp:"));
- }
-}
diff --git a/qpid/java/common/src/test/java/org/apache/qpid/transport/ConnectionTest.java b/qpid/java/common/src/test/java/org/apache/qpid/transport/ConnectionTest.java
index dca6264367..8aa8c5f647 100644
--- a/qpid/java/common/src/test/java/org/apache/qpid/transport/ConnectionTest.java
+++ b/qpid/java/common/src/test/java/org/apache/qpid/transport/ConnectionTest.java
@@ -74,6 +74,8 @@ public class ConnectionTest extends TestCase implements SessionListener
public void opened(Session ssn) {}
+ public void resumed(Session ssn) {}
+
public void message(final Session ssn, MessageTransfer xfr)
{
if (queue)
@@ -122,6 +124,13 @@ public class ConnectionTest extends TestCase implements SessionListener
{
// do nothing
}
+ else if (body.startsWith("EXCP"))
+ {
+ ExecutionException exc = new ExecutionException();
+ exc.setDescription("intentional exception for testing");
+ ssn.invoke(exc);
+ ssn.close();
+ }
else
{
throw new IllegalArgumentException
@@ -138,9 +147,14 @@ public class ConnectionTest extends TestCase implements SessionListener
private void send(Session ssn, String msg)
{
+ send(ssn, msg, false);
+ }
+
+ private void send(Session ssn, String msg, boolean sync)
+ {
ssn.messageTransfer
("xxx", MessageAcceptMode.NONE, MessageAcquireMode.PRE_ACQUIRED,
- null, msg);
+ null, msg, sync ? SYNC : NONE);
}
private Connection connect(final Condition closed)
@@ -277,6 +291,7 @@ public class ConnectionTest extends TestCase implements SessionListener
class TestSessionListener implements SessionListener
{
public void opened(Session s) {}
+ public void resumed(Session s) {}
public void exception(Session s, SessionException e) {}
public void message(Session s, MessageTransfer xfr)
{
@@ -391,4 +406,41 @@ public class ConnectionTest extends TestCase implements SessionListener
conn.close();
}
+ public void testExecutionExceptionInvoke() throws Exception
+ {
+ startServer();
+
+ Connection conn = new Connection();
+ conn.connect("localhost", port, null, "guest", "guest");
+ Session ssn = conn.createSession();
+ send(ssn, "EXCP 0");
+ Thread.sleep(3000);
+ try
+ {
+ send(ssn, "SINK 1");
+ }
+ catch (SessionException exc)
+ {
+ assertNotNull(exc.getException());
+ }
+ }
+
+ public void testExecutionExceptionSync() throws Exception
+ {
+ startServer();
+
+ Connection conn = new Connection();
+ conn.connect("localhost", port, null, "guest", "guest");
+ Session ssn = conn.createSession();
+ send(ssn, "EXCP 0", true);
+ try
+ {
+ ssn.sync();
+ }
+ catch (SessionException exc)
+ {
+ assertNotNull(exc.getException());
+ }
+ }
+
}
diff --git a/qpid/java/common/src/test/java/org/apache/qpid/transport/codec/BBEncoderTest.java b/qpid/java/common/src/test/java/org/apache/qpid/transport/codec/BBEncoderTest.java
new file mode 100644
index 0000000000..79bf184fe2
--- /dev/null
+++ b/qpid/java/common/src/test/java/org/apache/qpid/transport/codec/BBEncoderTest.java
@@ -0,0 +1,47 @@
+/*
+ *
+ * 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.codec;
+
+import junit.framework.TestCase;
+
+import java.nio.ByteBuffer;
+
+/**
+ * BBEncoderTest
+ *
+ */
+
+public class BBEncoderTest extends TestCase
+{
+
+ public void testGrow()
+ {
+ BBEncoder enc = new BBEncoder(4);
+ enc.writeInt32(0xDEADBEEF);
+ ByteBuffer buf = enc.buffer();
+ assertEquals(0xDEADBEEF, buf.getInt(0));
+ enc.writeInt32(0xBEEFDEAD);
+ buf = enc.buffer();
+ assertEquals(0xDEADBEEF, buf.getInt(0));
+ assertEquals(0xBEEFDEAD, buf.getInt(4));
+ }
+
+}
diff --git a/qpid/java/common/src/test/java/org/apache/qpid/util/FileUtilsTest.java b/qpid/java/common/src/test/java/org/apache/qpid/util/FileUtilsTest.java
index fb367d042c..94e7e20a86 100644
--- a/qpid/java/common/src/test/java/org/apache/qpid/util/FileUtilsTest.java
+++ b/qpid/java/common/src/test/java/org/apache/qpid/util/FileUtilsTest.java
@@ -280,6 +280,30 @@ public class FileUtilsTest extends TestCase
checkFileLists(filesBefore, filesAfter);
}
+ public void testDeleteNonExistentFile()
+ {
+ File test = new File("FileUtilsTest-testDelete-"+System.currentTimeMillis());
+
+ assertTrue("File exists", !test.exists());
+ assertFalse("File is a directory", test.isDirectory());
+
+ assertTrue("Delete Succeeded ", !FileUtils.delete(test, true));
+ }
+
+ public void testDeleteNull()
+ {
+ try
+ {
+ FileUtils.delete(null, true);
+ fail("Delete with null value should throw NPE.");
+ }
+ catch (NullPointerException npe)
+ {
+ // expected path
+ }
+ }
+
+
/**
* Given two lists of File arrays ensure they are the same length and all entries in Before are in After
*
diff --git a/qpid/java/cpp.cluster.testprofile b/qpid/java/cpp.cluster.testprofile
index 1807ae098b..765eb714f3 100644
--- a/qpid/java/cpp.cluster.testprofile
+++ b/qpid/java/cpp.cluster.testprofile
@@ -3,3 +3,6 @@ broker=${project.root}/../cpp/src/qpidd --load-module ${project.root}/../cpp/src
test.excludesfile=${project.root}/ExcludeList ${project.root}/XAExcludeList ${project.root}/010ExcludeList
profile.clustered=true
+profile.failoverMsgCount=10
+profile.failoverIterations=10
+profile.failoverRandomSeed=20080921
diff --git a/qpid/java/lib/commons-beanutils-core-1.8.0.jar b/qpid/java/lib/commons-beanutils-core-1.8.0.jar
new file mode 100644
index 0000000000..87c15f4565
--- /dev/null
+++ b/qpid/java/lib/commons-beanutils-core-1.8.0.jar
Binary files differ
diff --git a/qpid/java/lib/commons-configuration-1.2.jar b/qpid/java/lib/commons-configuration-1.2.jar
deleted file mode 100644
index 574d0ac789..0000000000
--- a/qpid/java/lib/commons-configuration-1.2.jar
+++ /dev/null
Binary files differ
diff --git a/qpid/java/lib/commons-configuration-1.6.jar b/qpid/java/lib/commons-configuration-1.6.jar
new file mode 100644
index 0000000000..2d4689a1b8
--- /dev/null
+++ b/qpid/java/lib/commons-configuration-1.6.jar
Binary files differ
diff --git a/qpid/java/lib/commons-digester-1.8.1.jar b/qpid/java/lib/commons-digester-1.8.1.jar
new file mode 100644
index 0000000000..7abda9696a
--- /dev/null
+++ b/qpid/java/lib/commons-digester-1.8.1.jar
Binary files differ
diff --git a/qpid/java/lib/org.apache.commons.codec_1.3.0.v20080530-1600.jar b/qpid/java/lib/org.apache.commons.codec_1.3.0.v20080530-1600.jar
new file mode 100644
index 0000000000..d9b4c8ea1f
--- /dev/null
+++ b/qpid/java/lib/org.apache.commons.codec_1.3.0.v20080530-1600.jar
Binary files differ
diff --git a/qpid/java/lib/org.eclipse.equinox.launcher.gtk.linux.x86_64_1.0.101.R34x_v20080731/META-INF/ECLIPSE.RSA b/qpid/java/lib/org.eclipse.equinox.launcher.gtk.linux.x86_64_1.0.101.R34x_v20080731/META-INF/ECLIPSE.RSA
new file mode 100644
index 0000000000..df6b24ad57
--- /dev/null
+++ b/qpid/java/lib/org.eclipse.equinox.launcher.gtk.linux.x86_64_1.0.101.R34x_v20080731/META-INF/ECLIPSE.RSA
Binary files differ
diff --git a/qpid/java/lib/org.eclipse.equinox.launcher.gtk.linux.x86_64_1.0.101.R34x_v20080731/META-INF/ECLIPSE.SF b/qpid/java/lib/org.eclipse.equinox.launcher.gtk.linux.x86_64_1.0.101.R34x_v20080731/META-INF/ECLIPSE.SF
new file mode 100644
index 0000000000..4193e97338
--- /dev/null
+++ b/qpid/java/lib/org.eclipse.equinox.launcher.gtk.linux.x86_64_1.0.101.R34x_v20080731/META-INF/ECLIPSE.SF
@@ -0,0 +1,17 @@
+Signature-Version: 1.0
+SHA1-Digest-Manifest: gnfArgp6eM77c1JxQF9X3q9/Hd8=
+Created-By: 1.5.0 (IBM Corporation)
+SHA1-Digest-Manifest-Main-Attributes: hR6QNnvCGlzBxiyTmh4DMZ03Yyg=
+
+Name: about.html
+SHA1-Digest: xGcp/Hbq/ywyvVWkPzD/2vkIzdY=
+
+Name: eclipse_1115.so
+SHA1-Digest: 33jSy/p2jY6bvgg4W0xBlxjxMWA=
+
+Name: META-INF/eclipse.inf
+SHA1-Digest: SAqY+5ITAL0mkdYeijlSRhyIaZk=
+
+Name: launcher.gtk.linux.x86_64.properties
+SHA1-Digest: Q2rsj7VmfkLLH24miqu0v+2sZjE=
+
diff --git a/qpid/java/lib/org.eclipse.equinox.launcher.gtk.linux.x86_64_1.0.101.R34x_v20080731/META-INF/MANIFEST.MF b/qpid/java/lib/org.eclipse.equinox.launcher.gtk.linux.x86_64_1.0.101.R34x_v20080731/META-INF/MANIFEST.MF
new file mode 100644
index 0000000000..b790c0af9a
--- /dev/null
+++ b/qpid/java/lib/org.eclipse.equinox.launcher.gtk.linux.x86_64_1.0.101.R34x_v20080731/META-INF/MANIFEST.MF
@@ -0,0 +1,25 @@
+Manifest-Version: 1.0
+Bundle-SymbolicName: org.eclipse.equinox.launcher.gtk.linux.x86_64;sin
+ gleton:=true
+Bundle-ManifestVersion: 2
+Bundle-Localization: launcher.gtk.linux.x86_64
+Bundle-Name: %pluginName
+Eclipse-PlatformFilter: (& (osgi.ws=gtk) (osgi.os=linux) (osgi.arch=x8
+ 6_64))
+Bundle-Version: 1.0.101.R34x_v20080731
+Fragment-Host: org.eclipse.equinox.launcher;bundle-version="[1.0.0,1.1
+ .0)"
+Bundle-Vendor: %providerName
+
+Name: eclipse_1115.so
+SHA1-Digest: l0VkVxLXANjcUEWTLRqXKUmIfn8=
+
+Name: about.html
+SHA1-Digest: a9lDHrGuLPkvHBUhsqWU+V2mhPw=
+
+Name: META-INF/eclipse.inf
+SHA1-Digest: KyT9FF7C7t86NoBoa2kZT3ZJBfw=
+
+Name: launcher.gtk.linux.x86_64.properties
+SHA1-Digest: thXaNI0tmsHrCOYNbQBW2zzAh+Q=
+
diff --git a/qpid/java/lib/org.eclipse.equinox.launcher.gtk.linux.x86_64_1.0.101.R34x_v20080731/META-INF/eclipse.inf b/qpid/java/lib/org.eclipse.equinox.launcher.gtk.linux.x86_64_1.0.101.R34x_v20080731/META-INF/eclipse.inf
new file mode 100644
index 0000000000..7864d3c4c3
--- /dev/null
+++ b/qpid/java/lib/org.eclipse.equinox.launcher.gtk.linux.x86_64_1.0.101.R34x_v20080731/META-INF/eclipse.inf
@@ -0,0 +1,3 @@
+#Processed using Jarprocessor
+pack200.args = -E4
+pack200.conditioned = true
diff --git a/qpid/java/lib/org.eclipse.equinox.launcher.gtk.linux.x86_64_1.0.101.R34x_v20080731/about.html b/qpid/java/lib/org.eclipse.equinox.launcher.gtk.linux.x86_64_1.0.101.R34x_v20080731/about.html
new file mode 100644
index 0000000000..395df3ba90
--- /dev/null
+++ b/qpid/java/lib/org.eclipse.equinox.launcher.gtk.linux.x86_64_1.0.101.R34x_v20080731/about.html
@@ -0,0 +1,28 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"/>
+<title>About</title>
+</head>
+<body lang="EN-US">
+<h2>About This Content</h2>
+
+<p>June 5, 2006</p>
+<h3>License</h3>
+
+<p>The Eclipse Foundation makes available all content in this plug-in (&quot;Content&quot;).
+Unless otherwise indicated below, the Content is provided to you under the terms and conditions of the
+Eclipse Public License Version 1.0 (&quot;EPL&quot;). A copy of the EPL is available
+at <a href="http://www.eclipse.org/org/documents/epl-v10.php">http://www.eclipse.org/legal/epl-v10.html</a>.
+For purposes of the EPL, &quot;Program&quot; will mean the Content.</p>
+
+<p>If you did not receive this Content directly from the Eclipse Foundation, the Content is
+being redistributed by another party (&quot;Redistributor&quot;) and different terms and conditions may
+apply to your use of any object code in the Content. Check the Redistributor&rsquo;s license
+that was provided with the Content. If no such license exists, contact the Redistributor. Unless otherwise
+indicated below, the terms and conditions of the EPL still apply to any source code in the Content
+and such source code may be obtained at <a href="http://www.eclipse.org/">http://www.eclipse.org</a>.</p>
+
+</body>
+</html> \ No newline at end of file
diff --git a/qpid/java/lib/org.eclipse.equinox.launcher.gtk.linux.x86_64_1.0.101.R34x_v20080731/eclipse_1115.so b/qpid/java/lib/org.eclipse.equinox.launcher.gtk.linux.x86_64_1.0.101.R34x_v20080731/eclipse_1115.so
new file mode 100644
index 0000000000..8bf855533c
--- /dev/null
+++ b/qpid/java/lib/org.eclipse.equinox.launcher.gtk.linux.x86_64_1.0.101.R34x_v20080731/eclipse_1115.so
Binary files differ
diff --git a/qpid/java/lib/org.eclipse.equinox.launcher.gtk.linux.x86_64_1.0.101.R34x_v20080731/launcher.gtk.linux.x86_64.properties b/qpid/java/lib/org.eclipse.equinox.launcher.gtk.linux.x86_64_1.0.101.R34x_v20080731/launcher.gtk.linux.x86_64.properties
new file mode 100644
index 0000000000..da448aadbb
--- /dev/null
+++ b/qpid/java/lib/org.eclipse.equinox.launcher.gtk.linux.x86_64_1.0.101.R34x_v20080731/launcher.gtk.linux.x86_64.properties
@@ -0,0 +1,12 @@
+###############################################################################
+# Copyright (c) 2007 IBM Corporation and others.
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Eclipse Public License v1.0
+# which accompanies this distribution, and is available at
+# http://www.eclipse.org/legal/epl-v10.html
+#
+# Contributors:
+# IBM Corporation - initial API and implementation
+###############################################################################
+pluginName = Equinox Launcher Linux X86_64 Fragment
+providerName = Eclipse.org
diff --git a/qpid/java/lib/org.eclipse.equinox.launcher.gtk.solaris.sparc_1.0.101.R34x_v20080731/META-INF/ECLIPSE.RSA b/qpid/java/lib/org.eclipse.equinox.launcher.gtk.solaris.sparc_1.0.101.R34x_v20080731/META-INF/ECLIPSE.RSA
new file mode 100644
index 0000000000..81599f2e21
--- /dev/null
+++ b/qpid/java/lib/org.eclipse.equinox.launcher.gtk.solaris.sparc_1.0.101.R34x_v20080731/META-INF/ECLIPSE.RSA
Binary files differ
diff --git a/qpid/java/lib/org.eclipse.equinox.launcher.gtk.solaris.sparc_1.0.101.R34x_v20080731/META-INF/ECLIPSE.SF b/qpid/java/lib/org.eclipse.equinox.launcher.gtk.solaris.sparc_1.0.101.R34x_v20080731/META-INF/ECLIPSE.SF
new file mode 100644
index 0000000000..20fe507cdf
--- /dev/null
+++ b/qpid/java/lib/org.eclipse.equinox.launcher.gtk.solaris.sparc_1.0.101.R34x_v20080731/META-INF/ECLIPSE.SF
@@ -0,0 +1,17 @@
+Signature-Version: 1.0
+SHA1-Digest-Manifest: kR1kAxZlcW3W0rm/xjIZED9LrAo=
+Created-By: 1.5.0 (IBM Corporation)
+SHA1-Digest-Manifest-Main-Attributes: pqNWWWTyBz8hsANASpU3hoVl9kc=
+
+Name: about.html
+SHA1-Digest: xGcp/Hbq/ywyvVWkPzD/2vkIzdY=
+
+Name: eclipse_1115.so
+SHA1-Digest: o5PGzpcLRdWF5shzEwmVFCwZrb0=
+
+Name: META-INF/eclipse.inf
+SHA1-Digest: SAqY+5ITAL0mkdYeijlSRhyIaZk=
+
+Name: launcher.gtk.solaris.sparc.properties
+SHA1-Digest: gu+HrnaK+kn508ppLY/iXys12yA=
+
diff --git a/qpid/java/lib/org.eclipse.equinox.launcher.gtk.solaris.sparc_1.0.101.R34x_v20080731/META-INF/MANIFEST.MF b/qpid/java/lib/org.eclipse.equinox.launcher.gtk.solaris.sparc_1.0.101.R34x_v20080731/META-INF/MANIFEST.MF
new file mode 100644
index 0000000000..f81e6141bb
--- /dev/null
+++ b/qpid/java/lib/org.eclipse.equinox.launcher.gtk.solaris.sparc_1.0.101.R34x_v20080731/META-INF/MANIFEST.MF
@@ -0,0 +1,25 @@
+Manifest-Version: 1.0
+Bundle-SymbolicName: org.eclipse.equinox.launcher.gtk.solaris.sparc;si
+ ngleton:=true
+Bundle-ManifestVersion: 2
+Bundle-Localization: launcher.gtk.solaris.sparc
+Bundle-Name: %pluginName
+Eclipse-PlatformFilter: (& (osgi.ws=gtk) (osgi.os=solaris) (osgi.arch=
+ sparc))
+Bundle-Version: 1.0.101.R34x_v20080731
+Fragment-Host: org.eclipse.equinox.launcher;bundle-version="[1.0.0,1.1
+ .0)"
+Bundle-Vendor: %providerName
+
+Name: eclipse_1115.so
+SHA1-Digest: 5km5rPngvbWH3aWIYrl+xMejhCE=
+
+Name: about.html
+SHA1-Digest: a9lDHrGuLPkvHBUhsqWU+V2mhPw=
+
+Name: META-INF/eclipse.inf
+SHA1-Digest: KyT9FF7C7t86NoBoa2kZT3ZJBfw=
+
+Name: launcher.gtk.solaris.sparc.properties
+SHA1-Digest: B/N7qN8v4Os5flFl4mE2UaqnMZs=
+
diff --git a/qpid/java/lib/org.eclipse.equinox.launcher.gtk.solaris.sparc_1.0.101.R34x_v20080731/META-INF/eclipse.inf b/qpid/java/lib/org.eclipse.equinox.launcher.gtk.solaris.sparc_1.0.101.R34x_v20080731/META-INF/eclipse.inf
new file mode 100644
index 0000000000..7864d3c4c3
--- /dev/null
+++ b/qpid/java/lib/org.eclipse.equinox.launcher.gtk.solaris.sparc_1.0.101.R34x_v20080731/META-INF/eclipse.inf
@@ -0,0 +1,3 @@
+#Processed using Jarprocessor
+pack200.args = -E4
+pack200.conditioned = true
diff --git a/qpid/java/lib/org.eclipse.equinox.launcher.gtk.solaris.sparc_1.0.101.R34x_v20080731/about.html b/qpid/java/lib/org.eclipse.equinox.launcher.gtk.solaris.sparc_1.0.101.R34x_v20080731/about.html
new file mode 100644
index 0000000000..395df3ba90
--- /dev/null
+++ b/qpid/java/lib/org.eclipse.equinox.launcher.gtk.solaris.sparc_1.0.101.R34x_v20080731/about.html
@@ -0,0 +1,28 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"/>
+<title>About</title>
+</head>
+<body lang="EN-US">
+<h2>About This Content</h2>
+
+<p>June 5, 2006</p>
+<h3>License</h3>
+
+<p>The Eclipse Foundation makes available all content in this plug-in (&quot;Content&quot;).
+Unless otherwise indicated below, the Content is provided to you under the terms and conditions of the
+Eclipse Public License Version 1.0 (&quot;EPL&quot;). A copy of the EPL is available
+at <a href="http://www.eclipse.org/org/documents/epl-v10.php">http://www.eclipse.org/legal/epl-v10.html</a>.
+For purposes of the EPL, &quot;Program&quot; will mean the Content.</p>
+
+<p>If you did not receive this Content directly from the Eclipse Foundation, the Content is
+being redistributed by another party (&quot;Redistributor&quot;) and different terms and conditions may
+apply to your use of any object code in the Content. Check the Redistributor&rsquo;s license
+that was provided with the Content. If no such license exists, contact the Redistributor. Unless otherwise
+indicated below, the terms and conditions of the EPL still apply to any source code in the Content
+and such source code may be obtained at <a href="http://www.eclipse.org/">http://www.eclipse.org</a>.</p>
+
+</body>
+</html> \ No newline at end of file
diff --git a/qpid/java/lib/org.eclipse.equinox.launcher.gtk.solaris.sparc_1.0.101.R34x_v20080731/eclipse_1115.so b/qpid/java/lib/org.eclipse.equinox.launcher.gtk.solaris.sparc_1.0.101.R34x_v20080731/eclipse_1115.so
new file mode 100644
index 0000000000..3d8beb88dd
--- /dev/null
+++ b/qpid/java/lib/org.eclipse.equinox.launcher.gtk.solaris.sparc_1.0.101.R34x_v20080731/eclipse_1115.so
Binary files differ
diff --git a/qpid/java/lib/org.eclipse.equinox.launcher.gtk.solaris.sparc_1.0.101.R34x_v20080731/launcher.gtk.solaris.sparc.properties b/qpid/java/lib/org.eclipse.equinox.launcher.gtk.solaris.sparc_1.0.101.R34x_v20080731/launcher.gtk.solaris.sparc.properties
new file mode 100644
index 0000000000..c3f2ae186e
--- /dev/null
+++ b/qpid/java/lib/org.eclipse.equinox.launcher.gtk.solaris.sparc_1.0.101.R34x_v20080731/launcher.gtk.solaris.sparc.properties
@@ -0,0 +1,12 @@
+###############################################################################
+# Copyright (c) 2007 IBM Corporation and others.
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Eclipse Public License v1.0
+# which accompanies this distribution, and is available at
+# http://www.eclipse.org/legal/epl-v10.html
+#
+# Contributors:
+# IBM Corporation - initial API and implementation
+###############################################################################
+pluginName = Equinox Launcher Sparc Fragment
+providerName = Eclipse.org
diff --git a/qpid/java/lib/org.eclipse.swt.gtk.linux.x86_64_3.4.1.v3449c.jar b/qpid/java/lib/org.eclipse.swt.gtk.linux.x86_64_3.4.1.v3449c.jar
new file mode 100644
index 0000000000..95909028d4
--- /dev/null
+++ b/qpid/java/lib/org.eclipse.swt.gtk.linux.x86_64_3.4.1.v3449c.jar
Binary files differ
diff --git a/qpid/java/lib/org.eclipse.swt.gtk.solaris.sparc_3.4.1.v3449c.jar b/qpid/java/lib/org.eclipse.swt.gtk.solaris.sparc_3.4.1.v3449c.jar
new file mode 100644
index 0000000000..d7143505a4
--- /dev/null
+++ b/qpid/java/lib/org.eclipse.swt.gtk.solaris.sparc_3.4.1.v3449c.jar
Binary files differ
diff --git a/qpid/java/management/client/bin/qman-wsdm-start.cmd b/qpid/java/management/client/bin/qman-wsdm-start.cmd
index 4e80177521..df30ce8617 100644
--- a/qpid/java/management/client/bin/qman-wsdm-start.cmd
+++ b/qpid/java/management/client/bin/qman-wsdm-start.cmd
@@ -58,7 +58,6 @@ SET CLASSPATH=%QMAN_HOME%\etc
SET CLASSPATH=%CLASSPATH%;%QMAN_LIBS%\start.jar
SET CLASSPATH=%CLASSPATH%;%QMAN_LIBS%\jetty-6.1.14.jar
SET CLASSPATH=%CLASSPATH%;%QMAN_LIBS%\jetty-util-6.1.14.jar
-SET CLASSPATH=%CLASSPATH%;%QMAN_LIBS%\jetty-util-6.1.14.jar
SET CLASSPATH=%CLASSPATH%;%QMAN_LIBS%\geronimo-servlet_2.5_spec-1.2.jar
SET CLASSPATH=%CLASSPATH%;%QMAN_LIBS%\slf4j-api-1.4.0.jar
SET CLASSPATH=%CLASSPATH%;%QMAN_LIBS%\slf4j-log4j12-1.4.0.jar
diff --git a/qpid/java/management/client/bin/qman-wsdm-start.sh b/qpid/java/management/client/bin/qman-wsdm-start.sh
index 239d1bf2f0..39a4cba66e 100644
--- a/qpid/java/management/client/bin/qman-wsdm-start.sh
+++ b/qpid/java/management/client/bin/qman-wsdm-start.sh
@@ -58,7 +58,7 @@ ADMIN_KEY=gazzax
QMAN_LIBS=$QMAN_HOME/lib
JETTY_CONFIG_FILE=$QMAN_HOME/etc/jetty.xml
-QMAN_CLASSPATH=$QMAN_HOME/etc:$QMAN_LIBS/start.jar:$QMAN_LIBS/jetty-6.1.14.jar:$QMAN_LIBS/jetty-util-6.1.14.jar:$QMAN_LIBS/jetty-util-6.1.14.jar:$QMAN_LIBS/geronimo-servlet_2.5_spec-1.2.jar:$QMAN_LIBS/slf4j-api-1.4.0.jar:$QMAN_LIBS/slf4j-log4j12-1.4.0.jar:$QMAN_LIBS/log4j-1.2.12.jar
+QMAN_CLASSPATH=$QMAN_HOME/etc:$QMAN_LIBS/start.jar:$QMAN_LIBS/jetty-6.1.14.jar:$QMAN_LIBS/jetty-util-6.1.14.jar:$QMAN_LIBS/geronimo-servlet_2.5_spec-1.2.jar:$QMAN_LIBS/slf4j-api-1.4.0.jar:$QMAN_LIBS/slf4j-log4j12-1.4.0.jar:$QMAN_LIBS/log4j-1.2.12.jar
echo "==============================================================================="
echo""
diff --git a/qpid/java/management/client/build.xml b/qpid/java/management/client/build.xml
index 6543a569ee..729c15e2a6 100644
--- a/qpid/java/management/client/build.xml
+++ b/qpid/java/management/client/build.xml
@@ -25,7 +25,6 @@
<import file="../../module.xml"/>
- <property name="war.name" value="qman.war"/>
<property name="build.root" value="${module.build}"/>
<property name="web.module" value="${module.build}${file.separator}wsdm-module"/>
<property name="web-inf.folder" value="${web.module}${file.separator}WEB-INF"/>
@@ -49,7 +48,6 @@
</copy>
</target>
-
<target name="libs-release" description="copy dependencies into module release">
<copy todir="${module.release}${file.separator}" failonerror="true" verbose="true">
<fileset dir="${build}" casesensitive="yes" includes="${module.libs}">
@@ -59,6 +57,8 @@
<not><filename name="**/*xalan*"/></not>
<not><filename name="**/*wsdl*"/></not>
<not><filename name="**/*muse*"/></not>
+ <not><filename name="**/*jsp*"/></not>
+ <not><filename name="**/*core-3.1.1.jar*"/></not>
</fileset>
</copy>
<copy todir="${module.release}${file.separator}lib" failonerror="true">
@@ -195,7 +195,7 @@
<batchtest fork="${test.fork}" todir="${module.results}">
<fileset dir="${module.test.src}" excludes="${module.test.excludes}">
- <include name="**/${test}.java"/>
+ <include name="**/${test}.java"/>
</fileset>
</batchtest>
</junit>
diff --git a/qpid/java/management/client/console/brokers_management.jsp b/qpid/java/management/client/console/brokers_management.jsp
index ab9da15d29..449eabfcc1 100644
--- a/qpid/java/management/client/console/brokers_management.jsp
+++ b/qpid/java/management/client/console/brokers_management.jsp
@@ -97,7 +97,7 @@
Virtual Host :
</td>
<td>
- <input type="text" name="port"/>
+ <input type="text" name="virtualHost"/>
</td>
<td style="font-size: x-small;">
The virtual host name.
diff --git a/qpid/java/management/client/console/fragments/menu.jsp b/qpid/java/management/client/console/fragments/menu.jsp
index 5833f209ad..971123e996 100644
--- a/qpid/java/management/client/console/fragments/menu.jsp
+++ b/qpid/java/management/client/console/fragments/menu.jsp
@@ -3,8 +3,8 @@
<a href="<%=request.getContextPath()%>/console"> &nbsp; &gt; System Overview</a>
<a href="<%=request.getContextPath()%>/brokers_management">&nbsp; &gt; Brokers Management</a>
<a href="<%=request.getContextPath()%>/resources_management">&nbsp; &gt; Resources Management</a>
- <a href="<%=request.getContextPath()%>/tbd.jsp">&nbsp; &gt; Subscriptions Management</a>
- <a href="<%=request.getContextPath()%>/tbd.jsp">&nbsp; &gt; System Health</a>
+ <a>&nbsp; &gt; Subscriptions Management</a>
+ <a>&nbsp; &gt; System Health</a>
<a href="<%=request.getContextPath()%>/logging_configuration">&nbsp; &gt; Logging Configuration</a>
</div>
</div>
diff --git a/qpid/java/management/client/console/wsdl-viewer.xsl b/qpid/java/management/client/console/wsdl-viewer.xsl
deleted file mode 100644
index c3c9767e10..0000000000
--- a/qpid/java/management/client/console/wsdl-viewer.xsl
+++ /dev/null
@@ -1,2523 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-
-<!--
-/**
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
--->
-
-
-<!--
-* ====================================================================
-* wsdl-viewer.xsl
-* Version: 3.1.02
-*
-* URL: http://tomi.vanek.sk/xml/wsdl-viewer.xsl
-*
-* Author: tomi vanek
-* Inspiration: Uche Ogbui - WSDL processing with XSLT
-* http://www-106.ibm.com/developerworks/library/ws-trans/index.html
-* ====================================================================
--->
-
-
-<!--
-* ====================================================================
-* Description:
-* wsdl-viewer.xsl is a lightweight XSLT 1.0 transformation with minimal
-* usage of any hacks that extend the possibilities of the transformation
-* over the XSLT 1.0 constraints but eventually would harm the engine independance.
-*
-* The transformation has to run even in the browser offered XSLT engines
-* (tested in IE 6 and Firefox) and in ANT "batch" processing.
-* ====================================================================
-* How to add the HTML look to a WSDL:
-* <?xml version="1.0" encoding="utf-8"?>
-* <?xml-stylesheet type="text/xsl" href="wsdl-viewer.xsl"?>
-* <wsdl:definitions ...>
-* ... Here is the service declaration
-* </wsdl:definitions>
-*
-* The web-browsers (in Windows) are not able by default automatically recognize
-* the ".wsdl" file type (suffix). For the type recognition the WSDL file has
-* to be renamed by adding the suffix ".xml" - i.e. "myservice.wsdl.xml".
-* ====================================================================
-* Constraints:
-* 1. Processing of imported files
-* 1.1 Only 1 imported WSDL and 1 imported XSD is processed
-* (well, maybe with a smarter recursive strategy this restriction could be overcome)
-* 1.2 No recursive including is supported (i.e. includes in included XSD are ignored)
-* 2. Namespace support
-* 2.1 Namespaces are not taken in account by processing (references with NS)
-* 3. Source code
-* 3.1 Only the source code allready processed by the XML parser is rendered - implications:
-* == no access to the XML head line (<?xml version="1.0" encoding="utf-8"?>)
-* == "expanded" CDATA blocks (parser processes the CDATA,
-* XSLT does not have access to the original code)
-* == no control over the code page
-* == processing of special characters
-* == namespace nodes are not rendered (just the namespace aliases)
-* ====================================================================
-* Possible improvements:
-* * Functional requirements
-* + SOAP 1.2 binding (http://schemas.xmlsoap.org/wsdl/soap12/WSDL11SOAP12.pdf)
-* + WSDL 2.0 (http://www.w3.org/TR/2006/CR-wsdl20-primer-20060327/)
-* + Recognition of WSDL patterns (interface, binding, service instance, ...)
-* - Creating an xsd-viewer.xsl for XML-Schema file viewing
-* (extracting the functionality from wsdl-viewer into separate XSLT)
-* - Check the full support of the WSDL and XSD going through the standards
-* - Real-world WSDL testing
-* - XSLT 2.0 (http://www-128.ibm.com/developerworks/library/x-xslt20pt5.html) ???
-* ? Adding more derived information
-* * to be defined, what non-trivial information can we read out from the WSDL
-* * XSLT
-* + Modularization
-* - Is it meaningful?
-* - Maybe more distribution alternatives (modular, fat monolithic, thin performance monolithic)?
-* - Distribution build automatization
-* + Dynamic page: JavaSript
-* + Performance
-* - Better code comments / documentation
-* - SOAP client form - for testing the web service (AJAX based)
-* - New XSD parser - clean-up the algorithm
-* - Complete (recursive, multiple) include support
-* ? Namespace-aware version (no string processing hacks ;-)
-* * I think, because of the goal to support as many engines as possible,
-* this requirement is unrealistic. Maybe when XSLT 2.0 will be supported
-* in a huge majority of platforms, we can rethink this point....
-* (problems with different functionality of namespace-uri XPath function by different engines)
-* * Development architecture
-* - Setup of the development infrastructure
-* - Unit testing
-* ? Collaboration platform
-* * Documentation, web
-* - Better user guide
-* ? Forum, Wiki
-* ====================================================================
--->
-
-
-<!--
-* ====================================================================
-* History:
-* 2005-04-15 - Initial implementation
-* 2005-09-12 - Removed xsl:key to be able to use the James Clark's XT engine on W3C web-site
-* 2006-10-06 - Removed the Oliver Becker's method of conditional selection
-* of a value in a single expression (in Xalan/XSLTC this hack does not work!)
-* 2005-10-07 - Duplicated operations
-* 2006-12-08 - Import element support
-* 2006-12-14 - Displays all fault elements (not just the first one)
-* 2006-12-28 - W3C replaced silently the James Clark's XT engine with Michael Kay's closed-source Saxon!
-* wsdl-viewer.xsl will no longer support XT engine
-* 2007-02-28 - Stack-overflow bug (if the XSD element @name and @type are identic)
-* 2007-03-08 - 3.0.00 - New parsing, new layout
-* 2007-03-28 - 3.0.01 - Fix: New anti-recursion defense (no error message by recursion
-* because of dirty solution of namespace processing)
-* - Added: variables at the top to turn on/off certain details
-* 2007-03-29 - 3.0.02 - Layout clean-up for IE
-* 2007-03-29 - 3.0.03 - Fix: Anti-recursion algorithm
-* 2007-03-30 - 3.0.04 - Added: source code rendering of imported WSDL and XSD
-* 2007-04-15 - 3.0.05 - Fix: Recursive calls in element type rendering
-* - Fix: Rendering of messages (did not render the message types of complex types)
-* - Fix: Links in src. by arrays
-* - Fix: $binding-info
-* 2007-04-15 - 3.0.06 - Added: Extended rendering control ENABLE-xxx parameters
-* - Changed: Anti-recursion algorithm has recursion-depth parameter
-* 2007-07-19 - 3.0.07 - Fix: Rendering of array type in detail
-* 2007-08-01 - 3.0.08 - Fix: xsl:template name="render-type"
-* Fix: typo - "Impotred WSDL" should be "Impotred WSDL"
-* 2007-08-16 - 3.0.09 - Fix: xsl:template name="render-type" - anti recursion
-* 2007-12-05 - 3.1.00 - Modularized
-* 2007-12-23 - 3.1.01 - Terminating message by WS without interface or service definition was removed
-* (seems to be a correct state)
-* 2008-08-20 - 3.1.02 - Woden-214: Anti-recursion bypassed in xsd:choice element
-* ====================================================================
--->
-<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
- xmlns="http://www.w3.org/1999/xhtml"
- xmlns:ws="http://schemas.xmlsoap.org/wsdl/"
- xmlns:ws2="http://www.w3.org/ns/wsdl"
- xmlns:xsd="http://www.w3.org/2001/XMLSchema"
- xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
- xmlns:local="http://tomi.vanek.sk/xml/wsdl-viewer"
- version="1.0"
- exclude-result-prefixes="ws ws2 xsd soap local">
-
- <xsl:output method="xml" version="1.0" encoding="utf-8" indent="no"
- omit-xml-declaration="no"
- media-type="text/html"
- doctype-system="http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"
- doctype-public="-//W3C//DTD XHTML 1.0 Transitional//EN"/>
-
- <xsl:strip-space elements="*"/>
-
- <xsl:param name="wsdl-viewer.version">3.1.01</xsl:param>
-
-
-
- <!--
-@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
- Begin of included transformation: wsdl-viewer-global.xsl
-@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
--->
-<xsl:param name="ENABLE-SERVICE-PARAGRAPH" select="true()"/>
- <xsl:param name="ENABLE-OPERATIONS-PARAGRAPH" select="true()"/>
- <xsl:param name="ENABLE-SRC-CODE-PARAGRAPH" select="true()"/>
- <xsl:param name="ENABLE-ABOUT-PARAGRAPH" select="false()"/>
- <xsl:param name="ENABLE-OPERATIONS-TYPE" select="true()"/>
- <xsl:param name="ENABLE-LINK" select="true()"/>
- <xsl:param name="ENABLE-INOUTFAULT" select="true()"/>
- <xsl:param name="ENABLE-STYLEOPTYPEPATH" select="true()"/>
- <xsl:param name="ENABLE-DESCRIPTION" select="true()"/>
- <xsl:param name="ENABLE-PORTTYPE-NAME" select="true()"/>
- <xsl:param name="ENABLE-ANTIRECURSION-PROTECTION" select="true()"/>
- <xsl:param name="ANTIRECURSION-DEPTH">3</xsl:param>
- <xsl:variable name="GENERATED-BY">Generated by wsdl-viewer.xsl</xsl:variable>
- <xsl:variable name="PORT-TYPE-TEXT">Port type</xsl:variable>
- <xsl:variable name="IFACE-TEXT">Interface</xsl:variable>
- <xsl:variable name="SOURCE-CODE-TEXT">Source code</xsl:variable>
- <xsl:variable name="RECURSIVE"> ... is recursive</xsl:variable>
- <xsl:variable name="SRC-PREFIX">src.</xsl:variable>
- <xsl:variable name="SRC-FILE-PREFIX">src.file.</xsl:variable>
- <xsl:variable name="OPERATIONS-PREFIX">op.</xsl:variable>
- <xsl:variable name="PORT-PREFIX">port.</xsl:variable>
- <xsl:variable name="IFACE-PREFIX">iface.</xsl:variable>
- <xsl:variable name="global.wsdl-name"
- select="/*/*[(local-name() = 'import' or local-name() = 'include') and @location][1]/@location"/>
- <xsl:variable name="consolidated-wsdl" select="/* | document($global.wsdl-name)/*"/>
- <xsl:variable name="global.xsd-name"
- select="($consolidated-wsdl/*[local-name() = 'types']//xsd:import[@schemaLocation] | $consolidated-wsdl/*[local-name() = 'types']//xsd:include[@schemaLocation])[1]/@schemaLocation"/>
- <xsl:variable name="consolidated-xsd"
- select="(document($global.xsd-name)/xsd:schema/xsd:*|/*/*[local-name() = 'types']/xsd:schema/xsd:*)[local-name() = 'complexType' or local-name() = 'element' or local-name() = 'simpleType']"/>
- <xsl:variable name="global.service-name"
- select="concat($consolidated-wsdl/ws:service/@name, $consolidated-wsdl/ws2:service/@name)"/>
- <xsl:variable name="global.binding-name"
- select="concat($consolidated-wsdl/ws:binding/@name, $consolidated-wsdl/ws2:binding/@name)"/>
- <xsl:variable name="html-title">
- <xsl:apply-templates select="/*" mode="html-title.render"/>
- </xsl:variable>
-
- <!--
-@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
- End of included transformation: wsdl-viewer-global.xsl
-@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
--->
-
-
-
-<!--
-@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
- Begin of included transformation: wsdl-viewer-css.xsl
-@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
--->
-<xsl:variable name="css">
-
-/**
- wsdl-viewer.css
-*/
-
-/**
-=========================================
- Body
-=========================================
-
-html {
- background-color: #FFFFFF;
-}
-
-body {
- margin: 0;
- padding: 0;
- height: auto;
- color: white;
- background-color: #FFFFFF;
- font: normal Tahoma;
-}
-*/
-#outer_box {
- padding: 3px 3px 3px 194px;
- width: 400px;
-}
-
-#inner_box {
-
- background-color: white;
- color: black;
- font: normal Tahoma;
- font-size : x-small;
-}
-
-/**
-=========================================
- Fixed box with links
-=========================================
-*/
-#outer_links {
- position: fixed;
- left: 0px;
- top: 0px;
- margin: 3px;
- padding: 1px;
- z-index: 200;
- width: 180px;
- height: auto;
- background-color: gainsboro;
- padding-top: 2px;
- border: 1px solid navy;
-}
-
-* html #outer_links /* Override above rule for IE */
-{
- position: absolute;
- width: 188px;
- top: expression(offsetParent.scrollTop + 0);
-}
-
-#links {
- margin: 1px;
- padding: 3px;
- background-color: white;
- height: 350px;
- overflow: auto;
- border: 1px solid navy;
-}
-
-#links ul {
- left: -999em;
- list-style: none;
- margin: 0;
- padding: 0;
- z-index: 100;
-}
-
-#links li {
- margin: 0;
- padding: 2px 4px;
- width: auto;
- z-index: 100;
-}
-
-#links ul li {
- margin: 0;
- padding: 2px 4px;
- width: auto;
- z-index: 100;
-}
-
-#links a {
- display: block;
- padding: 0 2px;
- color: blue;
- width: auto;
- border: 1px solid white;
- text-decoration: none;
- white-space: nowrap;
-}
-
-#links a:hover {
- color: white;
- background-color: gray;
- border: 1px solid gray;
-}
-
-
-/**
-=========================================
- Navigation tabs
-=========================================
-*/
-
-#outer_nav {
- background-color: yellow;
- padding: 0;
- margin: 0;
-}
-
-#nav {
- height: 100%;
- width: auto;
- margin: 0;
- padding: 0;
- background-color: gainsboro;
- border-top: 1px solid gray;
- border-bottom: 3px solid gray;
- z-index: 100;
- font: bold Tahoma;
- letter-spacing: 2px;
-}
-
-#nav ul {
- background-color: gainsboro;
- height: auto;
- width: auto;
- list-style: none;
- margin: 0;
- padding: 0;
- z-index: 100;
-
- border: 1px solid silver;
- border-top-color: black;
- border-width: 1px 0 9px;
-}
-
-#nav li {
- display: inline;
- padding: 0;
- margin: 0;
-}
-
-#nav a {
- position: relative;
- top: 3px;
- float:left;
- width:auto;
- padding: 8px 10px 6px 10px;
- margin: 3px 3px 0;
- border: 1px solid gray;
- border-width: 2px 2px 3px 2px;
-
- color: black;
- background-color: silver;
- text-decoration:none;
- text-transform: uppercase;
-}
-
-#nav a:hover {
- margin-top: 1px;
- padding-top: 9px;
- padding-bottom: 7px;
- color: blue;
- background-color: gainsboro;
-}
-
-#nav a.current:link,
-#nav a.current:visited,
-#nav a.current:hover {
- background: white;
- color: black;
- text-shadow:none;
- margin-top: 0;
- padding-top: 11px;
- padding-bottom: 9px;
- border-bottom-width: 0;
- border-color: #A5CE77;
-}
-
-#nav a:active {
- background-color: silver;
- color: white;
-}
-
-
-
-/**
-=========================================
- Content
-=========================================
-*/
-#header {
- margin: 0;
- padding: .5em 4em;
- color: white;
- background-color: #369;
-}
-
-#content {
- margin: 0;
- padding: 0 2em .5em;
-}
-
-#footer {
- clear: both;
- margin: 0;
- padding: .5em 2em;
- color: gray;
- background-color: gainsboro;
- font-size: 80%;
- border-top: 1px dotted gray;
- text-align: right
-}
-
-.single_column {
- padding: 10px 10px 10px 10px;
- /*margin: 0px 33% 0px 0px; */
- margin: 3px 0;
-}
-
-#flexi_column {
- padding: 10px 10px 10px 10px;
- /*margin: 0px 33% 0px 0px; */
- margin: 0px 212px 0px 0px;
-}
-
-#fix_column {
- float: right;
- padding: 10px 10px 10px 10px;
- margin: 0px;
- width: 205px;
- /*width: 30%; */
- voice-family: "\"}\"";
- voice-family:inherit;
- /* width: 30%; */
- width: 205px;
-}
-html&gt;body #rightColumn {
- width: 205px; /* ie5win fudge ends */
-} /* Opera5.02 shows a 2px gap between. N6.01Win sometimes does.
- Depends on amount of fill and window size and wind direction. */
-
-/**
-=========================================
- Label / value
-=========================================
-*/
-
-.page {
- border-bottom: 3px dotted navy;
- margin: 0;
- padding: 10px 0 20px 0;
-}
-
-.value, .label {
- margin: 0;
- padding: 0;
-}
-
-.label {
- float: left;
- width: 140px;
- text-align: right;
- font-weight: bold;
- padding-bottom: .5em;
- margin-right: 0;
- color: darkblue;
-}
-
-.value {
- margin-left: 147px;
- color: darkblue;
- padding-bottom: .5em;
-}
-
-strong, strong a {
- color: darkblue;
- font-weight: bold;
- letter-spacing: 1px;
- margin-left: 2px;
-}
-
-
-/**
-=========================================
- Links
-=========================================
-*/
-
-a.local:link,
-a.local:visited {
- color: blue;
- margin-left: 10px;
- border-bottom: 1px dotted blue;
- text-decoration: none;
- font-style: italic;
-}
-
-a.local:hover {
- background-color: gainsboro;
- color: darkblue;
- padding-bottom: 1px;
- border-bottom: 1px solid darkblue;
-}
-
-a.target:link,
-a.target:visited,
-a.target:hover
-{
- text-decoration: none;
- background-color: transparent;
- border-bottom-type: none;
-}
-
-/**
-=========================================
- Box, Shadow
-=========================================
-*/
-
-.box {
- padding: 6px;
- color: black;
- background-color: gainsboro;
- border: 1px solid gray;
-}
-
-.shadow {
- background: silver;
- position: relative;
- top: 5px;
- left: 4px;
-}
-
-.shadow div {
- position: relative;
- top: -5px;
- left: -4px;
-}
-
-/**
-=========================================
- Floatcontainer
-=========================================
-*/
-
-.spacer
-{
- display: block;
- height: 0;
- font-size: 0;
- line-height: 0;
- margin: 0;
- padding: 0;
- border-style: none;
- clear: both;
- visibility:hidden;
-}
-
-.floatcontainer:after {
- content: ".";
- display: block;
- height: 0;
- font-size:0;
- clear: both;
- visibility:hidden;
-}
-.floatcontainer{
- display: inline-table;
-} /* Mark Hadley's fix for IE Mac */ /* Hides from IE Mac \*/ *
-html .floatcontainer {
- height: 1%;
-}
-.floatcontainer{
- display:block;
-} /* End Hack
-*/
-
-/**
-=========================================
- Source code
-=========================================
-*/
-
-.indent {
- margin: 2px 0 2px 20px;
-}
-
-.xml-element, .xml-proc, .xml-comment {
- margin: 2px 0;
- padding: 2px 0 2px 0;
-}
-
-.xml-element {
- word-spacing: 3px;
- color: red;
- font-weight: bold;
- font-style:normal;
- border-left: 1px dotted silver;
-}
-
-.xml-element div {
- margin: 2px 0 2px 40px;
-}
-
-.xml-att {
- color: blue;
- font-weight: bold;
-}
-
-.xml-att-val {
- color: blue;
- font-weight: normal;
-}
-
-.xml-proc {
- color: darkred;
- font-weight: normal;
- font-style: italic;
-}
-
-.xml-comment {
- color: green;
- font-weight: normal;
- font-style: italic;
-}
-
-.xml-text {
- color: green;
- font-weight: normal;
- font-style: normal;
-}
-
-
-/**
-=========================================
- Heading
-=========================================
-*/
-h1, h2, h3 {
- margin: 10px 10px 2px;
- font-family: Tahoma;
- font-weight: normal;
- }
-
-h1 {
- font-weight: bold;
- letter-spacing: 3px;
- font-size: 220%;
- line-height: 100%;
-}
-
-h2 {
- font-weight: bold;
- font-size: 175%;
- line-height: 200%;
-}
-
-h3 {
- font-size: 150%;
- line-height: 150%;
- font-style: italic;
-}
-
-/**
-=========================================
- Content formatting
-=========================================
-*/
-.port {
- margin-bottom: 10px;
- padding-bottom: 10px;
- border-bottom: 1px dashed gray;
-}
-
-.operation {
- margin-bottom: 20px;
- padding-bottom: 10px;
- border-bottom: 1px dashed gray;
-}
-
-
-/* --------------------------------------------------------
- Printing
-*/
-
-/*
-@media print
-{
- #outer_links, #outer_nav {
- display: none;
- }
-*/
-
- #outer_box {
- padding: 3px;
- }
-/* END print media definition
-}
-*/
-
-</xsl:variable>
-
- <!--
-@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
- End of included transformation: wsdl-viewer-css.xsl
-@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
--->
-
-
-
-
-<!--
-@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
- Begin of included transformation: wsdl-viewer-util.xsl
-@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
--->
-<xsl:template match="@*" mode="qname.normalized">
- <xsl:variable name="local" select="substring-after(., ':')"/>
- <xsl:choose>
- <xsl:when test="$local">
- <xsl:value-of select="$local"/>
- </xsl:when>
- <xsl:otherwise>
- <xsl:value-of select="."/>
- </xsl:otherwise>
- </xsl:choose>
- </xsl:template>
- <xsl:template match="ws:definitions | ws2:description" mode="html-title.render">
- <xsl:choose>
- <xsl:when test="$global.service-name">
- <xsl:value-of select="concat('Service : ', $global.service-name)"/>
- </xsl:when>
- <xsl:when test="$global.binding-name">
- <xsl:value-of select="concat('WS Binding: ', $global.binding-name)"/>
- </xsl:when>
- <xsl:when test="ws2:interface/@name">
- <xsl:value-of select="concat('WS Interface: ', ws2:interface/@name)"/>
- </xsl:when>
- <xsl:otherwise>Web Service Fragment</xsl:otherwise>
- <!-- <xsl:otherwise><xsl:message terminate="yes">Syntax error in element <xsl:call-template name="src.syntax-error.path"/></xsl:message>
- </xsl:otherwise>
--->
- </xsl:choose>
- </xsl:template>
- <xsl:template name="src.syntax-error">
- <xsl:message terminate="yes">Syntax error by WSDL source rendering in element <xsl:call-template name="src.syntax-error.path"/>
- </xsl:message>
- </xsl:template>
- <xsl:template name="src.syntax-error.path">
- <xsl:for-each select="parent::*">
- <xsl:call-template name="src.syntax-error.path"/>
- </xsl:for-each>
- <xsl:value-of select="concat('/', name(), '[', position(), ']')"/>
- </xsl:template>
- <xsl:template match="*[local-name(.) = 'documentation']" mode="documentation.render">
- <xsl:if test="$ENABLE-DESCRIPTION and string-length(.) &gt; 0">
- <div class="label">Description:</div>
- <div class="value">
- <xsl:value-of select="." disable-output-escaping="yes"/>
- </div>
- </xsl:if>
- </xsl:template>
- <xsl:template name="render.source-code-link">
- <xsl:if test="$ENABLE-SRC-CODE-PARAGRAPH and $ENABLE-LINK">
- <a class="local" href="{concat('#', $SRC-PREFIX, generate-id(.))}">
- <xsl:value-of select="$SOURCE-CODE-TEXT"/>
- </a>
- </xsl:if>
- </xsl:template>
- <xsl:template name="about.detail">
- <!-- <xsl:param name="version"/>
- <div>
- This page has been generated by <big>wsdl-viewer.xsl</big>, version <xsl:value-of select="$version"/>
- <br/>
- Author: <a href="http://tomi.vanek.sk/">tomi vanek</a>
- <br/>
- Download at <a href="http://tomi.vanek.sk/xml/wsdl-viewer.xsl">http://tomi.vanek.sk/xml/wsdl-viewer.xsl</a>.<br/>
- <br/>
- The transformation was inspired by the article<br/>
- Uche Ogbuji: <a href="http://www-106.ibm.com/developerworks/library/ws-trans/index.html">WSDL processing with XSLT</a>
- <br/>
- </div>
- </xsl:template>
- <xsl:template name="processor-info.render">
- <xsl:text>
-</xsl:text>
- <xsl:text>This document was generated by </xsl:text>
- <a href="{system-property('xsl:vendor-url')}">
- <xsl:value-of select="system-property('xsl:vendor')"/>
- </a>
- <xsl:text> XSLT engine.
-
-</xsl:text>
-
- <xsl:text>The engine processed the WSDL in XSLT </xsl:text>
- <xsl:value-of select="format-number(system-property('xsl:version'), '#.0')"/>
- <xsl:text> compliant mode.
-</xsl:text>
- -->
- </xsl:template>
-
- <!--
-@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
- End of included transformation: wsdl-viewer-util.xsl
-@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
--->
-
-
-
-<!--
-@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
- Begin of included transformation: wsdl-viewer-service.xsl
-@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
--->
-<xsl:template match="ws:service|ws2:service" mode="service-start">
- <div class="indent">
- <div class="label">Target Namespace:</div>
- <div class="value">
- <xsl:value-of select="$consolidated-wsdl/@targetNamespace"/>
- </div>
- <xsl:apply-templates select="*[local-name(.) = 'documentation']" mode="documentation.render"/>
- <xsl:apply-templates select="ws:port|ws2:endpoint" mode="service"/>
- </div>
- </xsl:template>
- <xsl:template match="ws2:endpoint" mode="service">
- <xsl:variable name="binding-name">
- <xsl:apply-templates select="@binding" mode="qname.normalized"/>
- </xsl:variable>
- <xsl:variable name="binding" select="$consolidated-wsdl/ws2:binding[@name = $binding-name]"/>
-
- <xsl:variable name="binding-type" select="$binding/@type"/>
- <xsl:variable name="binding-protocol" select="$binding/@*[local-name() = 'protocol']"/>
- <xsl:variable name="protocol">
- <xsl:choose>
- <xsl:when test="starts-with($binding-type, 'http://schemas.xmlsoap.org/wsdl/soap')">SOAP 1.1</xsl:when>
- <xsl:when test="starts-with($binding-type, 'http://www.w3.org/2005/08/wsdl/soap')">SOAP 1.2</xsl:when>
- <xsl:when test="starts-with($binding-type, 'http://schemas.xmlsoap.org/wsdl/mime')">MIME</xsl:when>
- <xsl:when test="starts-with($binding-type, 'http://schemas.xmlsoap.org/wsdl/http')">HTTP</xsl:when>
- <xsl:otherwise>Unknown</xsl:otherwise>
- </xsl:choose>
-
- <!-- TODO: Add all bindings to transport protocols -->
- <xsl:choose>
- <xsl:when test="starts-with($binding-protocol, 'http://www.w3.org/2003/05/soap/bindings/HTTP')"> over HTTP</xsl:when>
- <xsl:otherwise/>
- </xsl:choose>
- </xsl:variable>
-
- <div class="label">Location:</div>
- <div class="value">
- <xsl:value-of select="@address"/>
- </div>
-
- <div class="label">Protocol:</div>
- <div class="value">
- <xsl:value-of select="$protocol"/>
- </div>
-
- <xsl:apply-templates select="$binding" mode="service"/>
-
- <xsl:variable name="iface-name">
- <xsl:apply-templates select="../@interface" mode="qname.normalized"/>
- </xsl:variable>
- <xsl:apply-templates select="$consolidated-wsdl/ws2:interface[@name = $iface-name]" mode="service"/>
-
- </xsl:template>
- <xsl:template match="ws2:interface" mode="service">
- <h3>Interface <b>
- <xsl:value-of select="@name"/>
- </b>
- <xsl:if test="$ENABLE-LINK">
- <xsl:text> </xsl:text>
- <span>
- <xsl:if test="$ENABLE-OPERATIONS-PARAGRAPH">
- <a class="local" href="#{concat($PORT-PREFIX, generate-id(.))}">
- <xsl:value-of select="$PORT-TYPE-TEXT"/>
- </a>
- </xsl:if>
- <xsl:call-template name="render.source-code-link"/>
- </span>
- </xsl:if>
- </h3>
-
- <xsl:variable name="base-iface-name">
- <xsl:apply-templates select="@extends" mode="qname.normalized"/>
- </xsl:variable>
-
- <xsl:if test="$base-iface-name">
- <div class="label">Extends: </div>
- <div class="value">
- <xsl:value-of select="$base-iface-name"/>
- </div>
- </xsl:if>
-
- <xsl:variable name="base-iface"
- select="$consolidated-wsdl/ws2:interface[@name = $base-iface-name]"/>
-
- <div class="label">Operations:</div>
- <div class="value">
- <xsl:text>
-</xsl:text>
- <ol style="line-height: 180%;">
- <xsl:apply-templates select="$base-iface/ws2:operation | ws2:operation" mode="service">
- <xsl:sort select="@name"/>
- </xsl:apply-templates>
- </ol>
- </div>
- </xsl:template>
- <xsl:template match="ws:port" mode="service">
- <xsl:variable name="binding-name">
- <xsl:apply-templates select="@binding" mode="qname.normalized"/>
- </xsl:variable>
- <xsl:variable name="binding" select="$consolidated-wsdl/ws:binding[@name = $binding-name]"/>
-
- <xsl:variable name="binding-uri"
- select="namespace-uri( $binding/*[local-name() = 'binding'] )"/>
- <xsl:variable name="protocol">
- <xsl:choose>
- <xsl:when test="starts-with($binding-uri, 'http://schemas.xmlsoap.org/wsdl/soap')">SOAP</xsl:when>
- <xsl:when test="starts-with($binding-uri, 'http://schemas.xmlsoap.org/wsdl/mime')">MIME</xsl:when>
- <xsl:when test="starts-with($binding-uri, 'http://schemas.xmlsoap.org/wsdl/http')">HTTP</xsl:when>
- <xsl:otherwise>unknown</xsl:otherwise>
- </xsl:choose>
- </xsl:variable>
-
- <xsl:variable name="port-type-name">
- <xsl:apply-templates select="$binding/@type" mode="qname.normalized"/>
- </xsl:variable>
-
- <xsl:variable name="port-type"
- select="$consolidated-wsdl/ws:portType[@name = $port-type-name]"/>
-
-
- <h3>Port <b>
- <xsl:value-of select="@name"/>
- </b>
- <xsl:if test="$ENABLE-LINK">
- <xsl:text> </xsl:text>
- <!-- <small>-->
- <xsl:if test="$ENABLE-OPERATIONS-PARAGRAPH">
- <a class="local" href="#{concat($PORT-PREFIX, generate-id($port-type))}">
- <xsl:value-of select="$PORT-TYPE-TEXT"/>
- </a>
- </xsl:if>
- <xsl:call-template name="render.source-code-link"/>
- <!-- </small>-->
- </xsl:if>
- </h3>
-
- <div class="label">Location:</div>
- <div class="value">
- <xsl:value-of select="*[local-name() = 'address']/@location"/>
- </div>
-
- <div class="label">Protocol:</div>
- <div class="value">
- <xsl:value-of select="$protocol"/>
- </div>
-
- <xsl:apply-templates select="$binding" mode="service"/>
-
- <div class="label">Operations:</div>
- <div class="value">
- <xsl:text>
-</xsl:text>
- <ol style="line-height: 180%;">
- <xsl:apply-templates select="$consolidated-wsdl/ws:portType[@name = $port-type-name]/ws:operation"
- mode="service">
- <xsl:sort select="@name"/>
- </xsl:apply-templates>
- </ol>
- </div>
- </xsl:template>
- <xsl:template match="ws:operation|ws2:operation" mode="service">
- <li>
- <big>
- <i>
- <xsl:value-of select="@name"/>
- </i>
- </big>
- <xsl:if test="$ENABLE-LINK">
- <xsl:if test="$ENABLE-OPERATIONS-PARAGRAPH">
- <a class="local" href="{concat('#', $OPERATIONS-PREFIX, generate-id(.))}">Detail</a>
- </xsl:if>
- <xsl:call-template name="render.source-code-link"/>
- </xsl:if>
- </li>
- </xsl:template>
- <xsl:template match="ws:binding|ws2:binding" mode="service">
- <xsl:variable name="real-binding" select="*[local-name() = 'binding']|self::ws2:*"/>
-
- <xsl:if test="$real-binding/@style">
- <div class="label">Default style:</div>
- <div class="value">
- <xsl:value-of select="$real-binding/@style"/>
- </div>
- </xsl:if>
-
-
- <xsl:if test="$real-binding/@transport|$real-binding/*[local-name() = 'protocol']">
- <xsl:variable name="protocol"
- select="concat($real-binding/@transport, $real-binding/*[local-name() = 'protocol'])"/>
- <div class="label">Transport protocol:</div>
- <div class="value">
- <xsl:choose>
- <xsl:when test="$protocol = 'http://schemas.xmlsoap.org/soap/http'">SOAP over HTTP</xsl:when>
- <xsl:otherwise>
- <xsl:value-of select="$protocol"/>
- </xsl:otherwise>
- </xsl:choose>
- </div>
- </xsl:if>
-
- <xsl:if test="$real-binding/@verb">
- <div class="label">Default method:</div>
- <div class="value">
- <xsl:value-of select="$real-binding/@verb"/>
- </div>
- </xsl:if>
- </xsl:template>
-
- <!--
-@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
- End of included transformation: wsdl-viewer-service.xsl
-@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
--->
-
-
-
-<!--
-@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
- Begin of included transformation: wsdl-viewer-operations.xsl
-@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
--->
-<xsl:template match="ws2:interface" mode="operations">
- <xsl:if test="$ENABLE-PORTTYPE-NAME">
- <h3>
- <a name="{concat($IFACE-PREFIX, generate-id(.))}">
- <xsl:value-of select="$IFACE-TEXT"/>
- <xsl:text>
-</xsl:text>
- <b>
- <xsl:value-of select="@name"/>
- </b>
- </a>
- <xsl:call-template name="render.source-code-link"/>
- </h3>
- </xsl:if>
-
- <ol>
- <xsl:apply-templates select="ws2:operation" mode="operations">
- <xsl:sort select="@name"/>
- </xsl:apply-templates>
- </ol>
- </xsl:template>
- <xsl:template match="ws2:operation" mode="operations">
- <xsl:variable name="binding-info"
- select="$consolidated-wsdl/ws2:binding[@interface = current()/../@name or substring-after(@interface, ':') = current()/../@name]/ws2:operation[@ref = current()/@name or substring-after(@ref, ':') = current()/@name]"/>
- <li>
- <xsl:if test="position() != last()">
- <xsl:attribute name="class">operation</xsl:attribute>
- </xsl:if>
- <big>
- <b>
- <a name="{concat($OPERATIONS-PREFIX, generate-id(.))}">
- <xsl:value-of select="@name"/>
- </a>
- </b>
- </big>
- <div class="value">
- <xsl:text>
-</xsl:text>
- <xsl:call-template name="render.source-code-link"/>
- </div>
- <xsl:apply-templates select="ws2:documentation" mode="documentation.render"/>
-
- <xsl:if test="$ENABLE-STYLEOPTYPEPATH">
- <!-- TODO: add the operation attributes - according the WSDL 2.0 spec. -->
- </xsl:if>
- <xsl:apply-templates select="ws2:input|ws2:output|../ws2:fault[@name = ws2:infault/@ref or @name = ws2:outfault/@ref]"
- mode="operations.message">
- <xsl:with-param name="binding-data" select="$binding-info"/>
- </xsl:apply-templates>
- </li>
- </xsl:template>
- <xsl:template match="ws2:input|ws2:output|ws2:fault" mode="operations.message">
- <xsl:param name="binding-data"/>
- <xsl:if test="$ENABLE-INOUTFAULT">
- <div class="label">
- <xsl:value-of select="concat(translate(substring(local-name(.), 1, 1), 'abcdefghijklmnoprstuvwxyz', 'ABCDEFGHIJKLMNOPRSTUVWXYZ'), substring(local-name(.), 2), ':')"/>
- </div>
-
- <div class="value">
- <xsl:variable name="type-name">
- <xsl:apply-templates select="@element" mode="qname.normalized"/>
- </xsl:variable>
-
- <xsl:call-template name="render-type">
- <xsl:with-param name="type-local-name" select="$type-name"/>
- </xsl:call-template>
-
- <xsl:call-template name="render.source-code-link"/>
-
- <xsl:variable name="type-tree"
- select="$consolidated-xsd[@name = $type-name and not(xsd:simpleType)][1]"/>
- <xsl:apply-templates select="$type-tree" mode="operations.message.part"/>
- </div>
- </xsl:if>
- </xsl:template>
- <xsl:template match="ws:portType" mode="operations">
- <div>
- <xsl:if test="position() != last()">
- <xsl:attribute name="class">port</xsl:attribute>
- </xsl:if>
- <xsl:if test="$ENABLE-PORTTYPE-NAME">
- <h3>
- <a name="{concat($PORT-PREFIX, generate-id(.))}">
- <xsl:value-of select="$PORT-TYPE-TEXT"/>
- <xsl:text>
-</xsl:text>
- <b>
- <xsl:value-of select="@name"/>
- </b>
- </a>
- <xsl:call-template name="render.source-code-link"/>
- </h3>
- </xsl:if>
- <ol>
- <xsl:apply-templates select="ws:operation" mode="operations">
- <xsl:sort select="@name"/>
- </xsl:apply-templates>
- </ol>
- </div>
- </xsl:template>
- <xsl:template match="ws:operation" mode="operations">
- <xsl:variable name="binding-info"
- select="$consolidated-wsdl/ws:binding[@type = current()/../@name or substring-after(@type, ':') = current()/../@name]/ws:operation[@name = current()/@name]"/>
- <li>
- <xsl:if test="position() != last()">
- <xsl:attribute name="class">operation</xsl:attribute>
- </xsl:if>
- <big>
- <b>
- <a name="{concat($OPERATIONS-PREFIX, generate-id(.))}">
- <xsl:value-of select="@name"/>
- </a>
- </b>
- </big>
- <div class="value">
- <xsl:text>
-</xsl:text>
- <xsl:call-template name="render.source-code-link"/>
- </div>
-
- <xsl:if test="$ENABLE-DESCRIPTION and string-length(ws:documentation) &gt; 0">
- <div class="label">Description:</div>
- <div class="value">
- <xsl:value-of select="ws:documentation" disable-output-escaping="yes"/>
- </div>
- </xsl:if>
-
- <xsl:if test="$ENABLE-STYLEOPTYPEPATH">
- <xsl:variable name="binding-operation" select="$binding-info/*[local-name() = 'operation']"/>
- <xsl:if test="$binding-operation/@style">
- <div class="label">Style:</div>
- <div class="value">
- <xsl:value-of select="$binding-operation/@style"/>
- </div>
- </xsl:if>
-
- <div class="label">Operation type:</div>
- <div class="value">
- <xsl:choose>
- <xsl:when test="$binding-info/ws:input[not(../ws:output)]">
- <i>One-way.</i> The endpoint receives a message.</xsl:when>
- <xsl:when test="$binding-info/ws:input[following-sibling::ws:output]">
- <i>Request-response.</i> The endpoint receives a message, and sends a correlated message.</xsl:when>
- <xsl:when test="$binding-info/ws:input[preceding-sibling::ws:output]">
- <i>Solicit-response.</i> The endpoint sends a message, and receives a correlated message.</xsl:when>
- <xsl:when test="$binding-info/ws:output[not(../ws:input)]">
- <i>Notification.</i> The endpoint sends a message.</xsl:when>
- <xsl:otherwise>unknown</xsl:otherwise>
- </xsl:choose>
- </div>
-
- <xsl:if test="string-length($binding-operation/@soapAction) &gt; 0">
- <div class="label">SOAP action:</div>
- <div class="value">
- <xsl:value-of select="$binding-operation/@soapAction"/>
- </div>
- </xsl:if>
-
- <xsl:if test="$binding-operation/@location">
- <div class="label">HTTP path:</div>
- <div class="value">
- <xsl:value-of select="$binding-operation/@location"/>
- </div>
- </xsl:if>
- </xsl:if>
- <xsl:apply-templates select="ws:input|ws:output|ws:fault" mode="operations.message">
- <xsl:with-param name="binding-data" select="$binding-info"/>
- </xsl:apply-templates>
- </li>
- </xsl:template>
- <xsl:template match="ws:input|ws:output|ws:fault" mode="operations.message">
- <xsl:param name="binding-data"/>
- <xsl:if test="$ENABLE-INOUTFAULT">
- <div class="label">
- <xsl:value-of select="concat(translate(substring(local-name(.), 1, 1), 'abcdefghijklmnoprstuvwxyz', 'ABCDEFGHIJKLMNOPRSTUVWXYZ'), substring(local-name(.), 2), ':')"/>
- </div>
-
- <xsl:variable name="msg-local-name" select="substring-after(@message, ':')"/>
- <xsl:variable name="msg-name">
- <xsl:choose>
- <xsl:when test="$msg-local-name">
- <xsl:value-of select="$msg-local-name"/>
- </xsl:when>
- <xsl:otherwise>
- <xsl:value-of select="@message"/>
- </xsl:otherwise>
- </xsl:choose>
- </xsl:variable>
-
- <xsl:variable name="msg" select="$consolidated-wsdl/ws:message[@name = $msg-name]"/>
- <xsl:choose>
- <xsl:when test="$msg">
- <xsl:apply-templates select="$msg" mode="operations.message">
- <xsl:with-param name="binding-data"
- select="$binding-data/ws:*[local-name(.) = local-name(current())]/*"/>
- </xsl:apply-templates>
- </xsl:when>
- <xsl:otherwise>
- <div class="value">
- <i>none</i>
- </div>
- </xsl:otherwise>
- </xsl:choose>
- </xsl:if>
- </xsl:template>
- <xsl:template match="ws:message" mode="operations.message">
- <xsl:param name="binding-data"/>
- <div class="value">
- <xsl:value-of select="@name"/>
- <xsl:if test="$binding-data">
- <xsl:text> (</xsl:text>
- <xsl:value-of select="name($binding-data)"/>
- <xsl:variable name="use" select="$binding-data/@use"/>
- <xsl:if test="$use">
- <xsl:text>, use = </xsl:text>
- <xsl:value-of select="$use"/>
- </xsl:if>
- <xsl:variable name="part" select="$binding-data/@part"/>
- <xsl:if test="$part">
- <xsl:text>, part = </xsl:text>
- <xsl:value-of select="$part"/>
- </xsl:if>
- <xsl:text>)</xsl:text>
- </xsl:if>
- <xsl:call-template name="render.source-code-link"/>
- </div>
-
- <xsl:apply-templates select="ws:part" mode="operations.message"/>
- </xsl:template>
- <xsl:template match="ws:part" mode="operations.message">
- <div class="value box" style="margin-bottom: 3px">
- <xsl:choose>
- <xsl:when test="string-length(@name) &gt; 0">
- <b>
- <xsl:value-of select="@name"/>
- </b>
-
- <xsl:variable name="elem-or-type">
- <xsl:choose>
- <xsl:when test="@type">
- <xsl:value-of select="@type"/>
- </xsl:when>
- <xsl:otherwise>
- <xsl:value-of select="@element"/>
- </xsl:otherwise>
- </xsl:choose>
- </xsl:variable>
-
- <xsl:variable name="type-local-name" select="substring-after($elem-or-type, ':')"/>
- <xsl:variable name="type-name">
- <xsl:choose>
- <xsl:when test="$type-local-name">
- <xsl:value-of select="$type-local-name"/>
- </xsl:when>
- <xsl:when test="$elem-or-type">
- <xsl:value-of select="$elem-or-type"/>
- </xsl:when>
- <xsl:otherwise>unknown</xsl:otherwise>
- </xsl:choose>
- </xsl:variable>
-
- <xsl:call-template name="render-type">
- <xsl:with-param name="type-local-name" select="$type-name"/>
- </xsl:call-template>
-
- <xsl:variable name="part-type"
- select="$consolidated-xsd[@name = $type-name and not(xsd:simpleType)][1]"/>
- <xsl:apply-templates select="$part-type" mode="operations.message.part"/>
-
- </xsl:when>
- <xsl:otherwise>
- <i>none</i>
- </xsl:otherwise>
- </xsl:choose>
- </div>
- </xsl:template>
-
- <!--
-@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
- End of included transformation: wsdl-viewer-operations.xsl
-@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
--->
-
-
-
-<!--
-@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
- Begin of included transformation: wsdl-viewer-xsd-tree.xsl
-@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
--->
-<xsl:template match="xsd:simpleType" mode="operations.message.part"/>
- <xsl:template name="recursion.should.continue">
- <xsl:param name="anti.recursion"/>
- <xsl:param name="recursion.label"/>
- <xsl:param name="recursion.count">1</xsl:param>
- <xsl:variable name="has.recursion" select="contains($anti.recursion, $recursion.label)"/>
- <xsl:variable name="anti.recursion.fragment"
- select="substring-after($anti.recursion, $recursion.label)"/>
- <xsl:choose>
- <xsl:when test="$recursion.count &gt; $ANTIRECURSION-DEPTH"/>
-
- <xsl:when test="not($ENABLE-ANTIRECURSION-PROTECTION) or string-length($anti.recursion) = 0 or not($has.recursion)">
- <xsl:text>1</xsl:text>
- </xsl:when>
-
- <xsl:otherwise>
- <xsl:call-template name="recursion.should.continue">
- <xsl:with-param name="anti.recursion" select="$anti.recursion.fragment"/>
- <xsl:with-param name="recursion.label" select="$recursion.label"/>
- <xsl:with-param name="recursion.count" select="$recursion.count + 1"/>
- </xsl:call-template>
- </xsl:otherwise>
- </xsl:choose>
- </xsl:template>
- <xsl:template match="xsd:complexType" mode="operations.message.part">
- <xsl:param name="anti.recursion"/>
-
- <xsl:variable name="recursion.label" select="concat('[', @name, ']')"/>
- <xsl:variable name="recursion.test">
- <xsl:call-template name="recursion.should.continue">
- <xsl:with-param name="anti.recursion" select="$anti.recursion"/>
- <xsl:with-param name="recursion.label" select="$recursion.label"/>
- </xsl:call-template>
- </xsl:variable>
-
- <xsl:choose>
- <xsl:when test="string-length($recursion.test) != 0">
- <xsl:apply-templates select="*" mode="operations.message.part">
- <xsl:with-param name="anti.recursion" select="concat($anti.recursion, $recursion.label)"/>
- </xsl:apply-templates>
- </xsl:when>
- <xsl:otherwise>
- <span style="color:blue">
- <xsl:value-of select="$RECURSIVE"/>
- </span>
- </xsl:otherwise>
- </xsl:choose>
-
- </xsl:template>
- <xsl:template match="xsd:complexContent" mode="operations.message.part">
- <xsl:param name="anti.recursion"/>
-
- <xsl:apply-templates select="*" mode="operations.message.part">
- <xsl:with-param name="anti.recursion" select="$anti.recursion"/>
- </xsl:apply-templates>
- </xsl:template>
- <xsl:template match="xsd:complexType[descendant::xsd:attribute[ not(@*[local-name() = 'arrayType']) ]]"
- mode="operations.message.part">
- <xsl:param name="anti.recursion"/>
- <xsl:variable name="recursion.label" select="concat('[', @name, ']')"/>
- <xsl:variable name="recursion.test">
- <xsl:call-template name="recursion.should.continue">
- <xsl:with-param name="anti.recursion" select="$anti.recursion"/>
- <xsl:with-param name="recursion.label" select="$recursion.label"/>
- </xsl:call-template>
- </xsl:variable>
-
- <xsl:choose>
- <xsl:when test="string-length($recursion.test) != 0">
- <ul type="circle">
- <xsl:apply-templates select="*" mode="operations.message.part">
- <xsl:with-param name="anti.recursion" select="concat($anti.recursion, $recursion.label)"/>
- </xsl:apply-templates>
- </ul>
- </xsl:when>
- <xsl:otherwise>
- <span style="color:blue">
- <xsl:value-of select="$RECURSIVE"/>
- </span>
- </xsl:otherwise>
- </xsl:choose>
- </xsl:template>
- <xsl:template match="xsd:restriction | xsd:extension" mode="operations.message.part">
- <xsl:param name="anti.recursion"/>
- <xsl:variable name="type-local-name" select="substring-after(@base, ':')"/>
- <xsl:variable name="type-name">
- <xsl:choose>
- <xsl:when test="$type-local-name">
- <xsl:value-of select="$type-local-name"/>
- </xsl:when>
- <xsl:when test="@base">
- <xsl:value-of select="@base"/>
- </xsl:when>
- <xsl:otherwise>unknown type</xsl:otherwise>
- </xsl:choose>
- </xsl:variable>
- <xsl:variable name="base-type" select="$consolidated-xsd[@name = $type-name][1]"/>
- <!-- xsl:if test="not($type/@abstract)">
- <xsl:apply-templates select="$type"/>
- </xsl:if -->
- <xsl:if test="$base-type != 'Array'">
- <xsl:apply-templates select="$base-type" mode="operations.message.part">
- <xsl:with-param name="anti.recursion" select="$anti.recursion"/>
- </xsl:apply-templates>
- </xsl:if>
- <xsl:apply-templates select="*" mode="operations.message.part">
- <xsl:with-param name="anti.recursion" select="$anti.recursion"/>
- </xsl:apply-templates>
- </xsl:template>
- <xsl:template match="xsd:union" mode="operations.message.part">
- <xsl:call-template name="process-union">
- <xsl:with-param name="set" select="@memberTypes"/>
- </xsl:call-template>
- </xsl:template>
- <xsl:template name="process-union">
- <xsl:param name="set"/>
- <xsl:if test="$set">
- <xsl:variable name="item" select="substring-before($set, ' ')"/>
- <xsl:variable name="the-rest" select="substring-after($set, ' ')"/>
-
- <xsl:variable name="type-local-name" select="substring-after($item, ':')"/>
- <xsl:variable name="type-name">
- <xsl:choose>
- <xsl:when test="$type-local-name">
- <xsl:value-of select="$type-local-name"/>
- </xsl:when>
- <xsl:otherwise>
- <xsl:value-of select="$item"/>
- </xsl:otherwise>
- </xsl:choose>
- </xsl:variable>
-
- <xsl:call-template name="render-type">
- <xsl:with-param name="type-local-name" select="$type-name"/>
- </xsl:call-template>
-
- <xsl:call-template name="process-union">
- <xsl:with-param name="set" select="$the-rest"/>
- </xsl:call-template>
- </xsl:if>
- </xsl:template>
- <xsl:template match="xsd:sequence" mode="operations.message.part">
- <xsl:param name="anti.recursion"/>
- <ul type="square">
- <xsl:apply-templates select="*" mode="operations.message.part">
- <xsl:with-param name="anti.recursion" select="$anti.recursion"/>
- </xsl:apply-templates>
- </ul>
- </xsl:template>
- <xsl:template match="xsd:all|xsd:any|xsd:choice" mode="operations.message.part">
- <xsl:param name="anti.recursion"/>
- <xsl:variable name="list-type">
- <xsl:choose>
- <xsl:when test="self::xsd:all">disc</xsl:when>
- <xsl:when test="self::xsd:any">circle</xsl:when>
- <xsl:otherwise>square</xsl:otherwise>
- </xsl:choose>
- </xsl:variable>
-
- <xsl:element name="ul">
- <xsl:attribute name="style">
- <xsl:value-of select="concat('list-style-type:', $list-type)"/>
- </xsl:attribute>
- <xsl:apply-templates select="*" mode="operations.message.part">
- <xsl:with-param name="anti.recursion" select="$anti.recursion"/>
- </xsl:apply-templates>
- </xsl:element>
- </xsl:template>
- <xsl:template match="xsd:element[parent::xsd:schema]" mode="operations.message.part">
- <xsl:param name="anti.recursion"/>
- <xsl:variable name="recursion.label" select="concat('[', @name, ']')"/>
- <xsl:variable name="recursion.test">
- <xsl:call-template name="recursion.should.continue">
- <xsl:with-param name="anti.recursion" select="$anti.recursion"/>
- <xsl:with-param name="recursion.label" select="$recursion.label"/>
- </xsl:call-template>
- </xsl:variable>
-
- <xsl:choose>
- <xsl:when test="string-length($recursion.test) != 0">
- <xsl:variable name="type-name">
- <xsl:call-template name="xsd.element-type"/>
- </xsl:variable>
- <xsl:variable name="elem-type"
- select="$consolidated-xsd[generate-id() != generate-id(current()) and $type-name and @name=$type-name and contains(local-name(), 'Type')][1]"/>
-
- <xsl:if test="$type-name != @name">
- <xsl:apply-templates select="$elem-type" mode="operations.message.part">
- <xsl:with-param name="anti.recursion" select="concat($anti.recursion, $recursion.label)"/>
- </xsl:apply-templates>
-
- <xsl:if test="not($elem-type)">
- <xsl:call-template name="render-type">
- <xsl:with-param name="type-local-name" select="$type-name"/>
- </xsl:call-template>
- </xsl:if>
-
- <xsl:apply-templates select="*" mode="operations.message.part">
- <xsl:with-param name="anti.recursion" select="concat($anti.recursion, $recursion.label)"/>
- </xsl:apply-templates>
- </xsl:if>
- </xsl:when>
- <xsl:otherwise>
- <span style="color:blue">
- <xsl:value-of select="$RECURSIVE"/>
- </span>
- </xsl:otherwise>
- </xsl:choose>
-
- </xsl:template>
- <xsl:template match="xsd:element | xsd:attribute" mode="operations.message.part">
- <xsl:param name="anti.recursion"/>
- <!--
- <xsl:variable name="recursion.label" select="concat('[', @name, ']')"/>
--->
- <li>
- <xsl:variable name="local-ref" select="concat(@name, substring-after(@ref, ':'))"/>
- <xsl:variable name="elem-name">
- <xsl:choose>
- <xsl:when test="@name">
- <xsl:value-of select="@name"/>
- </xsl:when>
- <xsl:when test="$local-ref">
- <xsl:value-of select="$local-ref"/>
- </xsl:when>
- <xsl:when test="@ref">
- <xsl:value-of select="@ref"/>
- </xsl:when>
- <xsl:otherwise>anonymous</xsl:otherwise>
- </xsl:choose>
- </xsl:variable>
- <xsl:value-of select="$elem-name"/>
-
- <xsl:variable name="type-name">
- <xsl:call-template name="xsd.element-type"/>
- </xsl:variable>
-
- <xsl:call-template name="render-type">
- <xsl:with-param name="type-local-name" select="$type-name"/>
- </xsl:call-template>
-
- <xsl:variable name="elem-type"
- select="$consolidated-xsd[@name = $type-name and contains(local-name(), 'Type')][1]"/>
- <xsl:apply-templates select="$elem-type | *" mode="operations.message.part">
- <xsl:with-param name="anti.recursion" select="$anti.recursion"/>
- </xsl:apply-templates>
- </li>
- </xsl:template>
- <xsl:template match="xsd:attribute[ @*[local-name() = 'arrayType'] ]"
- mode="operations.message.part">
- <xsl:param name="anti.recursion"/>
- <xsl:variable name="array-local-name"
- select="substring-after(@*[local-name() = 'arrayType'], ':')"/>
- <xsl:variable name="type-local-name" select="substring-before($array-local-name, '[')"/>
- <xsl:variable name="array-type" select="$consolidated-xsd[@name = $type-local-name][1]"/>
-
- <xsl:variable name="recursion.label" select="concat('[', $type-local-name, ']')"/>
- <xsl:variable name="recursion.test">
- <xsl:call-template name="recursion.should.continue">
- <xsl:with-param name="anti.recursion" select="$anti.recursion"/>
- <xsl:with-param name="recursion.label" select="$recursion.label"/>
- </xsl:call-template>
- </xsl:variable>
-
- <xsl:choose>
- <xsl:when test="string-length($recursion.test) != 0">
- <xsl:apply-templates select="$array-type" mode="operations.message.part">
- <xsl:with-param name="anti.recursion" select="concat($anti.recursion, $recursion.label)"/>
- </xsl:apply-templates>
- </xsl:when>
- <xsl:otherwise>
- <span style="color:blue">
- <xsl:value-of select="$RECURSIVE"/>
- </span>
- </xsl:otherwise>
- </xsl:choose>
- </xsl:template>
- <xsl:template name="xsd.element-type">
- <xsl:variable name="ref-or-type">
- <xsl:choose>
- <xsl:when test="@type">
- <xsl:value-of select="@type"/>
- </xsl:when>
- <xsl:otherwise>
- <xsl:value-of select="@ref"/>
- </xsl:otherwise>
- </xsl:choose>
- </xsl:variable>
-
- <xsl:variable name="type-local-name" select="substring-after($ref-or-type, ':')"/>
- <xsl:variable name="type-name">
- <xsl:choose>
- <xsl:when test="$type-local-name">
- <xsl:value-of select="$type-local-name"/>
- </xsl:when>
- <xsl:when test="$ref-or-type">
- <xsl:value-of select="$ref-or-type"/>
- </xsl:when>
- <xsl:otherwise>undefined</xsl:otherwise>
- </xsl:choose>
- </xsl:variable>
- <xsl:value-of select="$type-name"/>
- </xsl:template>
- <xsl:template match="xsd:documentation" mode="operations.message.part">
- <div style="color:green">
- <xsl:value-of select="." disable-output-escaping="yes"/>
- </div>
- </xsl:template>
- <xsl:template name="render-type">
- <xsl:param name="anti.recursion"/>
- <xsl:param name="type-local-name"/>
-
- <xsl:if test="$ENABLE-OPERATIONS-TYPE">
- <xsl:variable name="properties">
- <xsl:if test="self::xsd:element | self::xsd:attribute[parent::xsd:complexType]">
- <xsl:variable name="min">
- <xsl:if test="@minOccurs = '0'">optional</xsl:if>
- </xsl:variable>
- <xsl:variable name="max">
- <xsl:if test="@maxOccurs = 'unbounded'">unbounded</xsl:if>
- </xsl:variable>
- <xsl:variable name="nillable">
- <xsl:if test="@nillable">nillable</xsl:if>
- </xsl:variable>
-
- <xsl:if test="(string-length($min) + string-length($max) + string-length($nillable) + string-length(@use)) &gt; 0">
- <xsl:text> - </xsl:text>
- <xsl:value-of select="$min"/>
- <xsl:if test="string-length($min) and string-length($max)">
- <xsl:text>, </xsl:text>
- </xsl:if>
- <xsl:value-of select="$max"/>
- <xsl:if test="(string-length($min) + string-length($max)) &gt; 0 and string-length($nillable)">
- <xsl:text>, </xsl:text>
- </xsl:if>
- <xsl:value-of select="$nillable"/>
- <xsl:if test="(string-length($min) + string-length($max) + string-length($nillable)) &gt; 0 and string-length(@use)">
- <xsl:text>, </xsl:text>
- </xsl:if>
- <xsl:value-of select="@use"/>
- <xsl:text>; </xsl:text>
- </xsl:if>
- </xsl:if>
- </xsl:variable>
-
- <xsl:variable name="recursion.label" select="concat('[', $type-local-name, ']')"/>
- <xsl:variable name="recursion.test">
- <xsl:call-template name="recursion.should.continue">
- <xsl:with-param name="anti.recursion" select="$anti.recursion"/>
- <xsl:with-param name="recursion.label" select="$recursion.label"/>
- <xsl:with-param name="recursion.count" select="$ANTIRECURSION-DEPTH"/>
- </xsl:call-template>
- </xsl:variable>
-
- <xsl:if test="string-length($recursion.test) != 0">
- <span style="color:blue">
- <xsl:value-of select="$properties"/>
- <xsl:variable name="elem-type"
- select="$consolidated-xsd[@name = $type-local-name and (not(contains(local-name(current()), 'element')) or contains(local-name(), 'Type'))][1]"/>
- <xsl:if test="string-length($type-local-name) &gt; 0">
- <xsl:call-template name="render-type.write-name">
- <xsl:with-param name="type-local-name" select="$type-local-name"/>
- </xsl:call-template>
- </xsl:if>
-
- <xsl:choose>
- <xsl:when test="$elem-type">
-
- <xsl:apply-templates select="$elem-type" mode="render-type">
- <xsl:with-param name="anti.recursion" select="concat($anti.recursion, $recursion.label)"/>
- </xsl:apply-templates>
- </xsl:when>
- <xsl:otherwise>
-
- <xsl:apply-templates select="*" mode="render-type">
- <xsl:with-param name="anti.recursion" select="concat($anti.recursion, $recursion.label)"/>
- </xsl:apply-templates>
- </xsl:otherwise>
- </xsl:choose>
- </span>
- </xsl:if>
- </xsl:if>
- </xsl:template>
- <xsl:template name="render-type.write-name">
- <xsl:param name="type-local-name"/>
- <xsl:text> type </xsl:text>
- <big>
- <i>
- <xsl:choose>
- <xsl:when test="$type-local-name">
- <xsl:value-of select="$type-local-name"/>
- </xsl:when>
- <xsl:otherwise>undefined</xsl:otherwise>
- </xsl:choose>
- </i>
- </big>
- </xsl:template>
- <xsl:template match="*" mode="render-type"/>
- <xsl:template match="xsd:element | xsd:complexType | xsd:simpleType | xsd:complexContent"
- mode="render-type">
- <xsl:param name="anti.recursion"/>
- <xsl:apply-templates select="*" mode="render-type">
- <xsl:with-param name="anti.recursion" select="$anti.recursion"/>
- </xsl:apply-templates>
- </xsl:template>
- <xsl:template match="xsd:restriction[ parent::xsd:simpleType ]" mode="render-type">
- <xsl:param name="anti.recursion"/>
- <xsl:variable name="type-local-name" select="substring-after(@base, ':')"/>
- <xsl:variable name="type-name">
- <xsl:choose>
- <xsl:when test="$type-local-name">
- <xsl:value-of select="$type-local-name"/>
- </xsl:when>
- <xsl:when test="@base">
- <xsl:value-of select="@base"/>
- </xsl:when>
- <xsl:otherwise>undefined</xsl:otherwise>
- </xsl:choose>
- </xsl:variable>
-
- <xsl:text> - </xsl:text>
- <xsl:call-template name="render-type.write-name">
- <xsl:with-param name="type-local-name" select="$type-local-name"/>
- </xsl:call-template>
- <xsl:text> with </xsl:text>
- <xsl:value-of select="local-name()"/>
- <xsl:apply-templates select="*" mode="render-type">
- <xsl:with-param name="anti.recursion" select="$anti.recursion"/>
- </xsl:apply-templates>
- </xsl:template>
- <xsl:template match="xsd:simpleType/xsd:restriction/xsd:*[not(self::xsd:enumeration)]"
- mode="render-type">
- <xsl:text> </xsl:text>
- <xsl:value-of select="local-name()"/>
- <xsl:text>(</xsl:text>
- <xsl:value-of select="@value"/>
- <xsl:text>)</xsl:text>
- </xsl:template>
- <xsl:template match="xsd:restriction | xsd:extension" mode="render-type">
- <xsl:param name="anti.recursion"/>
- <xsl:variable name="type-local-name" select="substring-after(@base, ':')"/>
- <xsl:variable name="type-name">
- <xsl:choose>
- <xsl:when test="$type-local-name">
- <xsl:value-of select="$type-local-name"/>
- </xsl:when>
- <xsl:when test="@base">
- <xsl:value-of select="@base"/>
- </xsl:when>
- <xsl:otherwise>undefined</xsl:otherwise>
- </xsl:choose>
- </xsl:variable>
- <xsl:variable name="base-type" select="$consolidated-xsd[@name = $type-name][1]"/>
- <xsl:variable name="abstract">
- <xsl:if test="$base-type/@abstract">abstract </xsl:if>
- </xsl:variable>
-
- <xsl:if test="not($type-name = 'Array')">
- <xsl:value-of select="concat(' - ', local-name(), ' of ', $abstract)"/>
- <xsl:call-template name="render-type.write-name">
- <xsl:with-param name="type-local-name" select="$type-name"/>
- </xsl:call-template>
- </xsl:if>
-
- <xsl:apply-templates select="$base-type | *" mode="render-type">
- <xsl:with-param name="anti.recursion" select="$anti.recursion"/>
- </xsl:apply-templates>
- </xsl:template>
- <xsl:template match="xsd:attribute[ @*[local-name() = 'arrayType'] ]" mode="render-type">
- <xsl:param name="anti.recursion"/>
- <xsl:variable name="array-local-name"
- select="substring-after(@*[local-name() = 'arrayType'], ':')"/>
- <xsl:variable name="type-local-name" select="substring-before($array-local-name, '[')"/>
- <xsl:variable name="array-type" select="$consolidated-xsd[@name = $type-local-name][1]"/>
-
- <xsl:text> - array of </xsl:text>
- <xsl:call-template name="render-type.write-name">
- <xsl:with-param name="type-local-name" select="$type-local-name"/>
- </xsl:call-template>
-
- <xsl:apply-templates select="$array-type" mode="render-type">
- <xsl:with-param name="anti.recursion" select="$anti.recursion"/>
- </xsl:apply-templates>
- </xsl:template>
- <xsl:template match="xsd:enumeration" mode="render-type"/>
- <xsl:template match="xsd:enumeration[not(preceding-sibling::xsd:enumeration)]"
- mode="render-type">
- <xsl:text> - enum { </xsl:text>
- <xsl:apply-templates select="self::* | following-sibling::xsd:enumeration" mode="render-type.enum"/>
- <xsl:text> }</xsl:text>
- </xsl:template>
- <xsl:template match="xsd:enumeration" mode="render-type.enum">
- <xsl:if test="preceding-sibling::xsd:enumeration">
- <xsl:text>, </xsl:text>
- </xsl:if>
- <xsl:text disable-output-escaping="yes">'</xsl:text>
- <xsl:value-of select="@value"/>
- <xsl:text disable-output-escaping="yes">'</xsl:text>
- </xsl:template>
-
- <!--
-@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
- End of included transformation: wsdl-viewer-xsd-tree.xsl
-@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
--->
-
-
-
-<!--
-@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
- Begin of included transformation: wsdl-viewer-src.xsl
-@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
--->
-<xsl:template match="@*" mode="src.import">
- <xsl:param name="src.import.stack"/>
- <xsl:variable name="recursion.label" select="concat('[', string(.), ']')"/>
- <xsl:variable name="recursion.check" select="concat($src.import.stack, $recursion.label)"/>
-
- <xsl:choose>
- <xsl:when test="contains($src.import.stack, $recursion.label)">
- <h2 style="red">
- <xsl:value-of select="concat('Cyclic include / import: ', $recursion.check)"/>
- </h2>
- </xsl:when>
- <xsl:otherwise>
- <h2>
- <a name="{concat($SRC-FILE-PREFIX, generate-id(..))}">
- <xsl:choose>
- <xsl:when test="parent::xsd:include">Included </xsl:when>
- <xsl:otherwise>Imported </xsl:otherwise>
- </xsl:choose>
-
- <xsl:choose>
- <xsl:when test="name() = 'location'">WSDL </xsl:when>
- <xsl:otherwise>Schema </xsl:otherwise>
- </xsl:choose>
- <i>
- <xsl:value-of select="."/>
- </i>
- </a>
- </h2>
-
- <div class="box">
- <xsl:apply-templates select="document(string(.))" mode="src"/>
- </div>
-
- <xsl:apply-templates select="document(string(.))/*/*[local-name() = 'import'][@location]/@location"
- mode="src.import">
- <xsl:with-param name="src.import.stack" select="$recursion.check"/>
- </xsl:apply-templates>
- <xsl:apply-templates select="document(string(.))//xsd:import[@schemaLocation]/@schemaLocation"
- mode="src.import">
- <xsl:with-param name="src.import.stack" select="$recursion.check"/>
- </xsl:apply-templates>
- </xsl:otherwise>
- </xsl:choose>
- </xsl:template>
- <xsl:template match="*" mode="src">
- <div class="xml-element">
- <a name="{concat($SRC-PREFIX, generate-id(.))}">
- <xsl:apply-templates select="." mode="src.link"/>
- <xsl:apply-templates select="." mode="src.start-tag"/>
- </a>
- <xsl:apply-templates select="*|comment()|processing-instruction()|text()[string-length(normalize-space(.)) &gt; 0]"
- mode="src"/>
- <xsl:apply-templates select="." mode="src.end-tag"/>
- </div>
- </xsl:template>
- <xsl:template match="*" mode="src.start-tag">
- <xsl:call-template name="src.elem">
- <xsl:with-param name="src.elem.end-slash"> /</xsl:with-param>
- </xsl:call-template>
- </xsl:template>
- <xsl:template match="*[*|comment()|processing-instruction()|text()[string-length(normalize-space(.)) &gt; 0]]"
- mode="src.start-tag">
- <xsl:call-template name="src.elem"/>
- </xsl:template>
- <xsl:template match="*" mode="src.end-tag"/>
- <xsl:template match="*[*|comment()|processing-instruction()|text()[string-length(normalize-space(.)) &gt; 0]]"
- mode="src.end-tag">
- <xsl:call-template name="src.elem">
- <xsl:with-param name="src.elem.start-slash">/</xsl:with-param>
- </xsl:call-template>
- </xsl:template>
- <xsl:template match="*" mode="src.link-attribute">
- <xsl:if test="$ENABLE-LINK">
- <xsl:attribute name="href">
- <xsl:value-of select="concat('#', $SRC-PREFIX, generate-id(.))"/>
- </xsl:attribute>
- </xsl:if>
- </xsl:template>
- <xsl:template match="*[local-name() = 'import' or local-name() = 'include'][@location or @schemaLocation]"
- mode="src.link">
- <xsl:if test="$ENABLE-LINK">
- <xsl:attribute name="href">
- <xsl:value-of select="concat('#', $SRC-FILE-PREFIX, generate-id(.))"/>
- </xsl:attribute>
- </xsl:if>
- </xsl:template>
- <xsl:template match="*" mode="src.link"/>
- <xsl:template match="ws2:service|ws2:binding" mode="src.link">
- <xsl:variable name="iface-name">
- <xsl:apply-templates select="@interface" mode="qname.normalized"/>
- </xsl:variable>
- <xsl:apply-templates select="$consolidated-wsdl/ws2:interface[@name = $iface-name]"
- mode="src.link-attribute"/>
- </xsl:template>
- <xsl:template match="ws2:endpoint" mode="src.link">
- <xsl:variable name="binding-name">
- <xsl:apply-templates select="@binding" mode="qname.normalized"/>
- </xsl:variable>
- <xsl:apply-templates select="$consolidated-wsdl/ws2:binding[@name = $binding-name]"
- mode="src.link-attribute"/>
- </xsl:template>
- <xsl:template match="ws2:binding/ws2:operation" mode="src.link">
- <xsl:variable name="operation-name">
- <xsl:apply-templates select="@ref" mode="qname.normalized"/>
- </xsl:variable>
- <xsl:apply-templates select="$consolidated-wsdl/ws2:interface/ws2:operation[@name = $operation-name]"
- mode="src.link-attribute"/>
- </xsl:template>
- <xsl:template match="ws2:binding/ws2:fault|ws2:interface/ws2:operation/ws2:infault|ws2:interface/ws2:operation/ws2:outfault"
- mode="src.link">
- <xsl:variable name="operation-name">
- <xsl:apply-templates select="@ref" mode="qname.normalized"/>
- </xsl:variable>
- <xsl:apply-templates select="$consolidated-wsdl/ws2:interface/ws2:fault[@name = $operation-name]"
- mode="src.link-attribute"/>
- </xsl:template>
- <xsl:template match="ws2:interface/ws2:operation/ws2:input|ws2:interface/ws2:operation/ws2:output|ws2:interface/ws2:fault"
- mode="src.link">
- <xsl:variable name="elem-name">
- <xsl:apply-templates select="@element" mode="qname.normalized"/>
- </xsl:variable>
- <xsl:apply-templates select="$consolidated-xsd[@name = $elem-name]" mode="src.link-attribute"/>
- </xsl:template>
- <xsl:template match="ws:operation/ws:input[@message] | ws:operation/ws:output[@message] | ws:operation/ws:fault[@message] | soap:header[ancestor::ws:operation and @message]"
- mode="src.link">
- <xsl:apply-templates select="$consolidated-wsdl/ws:message[@name = substring-after( current()/@message, ':' )]"
- mode="src.link-attribute"/>
- </xsl:template>
- <xsl:template match="ws:operation/ws:input[@message] | ws:operation/ws:output[@message] | ws:operation/ws:fault[@message] | soap:header[ancestor::ws:operation and @message]"
- mode="src.link">
- <xsl:apply-templates select="$consolidated-wsdl/ws:message[@name = substring-after( current()/@message, ':' )]"
- mode="src.link-attribute"/>
- </xsl:template>
- <xsl:template match="ws:message/ws:part[@element or @type]" mode="src.link">
- <xsl:variable name="elem-local-name" select="substring-after(@element, ':')"/>
- <xsl:variable name="type-local-name" select="substring-after(@type, ':')"/>
- <xsl:variable name="elem-name">
- <xsl:choose>
- <xsl:when test="$elem-local-name">
- <xsl:value-of select="$elem-local-name"/>
- </xsl:when>
- <xsl:when test="$type-local-name">
- <xsl:value-of select="$type-local-name"/>
- </xsl:when>
- <xsl:when test="@element">
- <xsl:value-of select="@element"/>
- </xsl:when>
- <xsl:when test="@type">
- <xsl:value-of select="@type"/>
- </xsl:when>
- <xsl:otherwise>
- <xsl:call-template name="src.syntax-error"/>
- </xsl:otherwise>
- </xsl:choose>
- </xsl:variable>
-
- <xsl:apply-templates select="$consolidated-xsd[@name = $elem-name]" mode="src.link-attribute"/>
- </xsl:template>
- <xsl:template match="ws:service/ws:port[@binding]" mode="src.link">
- <xsl:variable name="binding-name">
- <xsl:apply-templates select="@binding" mode="qname.normalized"/>
- </xsl:variable>
- <xsl:apply-templates select="$consolidated-wsdl/ws:binding[@name = $binding-name]"
- mode="src.link-attribute"/>
- </xsl:template>
- <xsl:template match="ws:operation[@name and parent::ws:binding/@type]" mode="src.link">
- <xsl:variable name="type-name">
- <xsl:apply-templates select="../@type" mode="qname.normalized"/>
- </xsl:variable>
- <xsl:apply-templates select="$consolidated-wsdl/ws:portType[@name = $type-name]/ws:operation[@name = current()/@name]"
- mode="src.link-attribute"/>
- </xsl:template>
- <xsl:template match="xsd:element[@ref or @type]" mode="src.link">
- <xsl:variable name="ref-or-type">
- <xsl:choose>
- <xsl:when test="@type">
- <xsl:value-of select="@type"/>
- </xsl:when>
- <xsl:otherwise>
- <xsl:value-of select="@ref"/>
- </xsl:otherwise>
- </xsl:choose>
- </xsl:variable>
-
- <xsl:variable name="type-local-name" select="substring-after($ref-or-type, ':')"/>
- <xsl:variable name="xsd-name">
- <xsl:choose>
- <xsl:when test="$type-local-name">
- <xsl:value-of select="$type-local-name"/>
- </xsl:when>
- <xsl:when test="$ref-or-type">
- <xsl:value-of select="$ref-or-type"/>
- </xsl:when>
- <xsl:otherwise/>
- </xsl:choose>
- </xsl:variable>
-
- <xsl:if test="$xsd-name">
- <xsl:variable name="msg"
- select="$consolidated-xsd[@name = $xsd-name and contains(local-name(), 'Type')][1]"/>
- <xsl:apply-templates select="$msg" mode="src.link-attribute"/>
- </xsl:if>
- </xsl:template>
- <xsl:template match="xsd:attribute[contains(@ref, 'arrayType')]" mode="src.link">
- <xsl:variable name="att-array-type"
- select="substring-before(@*[local-name() = 'arrayType'], '[]')"/>
- <xsl:variable name="xsd-local-name" select="substring-after($att-array-type, ':')"/>
- <xsl:variable name="xsd-name">
- <xsl:choose>
- <xsl:when test="$xsd-local-name">
- <xsl:value-of select="$xsd-local-name"/>
- </xsl:when>
- <xsl:otherwise>
- <xsl:value-of select="$att-array-type"/>
- </xsl:otherwise>
- </xsl:choose>
- </xsl:variable>
- <xsl:if test="$xsd-name">
- <xsl:variable name="msg" select="$consolidated-xsd[@name = $xsd-name][1]"/>
- <xsl:apply-templates select="$msg" mode="src.link-attribute"/>
- </xsl:if>
- </xsl:template>
- <xsl:template match="xsd:extension | xsd:restriction" mode="src.link">
- <xsl:variable name="xsd-local-name" select="substring-after(@base, ':')"/>
- <xsl:variable name="xsd-name">
- <xsl:choose>
- <xsl:when test="$xsd-local-name">
- <xsl:value-of select="$xsd-local-name"/>
- </xsl:when>
- <xsl:otherwise>
- <xsl:value-of select="@type"/>
- </xsl:otherwise>
- </xsl:choose>
- </xsl:variable>
- <xsl:variable name="msg" select="$consolidated-xsd[@name = $xsd-name][1]"/>
- <xsl:apply-templates select="$msg" mode="src.link-attribute"/>
- </xsl:template>
- <xsl:template name="src.elem">
- <xsl:param name="src.elem.start-slash"/>
- <xsl:param name="src.elem.end-slash"/>
-
- <xsl:value-of select="concat('&lt;', $src.elem.start-slash, name(.))"
- disable-output-escaping="no"/>
- <xsl:if test="not($src.elem.start-slash)">
- <xsl:apply-templates select="@*" mode="src"/>
- <xsl:apply-templates select="." mode="src.namespace"/>
- </xsl:if>
- <xsl:value-of select="concat($src.elem.end-slash, '&gt;')" disable-output-escaping="no"/>
- </xsl:template>
- <xsl:template match="@*" mode="src">
- <xsl:text> </xsl:text>
- <span class="xml-att">
- <xsl:value-of select="concat(name(), '=')"/>
- <span class="xml-att-val">
- <xsl:value-of select="concat('&#34;', ., '&#34;')" disable-output-escaping="yes"/>
- </span>
- </span>
- </xsl:template>
- <xsl:template match="*" mode="src.namespace">
- <xsl:variable name="supports-namespace-axis" select="count(/*/namespace::*) &gt; 0"/>
- <xsl:variable name="current" select="current()"/>
-
- <xsl:choose>
- <xsl:when test="count(/*/namespace::*) &gt; 0">
- <!--
- When the namespace axis is present (e.g. Internet Explorer), we can simulate
- the namespace declarations by comparing the namespaces in scope on this element
- with those in scope on the parent element. Any difference must have been the
- result of a namespace declaration. Note that this doesn't reflect the actual
- source - it will strip out redundant namespace declarations.
- -->
- <xsl:for-each select="namespace::*[. != 'http://www.w3.org/XML/1998/namespace']">
- <xsl:if test="not($current/parent::*[namespace::*[. = current()]])">
- <div class="xml-att">
- <xsl:text> xmlns</xsl:text>
- <xsl:if test="string-length(name())">:</xsl:if>
- <xsl:value-of select="concat(name(), '=')"/>
- <span class="xml-att-val">
- <xsl:value-of select="concat('&#34;', ., '&#34;')" disable-output-escaping="yes"/>
- </span>
- </div>
- </xsl:if>
- </xsl:for-each>
- </xsl:when>
- <xsl:otherwise>
- <!--
- When the namespace axis isn't supported (e.g. Mozilla), we can simulate
- appropriate declarations from namespace elements.
- This currently doesn't check for namespaces on attributes.
- In the general case we can't reliably detect the use of QNames in content, but
- in the case of schema, we know which content could contain a QName and look
- there too. This mechanism is rather unpleasant though, since it records
- namespaces where they are used rather than showing where they are declared
- (on some parent element) in the source. Yukk!
- -->
- <xsl:if test="namespace-uri(.) != namespace-uri(parent::*) or not(parent::*)">
- <span class="xml-att">
- <xsl:text> xmlns</xsl:text>
- <xsl:if test="substring-before(name(),':') != ''">:</xsl:if>
- <xsl:value-of select="substring-before(name(),':')"/>
- <xsl:text>=</xsl:text>
- <span class="xml-att-val">
- <xsl:value-of select="concat('&#34;', namespace-uri(.), '&#34;')" disable-output-escaping="yes"/>
- </span>
- </span>
- </xsl:if>
- </xsl:otherwise>
- </xsl:choose>
-
- </xsl:template>
- <xsl:template match="text()" mode="src">
- <span class="xml-text">
- <xsl:value-of select="." disable-output-escaping="no"/>
- </span>
- </xsl:template>
- <xsl:template match="comment()" mode="src">
- <div class="xml-comment">
- <xsl:text disable-output-escaping="no">&lt;!-- </xsl:text>
- <xsl:value-of select="." disable-output-escaping="no"/>
- <xsl:text disable-output-escaping="no"> --&gt;
-</xsl:text>
- </div>
- </xsl:template>
- <xsl:template match="processing-instruction()" mode="src">
- <div class="xml-proc">
- <xsl:text disable-output-escaping="no">&lt;?</xsl:text>
- <xsl:copy-of select="name(.)"/>
- <xsl:value-of select="concat(' ', .)" disable-output-escaping="yes"/>
- <xsl:text disable-output-escaping="no"> ?&gt;
-</xsl:text>
- </div>
- </xsl:template>
-
- <!--
-@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
- End of included transformation: wsdl-viewer-src.xsl
-@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
--->
-
-
-
-
-
-<!--
-==================================================================
- Starting point
-==================================================================
--->
-
-<xsl:template match="/">
- <html>
- <xsl:call-template name="head.render"/>
- <xsl:call-template name="body.render"/>
- </html>
- </xsl:template>
-
-
-
- <!--
-==================================================================
- Rendering: HTML head
-==================================================================
--->
-
-<xsl:template name="head.render">
- <head>
- <title>
- <xsl:value-of select="concat($html-title, ' - ', 'Generated by wsdl-viewer.xsl')"/>
- </title>
- <meta http-equiv="content-type" content="text/html; charset=utf-8"/>
- <meta http-equiv="content-script-type" content="text/javascript"/>
- <meta http-equiv="content-style-type" content="text/css"/>
- <meta name="Generator" content="http://tomi.vanek.sk/xml/wsdl-viewer.xsl"/>
-
- <meta http-equiv="imagetoolbar" content="false"/>
- <meta name="MSSmartTagsPreventParsing" content="true"/>
-
- <style type="text/css">
- <xsl:value-of select="$css" disable-output-escaping="yes"/>
- </style>
-
- <script src="wsdl-viewer.js" type="text/javascript" language="javascript">
- <xsl:comment>
- <xsl:text>
- // </xsl:text>
- </xsl:comment>
- </script>
- </head>
- </xsl:template>
-
-
-
- <!--
-==================================================================
- Rendering: HTML body
-==================================================================
--->
-
-<xsl:template name="body.render">
- <body id="operations">
- <div id="outer_box">
- <div id="inner_box" onload="pagingInit()">
- <xsl:call-template name="title.render"/>
-
-
- <!-- TODO: pages with tabs for selecting some aspect of the WSDL
- <xsl:call-template name="navig.render"/>
--->
-
- <xsl:call-template name="content.render"/>
- <xsl:call-template name="footer.render"/>
- </div>
- </div>
- </body>
- </xsl:template>
-
-
-
- <!--
-==================================================================
- Rendering: heading
-==================================================================
--->
-
-<xsl:template name="title.render">
- <div id="header">
- <h1>
- <xsl:value-of select="$html-title"/>
- </h1>
- </div>
- </xsl:template>
-
-
-
- <!--
-==================================================================
- Rendering: navigation
-==================================================================
--->
-
-<xsl:template name="navig.render">
- <div id="outer_nav">
- <div id="nav" class="floatcontainer">
- <ul>
- <li id="nav-service">
- <a href="#page.service">Service</a>
- </li>
- <li id="nav-operations">
- <a href="#page.operations">Operations</a>
- </li>
- <li id="nav-wsdl">
- <a href="#page.src">Source Code</a>
- </li>
-
-
- <!-- <li id="nav-client"><a href="#TODO-1">Client</a></li>
-
-
-
- <li id="nav-about">
- <a href="#page.about" class="current">About</a>
- </li>-->
- </ul>
- </div>
- </div>
- </xsl:template>
-
-
-
- <!--
-==================================================================
- Rendering: content
-==================================================================
--->
-
-<xsl:template name="content.render">
- <div id="content">
- <xsl:if test="$ENABLE-SERVICE-PARAGRAPH">
- <xsl:call-template name="service.render"/>
- </xsl:if>
- <xsl:if test="$ENABLE-OPERATIONS-PARAGRAPH">
- <xsl:call-template name="operations.render"/>
- </xsl:if>
- <xsl:if test="$ENABLE-SRC-CODE-PARAGRAPH">
- <xsl:call-template name="src.render"/>
- </xsl:if>
- <xsl:if test="$ENABLE-ABOUT-PARAGRAPH">
- <xsl:call-template name="about.render">
- <xsl:with-param name="version" select="$wsdl-viewer.version"/>
- </xsl:call-template>
- </xsl:if>
- </div>
- </xsl:template>
-
-
-
- <!--
-==================================================================
- Rendering: footer
-==================================================================
--->
-
-<xsl:template name="footer.render">
- <div id="footer">
- This page was generated by wsdl-viewer.xsl (<a href="http://tomi.vanek.sk">http://tomi.vanek.sk</a>)
-</div>
- </xsl:template>
-
-
-
- <!--
-==================================================================
- Rendering: WSDL service information
-==================================================================
--->
-
-<xsl:template name="service.render">
- <div class="page">
- <a class="target" name="page.service">
- <h2>
- <xsl:value-of select="$html-title"/>
- </h2>
- </a>
- <xsl:apply-templates select="$consolidated-wsdl/*[local-name(.) = 'documentation']"
- mode="documentation.render"/>
- <xsl:apply-templates select="$consolidated-wsdl/ws:service|$consolidated-wsdl/ws2:service"
- mode="service-start"/>
- <xsl:if test="not($consolidated-wsdl/*[local-name() = 'service']/@name)">
-
-
-<!-- If the WS is without implementation, just with binding points = WS interface -->
-
- <xsl:apply-templates select="$consolidated-wsdl/ws:binding" mode="service-start"/>
- <xsl:apply-templates select="$consolidated-wsdl/ws2:interface" mode="service"/>
- </xsl:if>
- </div>
- </xsl:template>
-
-
-
- <!--
-==================================================================
- Rendering: WSDL operations - detail
-==================================================================
--->
-
-<xsl:template name="operations.render">
- <div class="page">
- <a class="target" name="page.operations">
- <h2>Operations</h2>
- </a>
- <ul>
- <xsl:apply-templates select="$consolidated-wsdl/ws:portType" mode="operations">
- <xsl:sort select="@name"/>
- </xsl:apply-templates>
-
- <xsl:choose>
- <xsl:when test="$consolidated-wsdl/*[local-name() = 'service']/@name">
- <xsl:variable name="iface-name">
- <xsl:apply-templates select="$consolidated-wsdl/*[local-name() = 'service']/@interface"
- mode="qname.normalized"/>
- </xsl:variable>
- <xsl:apply-templates select="$consolidated-wsdl/ws2:interface[@name = $iface-name]"
- mode="operations">
- <xsl:sort select="@name"/>
- </xsl:apply-templates>
- </xsl:when>
- <xsl:when test="$consolidated-wsdl/ws2:interface/@name">
-
-
-<!-- TODO: What to do if there are more interfaces? -->
-
- <xsl:apply-templates select="$consolidated-wsdl/ws2:interface[1]" mode="operations"/>
- </xsl:when>
- <xsl:otherwise>
-
-
-<!-- TODO: Error message or handling somehow this unexpected situation -->
-
- </xsl:otherwise>
- </xsl:choose>
- </ul>
- </div>
- </xsl:template>
-
-
-
- <!--
-==================================================================
- Rendering: WSDL and XSD source code files
-==================================================================
--->
-
-<xsl:template name="src.render">
- <div class="page">
- <a class="target" name="page.src">
- <h2>WSDL source code</h2>
- </a>
- <div class="box">
- <div class="xml-proc">
- <xsl:text>&lt;?xml version="1.0"?&gt;</xsl:text>
- </div>
- <xsl:apply-templates select="/" mode="src"/>
- </div>
-
- <xsl:apply-templates select="/*/*[local-name() = 'import'][@location]/@location" mode="src.import"/>
- <xsl:apply-templates select="$consolidated-wsdl/*[local-name() = 'types']//xsd:import[@schemaLocation]/@schemaLocation | $consolidated-wsdl/*[local-name() = 'types']//xsd:include[@schemaLocation]/@schemaLocation"
- mode="src.import"/>
- </div>
- </xsl:template>
-
-
-
- <!--
-==================================================================
- Rendering: About
-==================================================================
--->
-
-<xsl:template name="about.render">
- <xsl:param name="version"/>
- <div class="page">
- <a class="target" name="page.about">
- <h2>About <em>wsdl-viewer.xsl</em>
- </h2>
- </a>
- <div class="floatcontainer">
- <div id="fix_column">
- <div class="shadow">
- <div class="box">
- <xsl:call-template name="processor-info.render"/>
- </div>
- </div>
- </div>
-
- <div id="flexi_column">
- <xsl:call-template name="about.detail">
- <xsl:with-param name="version" select="$wsdl-viewer.version"/>
- </xsl:call-template>
- </div>
- </div>
- </div>
- </xsl:template>
-
-
-</xsl:stylesheet> \ No newline at end of file
diff --git a/qpid/java/management/client/console/wsdm_rmd_perspective.jsp b/qpid/java/management/client/console/wsdm_rmd_perspective.jsp
index fc114a962d..fe70930627 100644
--- a/qpid/java/management/client/console/wsdm_rmd_perspective.jsp
+++ b/qpid/java/management/client/console/wsdm_rmd_perspective.jsp
@@ -18,7 +18,7 @@
<body>
<div id="page" align="center">
<jsp:include page="/fragments/header.jsp">
- <jsp:param name="title" value="Resource Management - WS-DM WSDL Perspective"/>
+ <jsp:param name="title" value="Resource Management - WS-DM RMD Perspective"/>
</jsp:include>
<div id="content" align="center">
@@ -63,12 +63,8 @@
</tr>
<tr>
<td valign="top">
- <div class="panel" align="justify" style="height:500px; overflow-y:auto;">
- <c:set var="xml">
- ${wsdl}
- </c:set>
- <c:import var="xslt" url="wsdl-viewer.xsl" />
- <x:transform xml="${xml}" xslt="${xslt}" />
+ <div class="panel" align="left" style="height:500px; width=200px; overflow-y:auto; font-size: smaller; font-weight:bold;">
+ <pre> <c:out value="${rmd}" /> </pre>
</div>
</td>
</tr>
diff --git a/qpid/java/management/client/console/wsdm_wsdl_perspective.jsp b/qpid/java/management/client/console/wsdm_wsdl_perspective.jsp
index b725716fd8..3759459842 100644
--- a/qpid/java/management/client/console/wsdm_wsdl_perspective.jsp
+++ b/qpid/java/management/client/console/wsdm_wsdl_perspective.jsp
@@ -63,12 +63,8 @@
</tr>
<tr>
<td valign="top">
- <div class="panel" align="justify" style="height:500px; overflow-y:auto;">
- <c:set var="xml">
- ${wsdl}
- </c:set>
- <c:import var="xslt" url="wsdl-viewer.xsl" />
- <x:transform xml="${xml}" xslt="${xslt}" />
+ <div class="panel" align="left" style="height:500px; width=200px; overflow-y:auto; font-size: smaller; font-weight:bold;">
+ <pre> <c:out value="${wsdl}" /> </pre>
</div>
</td>
</tr>
diff --git a/qpid/java/management/client/src/example/PauseAndResumeSubscription.out.ok b/qpid/java/management/client/src/example/PauseAndResumeSubscription.out.ok
new file mode 100644
index 0000000000..8a98e1d0b7
--- /dev/null
+++ b/qpid/java/management/client/src/example/PauseAndResumeSubscription.out.ok
@@ -0,0 +1,133 @@
+This example is demonstrating a WS-Notification scenario
+when (for simplicity) QMan is at the same time consumer
+and producer.
+
+Specifically the example shows how a requestor can create,
+pause and resume a subscription.
+Type enter to proceed...
+
+[CLIENT TRACE] SOAP envelope contents (outgoing):
+
+<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope">
+ <soap:Header>
+ <wsa:To xmlns:wsa="http://www.w3.org/2005/08/addressing">http://romagazzarini:8080/qman/services/adapter</wsa:To>
+ <wsa:Action xmlns:wsa="http://www.w3.org/2005/08/addressing">http://docs.oasis-open.org/wsn/bw-2/NotificationProducer/SubscribeRequest</wsa:Action>
+ <wsa:MessageID xmlns:wsa="http://www.w3.org/2005/08/addressing">uuid:485cc87c-660e-de43-e8fa-4ad5fffa95a6</wsa:MessageID>
+ <wsa:From xmlns:wsa="http://www.w3.org/2005/08/addressing">
+ <wsa:Address>http://www.w3.org/2005/08/addressing/role/anonymous</wsa:Address>
+ </wsa:From>
+ </soap:Header>
+ <soap:Body>
+ <wsnt:Subscribe xmlns:wsnt="http://docs.oasis-open.org/wsn/b-2">
+ <wsnt:ConsumerReference>
+ <wsa:Address xmlns:wsa="http://www.w3.org/2005/08/addressing">http://romagazzarini:8080/qman/services/consumer</wsa:Address>
+ </wsnt:ConsumerReference>
+ </wsnt:Subscribe>
+ </soap:Body>
+</soap:Envelope>
+
+[CLIENT TRACE] SOAP envelope contents (incoming):
+
+<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope">
+ <soap:Header>
+ <wsa:To xmlns:wsa="http://www.w3.org/2005/08/addressing">http://www.w3.org/2005/08/addressing/role/anonymous</wsa:To>
+ <wsa:Action xmlns:wsa="http://www.w3.org/2005/08/addressing">http://docs.oasis-open.org/wsn/bw-2/NotificationProducer/SubscribeResponse</wsa:Action>
+ <wsa:MessageID xmlns:wsa="http://www.w3.org/2005/08/addressing">uuid:0ee610d1-e211-95c6-a498-e1084a610c44</wsa:MessageID>
+ <wsa:RelatesTo RelationshipType="wsa:Reply" xmlns:wsa="http://www.w3.org/2005/08/addressing">uuid:485cc87c-660e-de43-e8fa-4ad5fffa95a6</wsa:RelatesTo>
+ <wsa:From xmlns:wsa="http://www.w3.org/2005/08/addressing">
+ <wsa:Address>http://romagazzarini:8080/qman/services/adapter</wsa:Address>
+ </wsa:From>
+ </soap:Header>
+ <soap:Body>
+ <wsnt:SubscribeResponse xmlns:wsnt="http://docs.oasis-open.org/wsn/b-2">
+ <wsnt:SubscriptionReference>
+ <wsa:Address xmlns:wsa="http://www.w3.org/2005/08/addressing">http://romagazzarini:8080/qman/services/SubscriptionManager</wsa:Address>
+ <wsa:ReferenceParameters xmlns:wsa="http://www.w3.org/2005/08/addressing">
+ <qman-wsa:ResourceId xmlns:qman-wsa="http://amqp.apache.org/qpid/management/qman/addressing">282f28e6-4396-4000-a19d-87a03978e8a0</qman-wsa:ResourceId>
+ </wsa:ReferenceParameters>
+ </wsnt:SubscriptionReference>
+ <wsnt:CurrentTime>2009-02-27T13:51:56+01:00</wsnt:CurrentTime>
+ </wsnt:SubscribeResponse>
+ </soap:Body>
+</soap:Envelope>
+
+[CLIENT TRACE] SOAP envelope contents (outgoing):
+
+<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope">
+ <soap:Header>
+ <wsa:To xmlns:wsa="http://www.w3.org/2005/08/addressing">http://romagazzarini:8080/qman/services/SubscriptionManager</wsa:To>
+ <wsa:Action xmlns:wsa="http://www.w3.org/2005/08/addressing">http://docs.oasis-open.org/wsn/bw-2/SubscriptionManager/PauseSubscriptionRequest</wsa:Action>
+ <wsa:MessageID xmlns:wsa="http://www.w3.org/2005/08/addressing">uuid:35cc80af-84ac-2456-3e1f-edc2a7f60970</wsa:MessageID>
+ <wsa:From xmlns:wsa="http://www.w3.org/2005/08/addressing">
+ <wsa:Address>http://www.w3.org/2005/08/addressing/role/anonymous</wsa:Address>
+ </wsa:From>
+ <qman-wsa:ResourceId
+ xmlns:wsa="http://www.w3.org/2005/08/addressing"
+ wsa:IsReferenceParameter="true" xmlns:qman-wsa="http://amqp.apache.org/qpid/management/qman/addressing">282f28e6-4396-4000-a19d-87a03978e8a0</qman-wsa:ResourceId>
+ </soap:Header>
+ <soap:Body>
+ <wsnt:PauseSubscription xmlns:wsnt="http://docs.oasis-open.org/wsn/b-2"/>
+ </soap:Body>
+</soap:Envelope>
+
+[CLIENT TRACE] SOAP envelope contents (incoming):
+
+<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope">
+ <soap:Header>
+ <wsa:To xmlns:wsa="http://www.w3.org/2005/08/addressing">http://www.w3.org/2005/08/addressing/role/anonymous</wsa:To>
+ <wsa:Action xmlns:wsa="http://www.w3.org/2005/08/addressing">http://docs.oasis-open.org/wsn/bw-2/SubscriptionManager/PauseSubscriptionResponse</wsa:Action>
+ <wsa:MessageID xmlns:wsa="http://www.w3.org/2005/08/addressing">uuid:bb53d38a-428c-3d90-cc45-29d5cb27a8df</wsa:MessageID>
+ <wsa:RelatesTo RelationshipType="wsa:Reply" xmlns:wsa="http://www.w3.org/2005/08/addressing">uuid:35cc80af-84ac-2456-3e1f-edc2a7f60970</wsa:RelatesTo>
+ <wsa:From xmlns:wsa="http://www.w3.org/2005/08/addressing">
+ <wsa:Address>http://romagazzarini:8080/qman/services/SubscriptionManager</wsa:Address>
+ <wsa:ReferenceParameters>
+ <qman-wsa:ResourceId wsa:IsReferenceParameter="true"
+ xmlns:qman-wsa="http://amqp.apache.org/qpid/management/qman/addressing" xmlns:wsa="http://www.w3.org/2005/08/addressing">282f28e6-4396-4000-a19d-87a03978e8a0</qman-wsa:ResourceId>
+ </wsa:ReferenceParameters>
+ </wsa:From>
+ </soap:Header>
+ <soap:Body>
+ <muse-op:PauseSubscriptionResponse xmlns:muse-op="http://docs.oasis-open.org/wsn/b-2"/>
+ </soap:Body>
+</soap:Envelope>
+
+[CLIENT TRACE] SOAP envelope contents (outgoing):
+
+<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope">
+ <soap:Header>
+ <wsa:To xmlns:wsa="http://www.w3.org/2005/08/addressing">http://romagazzarini:8080/qman/services/SubscriptionManager</wsa:To>
+ <wsa:Action xmlns:wsa="http://www.w3.org/2005/08/addressing">http://docs.oasis-open.org/wsn/bw-2/SubscriptionManager/ResumeSubscriptionRequest</wsa:Action>
+ <wsa:MessageID xmlns:wsa="http://www.w3.org/2005/08/addressing">uuid:bfb48615-905a-e472-a9ca-5483fa592f60</wsa:MessageID>
+ <wsa:From xmlns:wsa="http://www.w3.org/2005/08/addressing">
+ <wsa:Address>http://www.w3.org/2005/08/addressing/role/anonymous</wsa:Address>
+ </wsa:From>
+ <qman-wsa:ResourceId
+ xmlns:wsa="http://www.w3.org/2005/08/addressing"
+ wsa:IsReferenceParameter="true" xmlns:qman-wsa="http://amqp.apache.org/qpid/management/qman/addressing">282f28e6-4396-4000-a19d-87a03978e8a0</qman-wsa:ResourceId>
+ </soap:Header>
+ <soap:Body>
+ <wsnt:ResumeSubscription xmlns:wsnt="http://docs.oasis-open.org/wsn/b-2"/>
+ </soap:Body>
+</soap:Envelope>
+
+[CLIENT TRACE] SOAP envelope contents (incoming):
+
+<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope">
+ <soap:Header>
+ <wsa:To xmlns:wsa="http://www.w3.org/2005/08/addressing">http://www.w3.org/2005/08/addressing/role/anonymous</wsa:To>
+ <wsa:Action xmlns:wsa="http://www.w3.org/2005/08/addressing">http://docs.oasis-open.org/wsn/bw-2/SubscriptionManager/ResumeSubscriptionResponse</wsa:Action>
+ <wsa:MessageID xmlns:wsa="http://www.w3.org/2005/08/addressing">uuid:aab4cf18-3cc0-30c4-7036-009e26bb3213</wsa:MessageID>
+ <wsa:RelatesTo RelationshipType="wsa:Reply" xmlns:wsa="http://www.w3.org/2005/08/addressing">uuid:bfb48615-905a-e472-a9ca-5483fa592f60</wsa:RelatesTo>
+ <wsa:From xmlns:wsa="http://www.w3.org/2005/08/addressing">
+ <wsa:Address>http://romagazzarini:8080/qman/services/SubscriptionManager</wsa:Address>
+ <wsa:ReferenceParameters>
+ <qman-wsa:ResourceId wsa:IsReferenceParameter="true"
+ xmlns:qman-wsa="http://amqp.apache.org/qpid/management/qman/addressing" xmlns:wsa="http://www.w3.org/2005/08/addressing">282f28e6-4396-4000-a19d-87a03978e8a0</qman-wsa:ResourceId>
+ </wsa:ReferenceParameters>
+ </wsa:From>
+ </soap:Header>
+ <soap:Body>
+ <muse-op:ResumeSubscriptionResponse xmlns:muse-op="http://docs.oasis-open.org/wsn/b-2"/>
+ </soap:Body>
+</soap:Envelope>
+
diff --git a/qpid/java/management/client/src/example/org/apache/qpid/management/example/ConsumerAndProducerExample.java b/qpid/java/management/client/src/example/org/apache/qpid/management/example/ConsumerAndProducerExample.java
index 93e78707e9..42587d78ff 100644
--- a/qpid/java/management/client/src/example/org/apache/qpid/management/example/ConsumerAndProducerExample.java
+++ b/qpid/java/management/client/src/example/org/apache/qpid/management/example/ConsumerAndProducerExample.java
@@ -26,7 +26,9 @@ import java.util.Date;
import org.apache.muse.util.xml.XPathUtils;
import org.apache.muse.ws.addressing.EndpointReference;
import org.apache.muse.ws.addressing.soap.SoapFault;
+import org.apache.muse.ws.notification.impl.FilterCollection;
import org.apache.muse.ws.notification.impl.MessagePatternFilter;
+import org.apache.muse.ws.notification.impl.ProducerPropertiesFilter;
import org.apache.muse.ws.notification.impl.TopicFilter;
import org.apache.muse.ws.notification.remote.NotificationProducerClient;
import org.apache.qpid.management.Names;
@@ -65,11 +67,11 @@ public class ConsumerAndProducerExample extends AbstractQManExample
void executeExample(String host, int port) throws Exception
{
// This is QMan...
- URI producerURI = URI.create("http://"+host+":"+port+"/qman/services/consumer");
+ URI producerURI = URI.create("http://"+host+":"+port+"/qman/services/adapter");
// ...and this is QMan too! Note that it has an hidden consumer capability that is used in
// order to run successfully this example...
- URI consumerURI = producerURI;
+ URI consumerURI = URI.create("http://"+host+":"+port+"/qman/services/consumer");
EndpointReference producerEPR = new EndpointReference(producerURI);
EndpointReference consumerEPR = new EndpointReference(consumerURI);
@@ -93,8 +95,11 @@ public class ConsumerAndProducerExample extends AbstractQManExample
// Example 6: a MessageFilter is installed in order to listen only for connection events
// (connections created or removed). The subscription will expire in 10 seconds.
allMessagesWithMessageFilterAndTerminationTime(producerEPR,consumerEPR);
+
+ // Example 7 : a subscription with more than one filter.
+ complexSubscription(producerEPR, consumerEPR);
}
-
+
/**
* Makes a subscription on all topics / all messages without an expiry date.
*
@@ -223,6 +228,41 @@ public class ConsumerAndProducerExample extends AbstractQManExample
new Date(System.currentTimeMillis() + 10000)); // Termination Time
}
+ /**
+ * Makes a subscription on a specifc topic with an expiry date.
+ * Only messages published on the given topic will be delivered to the given consumer.
+ * The subscription will end after 10 seconds
+ *
+ * @param producer the producer endpoint reference.
+ * @param consumer the consumer endpoint reference .
+ * @throws SoapFault when the subscription cannot be made.
+ */
+ private void complexSubscription(EndpointReference producer, EndpointReference consumer) throws SoapFault
+ {
+ NotificationProducerClient producerClient = new NotificationProducerClient(producer);
+ producerClient.setTrace(true);
+
+ FilterCollection filter = new FilterCollection();
+
+ TopicFilter topicFilter = new TopicFilter(Names.EVENTS_LIFECYLE_TOPIC_NAME);
+ MessagePatternFilter messageFilter= new MessagePatternFilter(
+ "/wsnt:NotificationMessage/wsnt:Message/qman:LifeCycleEvent/qman:Resource/qman:Name/text()='connection'", // expression (XPath)
+ XPathUtils.NAMESPACE_URI); // Dialect : the only supported dialect is XPath 1.0
+
+ ProducerPropertiesFilter producerFilter = new ProducerPropertiesFilter(
+ "boolean(/*/MgtPubInterval > 100 and /*/MsgTotalEnqueues > 56272)",
+ XPathUtils.NAMESPACE_URI);
+
+ filter.addFilter(topicFilter);
+ filter.addFilter(messageFilter);
+ filter.addFilter(producerFilter);
+
+ producerClient.subscribe(
+ consumer, // Consumer Endpoint reference
+ filter, // Topic Filter
+ new Date(System.currentTimeMillis() + 10000)); // Termination Time
+ }
+
@Override
void printOutExampleDescription()
{
@@ -245,4 +285,9 @@ public class ConsumerAndProducerExample extends AbstractQManExample
System.out.println("A subscription with a termination time will have a predefined expiry");
System.out.println("date while if there's no termination the subscription will never expire.");
}
+
+ public static void main(String[] args)
+ {
+ new ConsumerAndProducerExample().execute(new String[]{"localhost","8080"});
+ }
}
diff --git a/qpid/java/management/client/src/example/org/apache/qpid/management/example/PausableSubscriptionExample.java b/qpid/java/management/client/src/example/org/apache/qpid/management/example/PausableSubscriptionExample.java
new file mode 100644
index 0000000000..01a27a16f9
--- /dev/null
+++ b/qpid/java/management/client/src/example/org/apache/qpid/management/example/PausableSubscriptionExample.java
@@ -0,0 +1,88 @@
+/*
+ *
+ * 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.management.example;
+
+import java.net.URI;
+
+import org.apache.muse.ws.addressing.EndpointReference;
+import org.apache.muse.ws.notification.remote.NotificationProducerClient;
+import org.apache.muse.ws.notification.remote.SubscriptionClient;
+
+/**
+ * This example is demonstrating a WS-Notification scenario
+ * when (for simplicity) QMan is at the same time consumer
+ * and producer.
+ *
+ * Specifically the example shows how a requestor can create, pause and resume
+ * a subscription.
+ *
+ * @author Andrea Gazzarini
+ *
+ */
+public class PausableSubscriptionExample extends AbstractQManExample
+{
+ @Override
+ void executeExample(String host, int port) throws Exception
+ {
+ // This is QMan...
+ URI producerURI = URI.create("http://"+host+":"+port+"/qman/services/adapter");
+
+ // ...and this is QMan too! Note that it has an hidden consumer capability that is used in
+ // order to run successfully this example...
+ URI consumerURI = URI.create("http://"+host+":"+port+"/qman/services/consumer");
+
+ EndpointReference producerEPR = new EndpointReference(producerURI);
+ EndpointReference consumerEPR = new EndpointReference(consumerURI);
+
+ NotificationProducerClient producerClient = new NotificationProducerClient(producerEPR);
+ producerClient.setTrace(true);
+
+ // 1) Creates a subscription and gets the corresponding reference.
+ SubscriptionClient subscriptionClient = producerClient.subscribe(
+ consumerEPR, // Consumer Endpoint reference
+ null, // Filter, if null that means "all messages"
+ null); // Termination Time : if null the subscription will never expire.
+ subscriptionClient.setTrace(true);
+
+
+ // 2) Pauses the subscription.
+ subscriptionClient.pauseSubscription();
+
+ // 3) Resumes the subscription.
+ subscriptionClient.resumeSubscription();
+ }
+
+ @Override
+ void printOutExampleDescription()
+ {
+ System.out.println("This example is demonstrating a WS-Notification scenario ");
+ System.out.println("when (for simplicity) QMan is at the same time consumer ");
+ System.out.println("and producer.");
+ System.out.println();
+ System.out.println("Specifically the example shows how a requestor can create,");
+ System.out.println("pause and resume a subscription.");
+ }
+
+ public static void main(String[] args)
+ {
+ new PausableSubscriptionExample().execute(new String[]{"romagazzarini","8080"});
+ }
+}
diff --git a/qpid/java/management/client/src/main/java/muse.xml b/qpid/java/management/client/src/main/java/muse.xml
index d2f499cef9..cf651c34ac 100644
--- a/qpid/java/management/client/src/main/java/muse.xml
+++ b/qpid/java/management/client/src/main/java/muse.xml
@@ -29,7 +29,7 @@
<java-serializer-class>org.apache.qpid.management.wsdm.muse.serializer.DateSerializer</java-serializer-class>
</custom-serializer>
<router>
- <java-router-class>org.apache.muse.core.routing.SimpleResourceRouter</java-router-class>
+ <java-router-class>org.apache.muse.ws.resource.impl.WsResourceRouter</java-router-class>
<logging>
<log-file>log/muse.log</log-file>
<log-level>SEVERE</log-level>
diff --git a/qpid/java/management/client/src/main/java/org/apache/qpid/management/Messages.java b/qpid/java/management/client/src/main/java/org/apache/qpid/management/Messages.java
index 3d208835f0..4f84128fb3 100644
--- a/qpid/java/management/client/src/main/java/org/apache/qpid/management/Messages.java
+++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/Messages.java
@@ -170,6 +170,6 @@ public interface Messages
String QMAN_100037_INVOKE_OPERATION_FAILURE = "<QMAN-100037> : Operation Invocation failure for operation.";
String QMAN_100038_UNABLE_TO_SEND_WS_NOTIFICATION = "<QMAN-100038> : Unable to send notification.";
String QMAN_100039_UNABLE_TO_CONFIGURE_PROPERLY_WORKER_MANAGER = "<QMAN-100039> : Unable to properly configure WorkManager. A malformed property (NaN) was given as input parameter.";
-
+ String QMAN_100040_UNABLE_TO_LOCATE_WSRP_PROPERTIES = "<QMAN-100040> : Unable to evaluate the WSRP XPath expression on resource WSDL.";
} \ No newline at end of file
diff --git a/qpid/java/management/client/src/main/java/org/apache/qpid/management/Names.java b/qpid/java/management/client/src/main/java/org/apache/qpid/management/Names.java
index 808cafb6a7..d3ce711d5d 100644
--- a/qpid/java/management/client/src/main/java/org/apache/qpid/management/Names.java
+++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/Names.java
@@ -45,7 +45,7 @@ public abstract class Names
public static String CLASS = "class";
public static String EVENT = "event";
public static String OBJECT_ID="objectId";
- public static String BROKER_ID = "brokerID";
+ public static String BROKER_ID = "brokerId";
public static String DOMAIN_NAME = "Q-MAN";
public static String ARG_COUNT_PARAM_NAME = "argCount";
@@ -86,7 +86,7 @@ public abstract class Names
new StringBuilder()
.append(DOMAIN_NAME)
.append(':')
- .append("Type=Service")
+ .append("Name=QMan,Type=Service")
.toString());
} catch(Exception exception)
{
diff --git a/qpid/java/management/client/src/main/java/org/apache/qpid/management/configuration/AccessModeMapping.java b/qpid/java/management/client/src/main/java/org/apache/qpid/management/configuration/AccessModeMapping.java
deleted file mode 100644
index af6aaa36bf..0000000000
--- a/qpid/java/management/client/src/main/java/org/apache/qpid/management/configuration/AccessModeMapping.java
+++ /dev/null
@@ -1,83 +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.management.configuration;
-
-import org.apache.qpid.management.domain.model.AccessMode;
-
-/**
- * Class used to encapsulate a mapping between an access mode and a code.
- *
- * @author Andrea Gazzarini
- */
-class AccessModeMapping
-{
- private final int _code;
- private final AccessMode _accessMode;
-
- /**
- * Builds a new access mode mapping with the given parameters.
- *
- * @param code the access code.
- * @param accessMode the access mode.
- */
- AccessModeMapping(int code, AccessMode accessMode)
- {
- this._code = code;
- this._accessMode = accessMode;
- }
-
- /**
- * Returns the access mode of this mapping.
- *
- * @return the access mode of this mapping.
- */
- AccessMode getAccessMode ()
- {
- return _accessMode;
- }
-
- /**
- * Returns the code of this mapping.
- *
- * @return the code of this mapping.
- */
- int getCode ()
- {
- return _code;
- }
-
- /**
- * Returns a string representation of this mapping.
- * The returned string is indicating the code and the corresponding access mode.
- *
- * @return a string representation of this mapping.
- */
- @Override
- public String toString ()
- {
- return new StringBuilder()
- .append("AccessMode mapping (")
- .append(_code)
- .append(',')
- .append(_accessMode)
- .append(')').toString();
- }
-}
diff --git a/qpid/java/management/client/src/main/java/org/apache/qpid/management/configuration/Configuration.java b/qpid/java/management/client/src/main/java/org/apache/qpid/management/configuration/Configuration.java
index c9d45c5023..51dc62f4fa 100644
--- a/qpid/java/management/client/src/main/java/org/apache/qpid/management/configuration/Configuration.java
+++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/configuration/Configuration.java
@@ -30,7 +30,16 @@ import org.apache.qpid.management.Messages;
import org.apache.qpid.management.Names;
import org.apache.qpid.management.domain.handler.base.IMessageHandler;
import org.apache.qpid.management.domain.model.AccessMode;
+import org.apache.qpid.management.domain.model.type.AbsTime;
+import org.apache.qpid.management.domain.model.type.DeltaTime;
+import org.apache.qpid.management.domain.model.type.ObjectReference;
+import org.apache.qpid.management.domain.model.type.Str16;
+import org.apache.qpid.management.domain.model.type.Str8;
import org.apache.qpid.management.domain.model.type.Type;
+import org.apache.qpid.management.domain.model.type.Uint16;
+import org.apache.qpid.management.domain.model.type.Uint32;
+import org.apache.qpid.management.domain.model.type.Uint64;
+import org.apache.qpid.management.domain.model.type.Uint8;
import org.apache.qpid.transport.DeliveryProperties;
import org.apache.qpid.transport.Header;
import org.apache.qpid.transport.MessageProperties;
@@ -71,7 +80,12 @@ public final class Configuration
private Configuration()
{
defineQueueNames();
+
createHeaderForCommandMessages();
+
+ addAccessModeMappings();
+
+ addTypeMappings();
}
void clean()
@@ -90,9 +104,11 @@ public final class Configuration
}
/**
- * Returns true if this configuration has at least one broker connection data.
+ * Returns true if this configuration has at least
+ * one broker configured.
*
- * @return true if this configuration has at least one broker connection data.
+ * @return true if this configuration has at least one
+ * broker configured.
*/
public boolean hasOneOrMoreBrokersDefined()
{
@@ -245,26 +261,46 @@ public final class Configuration
/**
* Adds a new type mapping to this configuration.
*
- * @param mapping the type mapping that will be added.
+ * @param code the code that will be associated with the declared type.
+ * @param type the type.
+ * @param vailidatorClassName the FQN of the validator class that will be
+ * associated with the given type.
*/
- void addTypeMapping(TypeMapping mapping) {
- int code = mapping.getCode();
- Type type = mapping.getType();
- String validatorClassName = mapping.getValidatorClassName();
- _typeMappings.put(code, type);
+ void addTypeMapping(int code, Type type, String validatorClassName) {
+ _typeMappings.put(code, type);
_validators.put(type, validatorClassName);
- LOGGER.info(Messages.QMAN_000005_TYPE_MAPPING_CONFIGURED, code,type,validatorClassName);
+ LOGGER.info(
+ Messages.QMAN_000005_TYPE_MAPPING_CONFIGURED,
+ code,
+ type,
+ validatorClassName);
}
-
+
+
+ /**
+ * Adds a new type mapping to this configuration.
+ *
+ * @param code the code that will be associated with the declared type.
+ * @param type the type.
+ */
+ void addTypeMapping(int code, Type type) {
+ _typeMappings.put(code, type);
+
+ LOGGER.info(
+ Messages.QMAN_000005_TYPE_MAPPING_CONFIGURED,
+ code,
+ type,
+ "not configured for this type.");
+ }
+
/**
* Adds a new access mode mapping to this configuration.
*
- * @param mapping the mapping that will be added.
+ * @param code the code that will be associated with the access mode,
+ * @param accessMode the accessMode.
*/
- void addAccessModeMapping(AccessModeMapping mapping){
- int code = mapping.getCode();
- AccessMode accessMode = mapping.getAccessMode();
+ void addAccessModeMapping(int code, AccessMode accessMode){
_accessModes.put(code, accessMode);
LOGGER.info(Messages.QMAN_000006_ACCESS_MODE_MAPPING_CONFIGURED, code,accessMode);
@@ -420,4 +456,34 @@ public final class Configuration
{
this._keepAliveTime = keepAliveTime;
}
+
+ /**
+ * Configures access mode mappings.
+ * An access mode mapping is an association between a code and an access mode.
+ */
+ private void addAccessModeMappings() {
+ addAccessModeMapping(1,AccessMode.RC);
+ addAccessModeMapping(2,AccessMode.RW);
+ addAccessModeMapping(3,AccessMode.RO);
+ }
+
+ /**
+ * Configures type mappings.
+ * A type mapping is an association between a code and a management type.
+ */
+ private void addTypeMappings()
+ {
+ addTypeMapping(1,new Uint8(),Names.NUMBER_VALIDATOR);
+ addTypeMapping(2,new Uint16(),Names.NUMBER_VALIDATOR);
+ addTypeMapping(3,new Uint32(),Names.NUMBER_VALIDATOR);
+ addTypeMapping(4,new Uint64(),Names.NUMBER_VALIDATOR);
+ addTypeMapping(6,new Str8(),Names.STRING_VALIDATOR);
+ addTypeMapping(7,new Str16(),Names.STRING_VALIDATOR);
+ addTypeMapping(8,new AbsTime());
+ addTypeMapping(9,new DeltaTime());
+ addTypeMapping(10,new ObjectReference());
+ addTypeMapping(11,new org.apache.qpid.management.domain.model.type.Boolean());
+ addTypeMapping(14,new org.apache.qpid.management.domain.model.type.Uuid());
+ addTypeMapping(15,new org.apache.qpid.management.domain.model.type.Map());
+ }
} \ No newline at end of file
diff --git a/qpid/java/management/client/src/main/java/org/apache/qpid/management/configuration/Configurator.java b/qpid/java/management/client/src/main/java/org/apache/qpid/management/configuration/Configurator.java
index 1cde9d5f88..fe44c6aff7 100644
--- a/qpid/java/management/client/src/main/java/org/apache/qpid/management/configuration/Configurator.java
+++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/configuration/Configurator.java
@@ -38,16 +38,6 @@ import org.apache.qpid.management.domain.handler.impl.HeartBeatIndicationMessage
import org.apache.qpid.management.domain.handler.impl.InstrumentationMessageHandler;
import org.apache.qpid.management.domain.handler.impl.MethodResponseMessageHandler;
import org.apache.qpid.management.domain.handler.impl.SchemaResponseMessageHandler;
-import org.apache.qpid.management.domain.model.AccessMode;
-import org.apache.qpid.management.domain.model.type.AbsTime;
-import org.apache.qpid.management.domain.model.type.DeltaTime;
-import org.apache.qpid.management.domain.model.type.ObjectReference;
-import org.apache.qpid.management.domain.model.type.Str16;
-import org.apache.qpid.management.domain.model.type.Str8;
-import org.apache.qpid.management.domain.model.type.Uint16;
-import org.apache.qpid.management.domain.model.type.Uint32;
-import org.apache.qpid.management.domain.model.type.Uint64;
-import org.apache.qpid.management.domain.model.type.Uint8;
import org.apache.qpid.transport.util.Logger;
import org.xml.sax.Attributes;
import org.xml.sax.InputSource;
@@ -148,9 +138,6 @@ public class Configurator extends DefaultHandler
}
}
- addTypeMappings();
- addAccessModeMappings();
-
addMandatoryManagementMessageHandlers();
addMandatoryMethodReplyMessageHandlers();
} catch (Exception exception)
@@ -209,38 +196,6 @@ public class Configurator extends DefaultHandler
return data;
}
- /**
- * Configures access mode mappings.
- * An access mode mapping is an association between a code and an access mode.
- */
- private void addAccessModeMappings() {
- Configuration configuration = Configuration.getInstance();
- configuration.addAccessModeMapping(new AccessModeMapping(1,AccessMode.RC));
- configuration.addAccessModeMapping(new AccessModeMapping(2,AccessMode.RW));
- configuration.addAccessModeMapping(new AccessModeMapping(3,AccessMode.RO));
- }
-
- /**
- * Configures type mappings.
- * A type mapping is an association between a code and a management type.
- */
- private void addTypeMappings()
- {
- Configuration configuration = Configuration.getInstance();
- configuration.addTypeMapping(new TypeMapping(1,new Uint8(),Names.NUMBER_VALIDATOR));
- configuration.addTypeMapping(new TypeMapping(2,new Uint16(),Names.NUMBER_VALIDATOR));
- configuration.addTypeMapping(new TypeMapping(3,new Uint32(),Names.NUMBER_VALIDATOR));
- configuration.addTypeMapping(new TypeMapping(4,new Uint64(),Names.NUMBER_VALIDATOR));
- configuration.addTypeMapping(new TypeMapping(6,new Str8(),Names.STRING_VALIDATOR));
- configuration.addTypeMapping(new TypeMapping(7,new Str16(),Names.STRING_VALIDATOR));
- configuration.addTypeMapping(new TypeMapping(8,new AbsTime()));
- configuration.addTypeMapping(new TypeMapping(9,new DeltaTime()));
- configuration.addTypeMapping(new TypeMapping(10,new ObjectReference()));
- configuration.addTypeMapping(new TypeMapping(11,new org.apache.qpid.management.domain.model.type.Boolean()));
- configuration.addTypeMapping(new TypeMapping(14,new org.apache.qpid.management.domain.model.type.Uuid()));
- configuration.addTypeMapping(new TypeMapping(15,new org.apache.qpid.management.domain.model.type.Map()));
- }
-
/**
* Configures the mandatory management message handlers.
*/
diff --git a/qpid/java/management/client/src/main/java/org/apache/qpid/management/configuration/TypeMapping.java b/qpid/java/management/client/src/main/java/org/apache/qpid/management/configuration/TypeMapping.java
deleted file mode 100644
index 2c0a460c1a..0000000000
--- a/qpid/java/management/client/src/main/java/org/apache/qpid/management/configuration/TypeMapping.java
+++ /dev/null
@@ -1,90 +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.management.configuration;
-
-import org.apache.qpid.management.domain.model.type.Type;
-
-/**
- * Type Mapping used for associating a code with a management type.
- *
- * @author Andrea Gazzarini
- */
-class TypeMapping
-{
- private final int _code;
- private final Type _type;
- private final String _validatorClass;
-
- /**
- * Builds a new type mapping with the given parameters and no validator.
- *
- * @param code the code.
- * @param type the management type.
- */
- TypeMapping(int code, Type type)
- {
- this(code,type,null);
- }
-
- /**
- * Builds a new type mapping with the given parameters.
- *
- * @param code the code.
- * @param type the management type.
- * @param validatorClassName the class name of the validator to be used.
- */
- TypeMapping(int code, Type type, String validatorClassName)
- {
- this._code = code;
- this._type = type;
- this._validatorClass = validatorClassName;
- }
-
- /**
- * Returns the code of this mapping.
- *
- * @return the code of this mapping.
- */
- int getCode ()
- {
- return _code;
- }
-
- /**
- * Returns the type for this mapping.
- *
- * @return the type for this mapping.
- */
- Type getType ()
- {
- return _type;
- }
-
- /**
- * Returns the validator class of this mapping.
- *
- * @return the validator class (as a string) of this mapping.
- */
- public String getValidatorClassName()
- {
- return _validatorClass;
- }
-}
diff --git a/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/JmxService.java b/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/JmxService.java
index 176cec451e..657d7e6210 100644
--- a/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/JmxService.java
+++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/JmxService.java
@@ -54,11 +54,10 @@ public class JmxService
*/
public void registerQManService(QMan qman) throws MBeanException
{
- ObjectName name = createQManName();
- if (!_mxServer.isRegistered(name))
+ if (!_mxServer.isRegistered(Names.QMAN_OBJECT_NAME))
{
try {
- _mxServer.registerMBean(qman, name);
+ _mxServer.registerMBean(qman, Names.QMAN_OBJECT_NAME);
} catch (Exception exception) {
throw new MBeanException(exception);
}
@@ -358,27 +357,6 @@ public class JmxService
throw new RuntimeException(exception);
}
}
-
- /**
- * Creates the QMan object name.
- *
- * @return the QMan object name.
- */
- private ObjectName createQManName()
- {
- String asString = new StringBuilder()
- .append(Names.DOMAIN_NAME)
- .append(':')
- .append("Type=Service")
- .toString();
- try
- {
- return new ObjectName(asString);
- } catch (MalformedObjectNameException exception)
- {
- throw new RuntimeException(exception);
- }
- }
ObjectName createEntityDefinitionName(String packageName, String className, String type)
{
@@ -407,7 +385,7 @@ public class JmxService
{
if (!_mxServer.isRegistered(name))
_mxServer.registerMBean(entity, name);
- _mxServer.addNotificationListener(name, createQManName(), null, null);
+ _mxServer.addNotificationListener(name, Names.QMAN_OBJECT_NAME, null, null);
} catch(Exception exception)
{
throw new RuntimeException(exception);
diff --git a/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/services/QMan.java b/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/services/QMan.java
index d124593472..c4c0ce5e74 100644
--- a/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/services/QMan.java
+++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/services/QMan.java
@@ -26,6 +26,9 @@ import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
+import java.util.concurrent.ArrayBlockingQueue;
+import java.util.concurrent.ThreadPoolExecutor;
+import java.util.concurrent.TimeUnit;
import javax.management.Attribute;
import javax.management.AttributeList;
@@ -45,6 +48,7 @@ import org.apache.qpid.management.Names;
import org.apache.qpid.management.configuration.BrokerAlreadyConnectedException;
import org.apache.qpid.management.configuration.BrokerConnectionData;
import org.apache.qpid.management.configuration.BrokerConnectionException;
+import org.apache.qpid.management.configuration.Configuration;
import org.apache.qpid.management.configuration.Configurator;
import org.apache.qpid.management.domain.model.JmxService;
import org.apache.qpid.transport.util.Logger;
@@ -58,6 +62,7 @@ public class QMan extends NotificationBroadcasterSupport implements DynamicMBean
private final List<ManagementClient> managementClients = new ArrayList<ManagementClient>();
private Configurator _configurator = new Configurator();
+ private ThreadPoolExecutor _workManager;
/**
* Starts QMan.
@@ -74,6 +79,8 @@ public class QMan extends NotificationBroadcasterSupport implements DynamicMBean
_configurator.configure();
+ configureWorkManager();
+
LOGGER.info(Messages.QMAN_000019_QMAN_STARTED);
} catch(Exception exception) {
LOGGER.error(exception,Messages.QMAN_100018_UNABLE_TO_STARTUP_CORRECTLY );
@@ -143,6 +150,36 @@ public class QMan extends NotificationBroadcasterSupport implements DynamicMBean
LOGGER.info(Messages.QMAN_000021_SHUT_DOWN);
}
+ /**
+ * Creates a management client using the given data.
+ *
+ * @param brokerId the broker identifier.
+ * @param data the broker connection data.
+ */
+ public void createManagementClient(UUID brokerId, BrokerConnectionData data)
+ {
+ try
+ {
+ ManagementClient client = new ManagementClient(brokerId,data);
+ client.estabilishFirstConnectionWithBroker();
+ managementClients.add(client);
+
+ LOGGER.info(Messages.QMAN_000004_MANAGEMENT_CLIENT_CONNECTED,brokerId);
+ } catch(StartupFailureException exception) {
+ LOGGER.error(exception, Messages.QMAN_100017_UNABLE_TO_CONNECT,brokerId,data);
+ }
+ }
+
+ /**
+ * Returns the list of management clients currently handled by QMan.
+ *
+ * @return the list of management clients currently handled by QMan.
+ */
+ public List<ManagementClient> getManagementClients()
+ {
+ return managementClients;
+ }
+
/**
* Injects the configurator on this QMan instance.
* That configutator later will be responsible to manage the configuration.
@@ -330,13 +367,20 @@ public class QMan extends NotificationBroadcasterSupport implements DynamicMBean
/**
* Simply dispatches the incoming notification to registered listeners.
+ * Consider that the notification is sent asynchronously so the QMan current thread is not
+ * waiting for completion of receiver task.
*
* @param notification the incoming notification.
* @param handback the context associated to this notification.
*/
- public void handleNotification(Notification notification, Object handback)
+ public void handleNotification(final Notification notification, Object handback)
{
- sendNotification(notification);
+ _workManager.execute(new Runnable(){
+ public void run()
+ {
+ sendNotification(notification);
+ }
+ });
}
/**
@@ -352,33 +396,17 @@ public class QMan extends NotificationBroadcasterSupport implements DynamicMBean
LOGGER.info(Messages.QMAN_000023_QMAN_REGISTERED_AS_MBEAN);
}
- /**
- * Creates a management client using the given data.
- *
- * @param brokerId the broker identifier.
- * @param data the broker connection data.
- */
- public void createManagementClient(UUID brokerId, BrokerConnectionData data)
- {
- try
- {
- ManagementClient client = new ManagementClient(brokerId,data);
- client.estabilishFirstConnectionWithBroker();
- managementClients.add(client);
-
- LOGGER.info(Messages.QMAN_000004_MANAGEMENT_CLIENT_CONNECTED,brokerId);
- } catch(StartupFailureException exception) {
- LOGGER.error(exception, Messages.QMAN_100017_UNABLE_TO_CONNECT,brokerId,data);
- }
- }
-
/**
- * Returns the list of management clients currently handled by QMan.
- *
- * @return the list of management clients currently handled by QMan.
+ * Configures work manager component.
*/
- public List<ManagementClient> getManagementClients()
- {
- return managementClients;
- }
+ private void configureWorkManager()
+ {
+ Configuration configuration = Configuration.getInstance();
+ _workManager = new ThreadPoolExecutor(
+ configuration.getWorkerManagerPoolSize(),
+ configuration.getWorkerManagerMaxPoolSize(),
+ configuration.getWorkerManagerKeepAliveTime(),
+ TimeUnit.MILLISECONDS,
+ new ArrayBlockingQueue<Runnable>(30));
+ }
}
diff --git a/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/services/QpidService.java b/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/services/QpidService.java
index a12993d40e..ee41beaf50 100644
--- a/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/services/QpidService.java
+++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/services/QpidService.java
@@ -86,6 +86,8 @@ public class QpidService implements SessionListener
public void opened(Session ssn) {}
+ public void resumed(Session ssn) {}
+
public void message(Session ssn, MessageTransfer xfr)
{
MessagePartListenerAdapter l = _listeners.get(xfr.getDestination());
diff --git a/qpid/java/management/client/src/main/java/org/apache/qpid/management/web/action/BrokerModel.java b/qpid/java/management/client/src/main/java/org/apache/qpid/management/web/action/BrokerModel.java
index 03e772b9b1..09b7309b96 100644
--- a/qpid/java/management/client/src/main/java/org/apache/qpid/management/web/action/BrokerModel.java
+++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/web/action/BrokerModel.java
@@ -30,12 +30,21 @@ import javax.management.ObjectName;
import org.apache.qpid.management.Names;
+/**
+ * Value Object encapsulating a broker management domain model.
+ *
+ * @author Andrea Gazzarini
+ */
public class BrokerModel
{
- private Map<String, List<ObjectName>> objectsByType = new HashMap<String, List<ObjectName>>();
-
- private String id;
+ private Map<String, List<ObjectName>> _objectsByType = new HashMap<String, List<ObjectName>>();
+ private String _id;
+ /**
+ * Adds a new object to this domain model.
+ *
+ * @param name the object name of the JMX entity.
+ */
void addObject(ObjectName name)
{
String packageName = name.getKeyProperty(Names.PACKAGE);
@@ -44,37 +53,48 @@ public class BrokerModel
{
String fqn = packageName+"."+className;
- List<ObjectName> objects = objectsByType.get(fqn);
+ List<ObjectName> objects = _objectsByType.get(fqn);
if (objects == null)
{
objects = new ArrayList<ObjectName>();
- objectsByType.put(fqn,objects);
+ _objectsByType.put(fqn,objects);
}
objects.add(name);
}
}
+ /**
+ * Gets the identifier of the owner of this model.
+ *
+ * @return the identifier of the owner of this model.
+ */
public String getId()
{
- return id;
+ return _id;
}
+ /**
+ * Sets the identifier of the owner of this model.
+ *
+ * @param id the identifier of the owner of this model.
+ */
public void setId(String id)
{
- this.id = id;
+ this._id = id;
}
- public Set<String> getCategoryNames(){
- return objectsByType.keySet();
+ public Set<String> getCategoryNames()
+ {
+ return _objectsByType.keySet();
}
public List<ObjectName> getCategory(String name)
{
- return objectsByType.get(name);
+ return _objectsByType.get(name);
}
public int getCategoryCount()
{
- return objectsByType.keySet().size();
+ return _objectsByType.keySet().size();
}
} \ No newline at end of file
diff --git a/qpid/java/management/client/src/main/java/org/apache/qpid/management/web/action/BrokersManagementAction.java b/qpid/java/management/client/src/main/java/org/apache/qpid/management/web/action/BrokersManagementAction.java
index ae886767e2..509c86c08b 100644
--- a/qpid/java/management/client/src/main/java/org/apache/qpid/management/web/action/BrokersManagementAction.java
+++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/web/action/BrokersManagementAction.java
@@ -42,9 +42,10 @@ import org.apache.qpid.management.domain.services.QMan;
* This controller is responsible to :
*
* <ul>
- * <li> prepare data for the page that is showing all connected brokers.</li>.
- * </li> connect QMan with a broker on demand.
+ * <li> prepare data for the page that is showing all connected brokers.</li>.
+ * </li> connect QMan with a broker on demand.
* </ul>
+ *
* @author Andrea Gazzarini
*/
public class BrokersManagementAction extends HttpServlet
@@ -54,6 +55,11 @@ public class BrokersManagementAction extends HttpServlet
/**
* Retrieves all connected brokers (their connection data) and prepare the model that
* is then forwarded to the appropriate view page.
+ *
+ * @param request the http request.
+ * @param response the http response.
+ * @throws ServletException in case of failure while forwarding to the view component.
+ * @throws IOException in case of failure while forwarding to the view component.
*/
@SuppressWarnings("unchecked")
@Override
@@ -87,7 +93,13 @@ public class BrokersManagementAction extends HttpServlet
}
/**
- * Connects QMan with a new broker.
+ * Connects QMan with a new broker and forwards to
+ * the brokers list view page.
+ *
+ * @param request the http request.
+ * @param response the http response.
+ * @throws ServletException in case of failure while forwarding to the view component.
+ * @throws IOException in case of failure while forwarding to the view component.
*/
@SuppressWarnings("unchecked")
@Override
@@ -123,28 +135,32 @@ public class BrokersManagementAction extends HttpServlet
errors.add("Invalid value for \"virtualHost\" attribute. Must be not null.");
}
- try{
+ try
+ {
port = Integer.parseInt(portString);
} catch(Exception exception)
{
errors.add("Invalid value for \"port\" attribute. Must be not null and must be a number.");
}
- try{
+ try
+ {
initialPoolCapacity = Integer.parseInt(initialCapacityString);
} catch(Exception exception)
{
errors.add("Invalid value for \"Initial Pool Capacity\" attribute. Must be not null and must be a number.");
}
- try{
+ try
+ {
maxPoolCapacity = Integer.parseInt(maxCapacityString);
} catch(Exception exception)
{
errors.add("Invalid value for \"Max Pool Capacity\" attribute. Must be not null and must be a number.");
}
- try{
+ try
+ {
maxWaitTimeout = Long.parseLong(maxWaitTimeoutString);
} catch(Exception exception)
{
diff --git a/qpid/java/management/client/src/main/java/org/apache/qpid/management/web/action/WsdmPropertiesPerspectiveAction.java b/qpid/java/management/client/src/main/java/org/apache/qpid/management/web/action/WsdmPropertiesPerspectiveAction.java
index de479a00d6..e3a8eb50d7 100644
--- a/qpid/java/management/client/src/main/java/org/apache/qpid/management/web/action/WsdmPropertiesPerspectiveAction.java
+++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/web/action/WsdmPropertiesPerspectiveAction.java
@@ -43,15 +43,12 @@ import javax.xml.namespace.QName;
import org.apache.muse.core.proxy.ProxyHandler;
import org.apache.muse.core.proxy.ReflectionProxyHandler;
import org.apache.muse.ws.addressing.EndpointReference;
-import org.apache.muse.ws.resource.remote.WsResourceClient;
import org.apache.qpid.management.Names;
import org.w3c.dom.Element;
public class WsdmPropertiesPerspectiveAction extends HttpServlet
{
private static final long serialVersionUID = -2411413147821629363L;
- private static final Object [] WSDL_DIALECT = new Object[]{"http://schemas.xmlsoap.org/wsdl/"};
- private static final Object [] RMD_DIALECT = new Object[]{"http://docs.oasis-open.org/wsrf/rmd-1"};
private ProxyHandler proxyHandler;
diff --git a/qpid/java/management/client/src/main/java/org/apache/qpid/management/web/action/WsdmRmdPerspectiveAction.java b/qpid/java/management/client/src/main/java/org/apache/qpid/management/web/action/WsdmRmdPerspectiveAction.java
index bafdc06633..b4c488e97c 100644
--- a/qpid/java/management/client/src/main/java/org/apache/qpid/management/web/action/WsdmRmdPerspectiveAction.java
+++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/web/action/WsdmRmdPerspectiveAction.java
@@ -35,6 +35,8 @@ import org.apache.muse.core.proxy.ProxyHandler;
import org.apache.muse.core.proxy.ReflectionProxyHandler;
import org.apache.muse.util.xml.XmlUtils;
import org.apache.muse.ws.addressing.EndpointReference;
+import org.apache.muse.ws.metadata.WsxConstants;
+import org.apache.muse.ws.resource.metadata.WsrmdConstants;
import org.apache.muse.ws.resource.remote.WsResourceClient;
import org.apache.qpid.management.Names;
import org.w3c.dom.Element;
@@ -42,7 +44,7 @@ import org.w3c.dom.Element;
public class WsdmRmdPerspectiveAction extends HttpServlet
{
private static final long serialVersionUID = -2411413147821629363L;
- private static final Object [] DIALECT = new Object[]{"http://docs.oasis-open.org/wsrf/rmd-1"};
+ private static final Object [] RMD_DIALECT = new Object[]{WsrmdConstants.NAMESPACE_URI};
private ProxyHandler proxyHandler;
@@ -52,10 +54,14 @@ public class WsdmRmdPerspectiveAction extends HttpServlet
public void init() throws ServletException
{
proxyHandler = new ReflectionProxyHandler();
- proxyHandler.setAction("http://schemas.xmlsoap.org/ws/2004/09/mex/GetMetadata");
- proxyHandler.setRequestName(new QName("http://schemas.xmlsoap.org/ws/2004/09/mex", "GetMetadata", Names.PREFIX));
- proxyHandler.setRequestParameterNames(new QName[]{new QName("http://schemas.xmlsoap.org/ws/2004/09/mex", "Dialect", Names.PREFIX)});
- proxyHandler.setResponseName(new QName("http://schemas.xmlsoap.org/ws/2004/09/mex", "Metadata", Names.PREFIX));
+ proxyHandler.setAction(WsxConstants.GET_METADATA_URI);
+ proxyHandler.setRequestName(WsxConstants.GET_METADATA_QNAME);
+ proxyHandler.setRequestParameterNames(new QName[]{
+ new QName(
+ WsxConstants.NAMESPACE_URI,
+ WsxConstants.DIALECT,
+ WsxConstants.PREFIX)});
+ proxyHandler.setResponseName(WsxConstants.METADATA_QNAME);
proxyHandler.setReturnType(Element[].class);
}
@@ -65,29 +71,49 @@ public class WsdmRmdPerspectiveAction extends HttpServlet
{
try
{
-// String resourceId = request.getParameter("resourceId");
-// ObjectName objectName = new ObjectName(resourceId);
-//
-// String wsresourceid = objectName.getKeyProperty(Names.OBJECT_ID);
-// EndpointReference resourceEndpointReference = new EndpointReference(getURI(request));
-// resourceEndpointReference.addParameter(
-// Names.RESOURCE_ID_QNAME,
-// wsresourceid);
-//
-// WsResourceClient resourceClient = new WsResourceClient(resourceEndpointReference);
-// Element rmd = ((Element[])resourceClient.invoke(proxyHandler,DIALECT))[0];
-//
-// String output = XmlUtils.toString(rmd);
-//
-// String [] keyProperties = objectName.getKeyPropertyListString().split(",");
-//
-// request.setAttribute("resourceId", objectName);
-// request.setAttribute("nameAttributes",keyProperties);
-// request.setAttribute("rmd",output);
- RequestDispatcher dispatcher = request.getRequestDispatcher("/tbd.jsp");
+ String resourceId = request.getParameter("resourceId");
+ ObjectName objectName = new ObjectName(resourceId);
+
+ String wsresourceid = objectName.getKeyProperty(Names.OBJECT_ID);
+ EndpointReference resourceEndpointReference = new EndpointReference(getURI(request));
+
+ resourceEndpointReference.addParameter(
+ Names.RESOURCE_ID_QNAME,
+ wsresourceid);
+
+ WsResourceClient resourceClient = new WsResourceClient(resourceEndpointReference);
+ Element rmd = ((Element[])resourceClient.invoke(proxyHandler,RMD_DIALECT))[0];
+
+// NodeList nodelist = wsdl.getChildNodes();
+// Element definitions = null;
+// for (int i = 0; i < nodelist.getLength(); i++)
+// {
+// Node node = nodelist.item(i);
+// switch (node.getNodeType())
+// {
+// case Node.ELEMENT_NODE:
+// {
+// Element element = (Element) node;
+// if (element.getNodeName().indexOf("definitions") != -1)
+// {
+// definitions = element;
+// break;
+// }
+// }
+// }
+// }
+
+ String output = XmlUtils.toString(rmd);
+
+ String [] keyProperties = objectName.getKeyPropertyListString().split(",");
+
+ request.setAttribute("resourceId", resourceId);
+ request.setAttribute("nameAttributes",keyProperties);
+ request.setAttribute("rmd",output);
+ RequestDispatcher dispatcher = request.getRequestDispatcher("/wsdm_rmd_perspective.jsp");
dispatcher.forward(request,response);
} catch(Exception exception)
- {
+ {
request.setAttribute("errorMessage","Unable to detect the exact cause Please look at the reported stack trace below.");
request.setAttribute("exception",exception);
RequestDispatcher dispatcher = request.getRequestDispatcher("/error_page.jsp");
diff --git a/qpid/java/management/client/src/main/java/org/apache/qpid/management/web/action/WsdmWsdlPerspectiveAction.java b/qpid/java/management/client/src/main/java/org/apache/qpid/management/web/action/WsdmWsdlPerspectiveAction.java
index 9b47fe95b9..77a5237037 100644
--- a/qpid/java/management/client/src/main/java/org/apache/qpid/management/web/action/WsdmWsdlPerspectiveAction.java
+++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/web/action/WsdmWsdlPerspectiveAction.java
@@ -35,6 +35,7 @@ import org.apache.muse.core.proxy.ProxyHandler;
import org.apache.muse.core.proxy.ReflectionProxyHandler;
import org.apache.muse.util.xml.XmlUtils;
import org.apache.muse.ws.addressing.EndpointReference;
+import org.apache.muse.ws.metadata.WsxConstants;
import org.apache.muse.ws.resource.remote.WsResourceClient;
import org.apache.qpid.management.Names;
import org.w3c.dom.Element;
@@ -44,7 +45,7 @@ import org.w3c.dom.NodeList;
public class WsdmWsdlPerspectiveAction extends HttpServlet
{
private static final long serialVersionUID = -2411413147821629363L;
- private static final Object [] WSDL_DIALECT = new Object[]{"http://schemas.xmlsoap.org/wsdl/"};
+ private static final Object [] WSDL_DIALECT = new Object[]{WsxConstants.WSDL_DIALECT};
private ProxyHandler proxyHandler;
@@ -54,10 +55,14 @@ public class WsdmWsdlPerspectiveAction extends HttpServlet
public void init() throws ServletException
{
proxyHandler = new ReflectionProxyHandler();
- proxyHandler.setAction("http://schemas.xmlsoap.org/ws/2004/09/mex/GetMetadata");
- proxyHandler.setRequestName(new QName("http://schemas.xmlsoap.org/ws/2004/09/mex", "GetMetadata", Names.PREFIX));
- proxyHandler.setRequestParameterNames(new QName[]{new QName("http://schemas.xmlsoap.org/ws/2004/09/mex", "Dialect", Names.PREFIX)});
- proxyHandler.setResponseName(new QName("http://schemas.xmlsoap.org/ws/2004/09/mex", "Metadata", Names.PREFIX));
+ proxyHandler.setAction(WsxConstants.GET_METADATA_URI);
+ proxyHandler.setRequestName(WsxConstants.GET_METADATA_QNAME);
+ proxyHandler.setRequestParameterNames(new QName[]{
+ new QName(
+ WsxConstants.NAMESPACE_URI,
+ WsxConstants.DIALECT,
+ WsxConstants.PREFIX)});
+ proxyHandler.setResponseName(WsxConstants.METADATA_QNAME);
proxyHandler.setReturnType(Element[].class);
}
@@ -72,6 +77,7 @@ public class WsdmWsdlPerspectiveAction extends HttpServlet
String wsresourceid = objectName.getKeyProperty(Names.OBJECT_ID);
EndpointReference resourceEndpointReference = new EndpointReference(getURI(request));
+
resourceEndpointReference.addParameter(
Names.RESOURCE_ID_QNAME,
wsresourceid);
diff --git a/qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/QEmuInitializer.java b/qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/QEmuInitializer.java
index 545e587f79..47aa4ea681 100644
--- a/qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/QEmuInitializer.java
+++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/QEmuInitializer.java
@@ -57,7 +57,9 @@ public class QEmuInitializer extends HttpServlet
Names.QPID_EMULATOR_OBJECT_NAME);
} catch(Exception exception)
{
- LOGGER.warn(exception,Messages.QMAN_300005_QEMU_INITIALIZATION_FAILURE);
+ LOGGER.warn(
+ exception,
+ Messages.QMAN_300005_QEMU_INITIALIZATION_FAILURE);
throw new ServletException(exception);
}
}
@@ -84,8 +86,8 @@ public class QEmuInitializer extends HttpServlet
{
try
{
- ManagementFactory.getPlatformMBeanServer()
- .unregisterMBean(Names.QPID_EMULATOR_OBJECT_NAME);
+ ManagementFactory.getPlatformMBeanServer().unregisterMBean(
+ Names.QPID_EMULATOR_OBJECT_NAME);
} catch (Exception exception)
{
}
diff --git a/qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/capabilities/Constants.java b/qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/capabilities/Constants.java
new file mode 100644
index 0000000000..59a5801505
--- /dev/null
+++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/capabilities/Constants.java
@@ -0,0 +1,44 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.qpid.management.wsdm.capabilities;
+
+import javax.xml.XMLConstants;
+import javax.xml.namespace.QName;
+
+public interface Constants
+{
+ String WSRP_PROPERTIES_XPATH = "/wsdl:definitions/wsdl:types/xsd:schema[" +
+ "@targetNamespace='http://amqp.apache.org/qpid/management/qman']" +
+ "/xsd:element[@name='QManWsResourceProperties']/xsd:complexType/xsd:sequence";
+
+ String SERVICE_LOCATION_XPATH = "/wsdl:definitions/wsdl:service/wsdl:port/wsdl-soap:address/@location";
+ String QMAN_SCHEMA_XPATH = "/wsdl:definitions/wsdl:types/xsd:schema[@targetNamespace='http://amqp.apache.org/qpid/management/qman']";
+
+ String MIN_OCCURS = "minOccurs";
+ String REF_ATTRIBUTE = "ref";
+ String NAME_ATTRIBUTE = "name";
+ String TYPE_ATTRIBUTE ="type";
+
+ QName XSD_ELEMENT_QNAME = new QName(XMLConstants.W3C_XML_SCHEMA_NS_URI,"element","xsd");
+ QName XSD_COMPLEX_TYPE_QNAME = new QName(XMLConstants.W3C_XML_SCHEMA_NS_URI,"complexType","xsd");
+ QName XSD_SEQUENCE_QNAME = new QName(XMLConstants.W3C_XML_SCHEMA_NS_URI,"sequence","xsd");
+
+} \ No newline at end of file
diff --git a/qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/capabilities/ConsumerCapability.java b/qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/capabilities/ConsumerCapability.java
index dd5eb523c1..bde98092a0 100644
--- a/qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/capabilities/ConsumerCapability.java
+++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/capabilities/ConsumerCapability.java
@@ -29,6 +29,8 @@ import org.apache.muse.ws.notification.WsnConstants;
/**
* WS-Notifications consumer capability.
+ * At the moment QMan is not a consumer of itself so this capability is here only
+ * for test purposes.
*
* @author Andrea Gazzarini
*/
diff --git a/qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/capabilities/DummyCapabilityBuilder.java b/qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/capabilities/DummyCapabilityBuilder.java
index 0676b4ac49..370cf3086d 100644
--- a/qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/capabilities/DummyCapabilityBuilder.java
+++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/capabilities/DummyCapabilityBuilder.java
@@ -29,32 +29,57 @@ import org.apache.muse.core.Environment;
/**
* Dummy capability builder used for avoid duplicated builds for the
* same class.
+ * Basically it acts likes a Null Object when the target capability class has been
+ * already built.
*
* @author Andrea Gazzarini
*/
public class DummyCapabilityBuilder implements IArtifactBuilder
{
-
- public void begin(ObjectName objectName) throws BuilderException
+ /**
+ * Director callback.
+ * Do nothing here (see class comments above.)
+ */
+ public void begin(ObjectName objectName)
{
}
- public void endAttributes() throws BuilderException
+ /**
+ * Director callback.
+ * Do nothing here (see class comments above.)
+ */
+ public void endAttributes()
{
}
- public void endOperations() throws BuilderException
+ /**
+ * Director callback.
+ * Do nothing here (see class comments above.)
+ */
+ public void endOperations()
{
}
- public void onAttribute(MBeanAttributeInfo attributeMetadata) throws BuilderException
+ /**
+ * Director callback.
+ * Do nothing here (see class comments above.)
+ */
+ public void onAttribute(MBeanAttributeInfo attributeMetadata)
{
}
- public void onOperation(MBeanOperationInfo operationMetadata) throws BuilderException
+ /**
+ * Director callback.
+ * Do nothing here (see class comments above.)
+ */
+ public void onOperation(MBeanOperationInfo operationMetadata)
{
}
+ /**
+ * Director callback.
+ * Do nothing here (see class comments above.)
+ */
public void setEnvironment(Environment environment)
{
}
diff --git a/qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/capabilities/MBeanCapability.java b/qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/capabilities/MBeanCapability.java
index 82d8e97d37..37ecc0c031 100644
--- a/qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/capabilities/MBeanCapability.java
+++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/capabilities/MBeanCapability.java
@@ -179,12 +179,8 @@ public abstract class MBeanCapability extends AbstractWsResourceCapability
params,
signature);
- Result result = new Result(
- output.getReturnCode(),
- output.getStatusText(),
- output.getOutputSection());
-
- return result;
+ return new Result(output.getOutputSection());
+
} catch (InstanceNotFoundException exception)
{
throw new EntityInstanceNotFoundFault(
diff --git a/qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/capabilities/MBeanCapabilityBuilder.java b/qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/capabilities/MBeanCapabilityBuilder.java
index ea623138a4..ea67bdf9e1 100644
--- a/qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/capabilities/MBeanCapabilityBuilder.java
+++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/capabilities/MBeanCapabilityBuilder.java
@@ -178,6 +178,14 @@ public class MBeanCapabilityBuilder implements IArtifactBuilder{
}
}
+ /**
+ * Director callback.
+ * All attributes have been notified.
+ *
+ * This builder is using this callback in order to create the initial
+ * properties QNames declaration.
+ *
+ */
public void endAttributes() throws BuilderException
{
_endAttributeHandler.endAttributes();
diff --git a/qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/capabilities/QManMetadataExchangeCapability.java b/qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/capabilities/QManMetadataExchangeCapability.java
index 7e58992540..d6255d0bed 100644
--- a/qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/capabilities/QManMetadataExchangeCapability.java
+++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/capabilities/QManMetadataExchangeCapability.java
@@ -21,6 +21,10 @@
package org.apache.qpid.management.wsdm.capabilities;
import org.apache.muse.util.xml.XmlUtils;
+import org.apache.muse.ws.metadata.WsxConstants;
+import org.apache.muse.ws.resource.WsResource;
+import org.apache.muse.ws.resource.metadata.MetadataDescriptor;
+import org.apache.muse.ws.resource.metadata.WsrmdConstants;
import org.apache.muse.ws.resource.metadata.ext.WsrfMetadataExchange;
import org.apache.muse.ws.wsdl.WsdlUtils;
import org.apache.qpid.management.wsdm.muse.resources.QManWsResource;
@@ -60,4 +64,36 @@ public class QManMetadataExchangeCapability extends WsrfMetadataExchange
return wsdl;
}
+
+ /**
+ * Returns the resource metadata descriptor associated with the owenr
+ * resource of thi capability.
+ *
+ * @return the resource metadata descriptor.
+ */
+ protected Element getResourceMetadataDescriptor()
+ {
+ WsResource resource = (WsResource)getResource();
+ MetadataDescriptor metadataDescriptor = resource.getPropertyCollection().getMetadata();
+ return metadataDescriptor.toXML();
+ }
+
+ public Element[] getMetadata(String dialect)
+ {
+ if (dialect == null)
+ {
+ return new Element[]{
+ getResourceMetadataDescriptor(),
+ getWSDL()};
+ } else {
+ if (WsrmdConstants.NAMESPACE_URI.equals(dialect))
+ {
+ return new Element[]{getResourceMetadataDescriptor()};
+ } else if (WsxConstants.WSDL_DIALECT.equals(dialect))
+ {
+ return new Element[]{getWSDL()};
+ }
+ }
+ return super.getMetadata(dialect);
+ }
} \ No newline at end of file
diff --git a/qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/capabilities/Result.java b/qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/capabilities/Result.java
index b8e22b4bc7..a00d2665ae 100644
--- a/qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/capabilities/Result.java
+++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/capabilities/Result.java
@@ -29,11 +29,9 @@ import java.util.*;
*
* @author Andrea Gazzarini
*/
-public class Result
+public final class Result
{
- private long _statusCode;
- private String _statusText;
- private Map<String,Object> _outputParameters;
+ private final Map<String,Object> _outputParameters;
/**
* Builds a new result DTO with the given parameters.
@@ -42,53 +40,11 @@ public class Result
* @param statusText the status message.
* @param outputParameters the output parameters.
*/
- public Result(long statusCode, String statusText,Map<String, Object> outputParameters)
+ public Result(Map<String, Object> outputParameters)
{
- this._statusCode = statusCode;
- this._statusText = statusText;
this._outputParameters = outputParameters;
}
-
- /**
- * Returns the status code.
- *
- * @return the status code.
- */
- public long getStatusCode()
- {
- return _statusCode;
- }
-
- /**
- * Sets the status code.
- *
- * @param statusCode the status code.
- */
- void setStatusCode(long statusCode)
- {
- this._statusCode = statusCode;
- }
-
- /**
- * Returns the status text.
- *
- * @return the status text.
- */
- public String getStatusText()
- {
- return _statusText;
- }
-
- /**
- * Sets the status text.
- *
- * @param statusText the status text.
- */
- void setStatusText(String statusText)
- {
- this._statusText = statusText;
- }
-
+
/**
* Returns the output parameterss.
*
@@ -98,14 +54,4 @@ public class Result
{
return _outputParameters;
}
-
- /**
- * Sets the output parameters.
- *
- * @param outputParameters the output parameters.
- */
- void setOutputParameters(Map<String, Object> outputParameters)
- {
- this._outputParameters = outputParameters;
- }
-}
+} \ No newline at end of file
diff --git a/qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/capabilities/RmdBuilder.java b/qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/capabilities/RmdBuilder.java
index 86aba0e5bb..c1678eb43f 100644
--- a/qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/capabilities/RmdBuilder.java
+++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/capabilities/RmdBuilder.java
@@ -128,7 +128,8 @@ class RmdBuilder implements IArtifactBuilder
*/
public Element[] getResourceMetadataDescriptor()
{
- Element [] properties = _metadataDescriptor.toArray(new Element[0]);
+ Element [] properties = _metadataDescriptor.toArray(
+ new Element[_metadataDescriptor.size()]);
return properties;
}
} \ No newline at end of file
diff --git a/qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/capabilities/WSDMArtifactsDirector.java b/qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/capabilities/WSDMArtifactsDirector.java
index c9ffd5eac0..35a919c295 100644
--- a/qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/capabilities/WSDMArtifactsDirector.java
+++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/capabilities/WSDMArtifactsDirector.java
@@ -35,7 +35,7 @@ import org.w3c.dom.Element;
*
* @author Andrea Gazzarini
*/
-class WSDMArtifactsDirector
+final class WSDMArtifactsDirector
{
private final ObjectName _eventSourceObjectName;
private final MBeanInfo _metadata;
@@ -189,7 +189,8 @@ class WSDMArtifactsDirector
*
* @param resource the ws resource.
*/
- public void setResource(Resource resource) {
+ public void setResource(Resource resource)
+ {
_wsdlBuilder.setWsdlPath(resource.getWsdlPath());
}
} \ No newline at end of file
diff --git a/qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/capabilities/WsArtifactsFactory.java b/qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/capabilities/WsArtifactsFactory.java
index 2a1bf059c3..94505d28f7 100644
--- a/qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/capabilities/WsArtifactsFactory.java
+++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/capabilities/WsArtifactsFactory.java
@@ -105,13 +105,18 @@ class WsArtifactsFactory
_cache.put(searchKey, result);
- LOGGER.debug(Messages.QMAN_200040_WS_ARTIFACTS_CACHED,searchKey);
+ LOGGER.debug(
+ Messages.QMAN_200040_WS_ARTIFACTS_CACHED,
+ searchKey);
}
return result;
} catch(Exception exception)
{
- throw new ArtifactsNotAvailableException(result,exception,objectName);
+ throw new ArtifactsNotAvailableException(
+ result,
+ exception,
+ objectName);
}
}
diff --git a/qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/capabilities/WsdlBuilder.java b/qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/capabilities/WsdlBuilder.java
index 02b25eb02f..6bfccda1ce 100644
--- a/qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/capabilities/WsdlBuilder.java
+++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/capabilities/WsdlBuilder.java
@@ -23,20 +23,22 @@ package org.apache.qpid.management.wsdm.capabilities;
import java.net.InetAddress;
import java.util.HashMap;
import java.util.Map;
+import java.util.UUID;
import javax.management.MBeanAttributeInfo;
import javax.management.MBeanOperationInfo;
import javax.management.MBeanParameterInfo;
import javax.management.ObjectName;
-import javax.xml.XMLConstants;
-import javax.xml.namespace.QName;
+import javax.xml.transform.TransformerException;
import org.apache.muse.core.Environment;
+import org.apache.muse.core.serializer.SerializerRegistry;
import org.apache.muse.util.ReflectUtils;
import org.apache.muse.util.xml.XmlUtils;
import org.apache.muse.ws.wsdl.WsdlUtils;
import org.apache.qpid.management.Messages;
import org.apache.qpid.management.Names;
+import org.apache.qpid.management.wsdm.muse.engine.WSDMAdapterEnvironment;
import org.apache.qpid.management.wsdm.muse.serializer.ObjectSerializer;
import org.apache.qpid.qman.debug.WsdlDebugger;
import org.apache.qpid.transport.util.Logger;
@@ -49,126 +51,61 @@ import org.w3c.dom.Element;
*
* @author Andrea Gazzarini
*/
-class WsdlBuilder implements IArtifactBuilder {
+class WsdlBuilder implements IArtifactBuilder,Constants {
private final static Logger LOGGER = Logger.get(WsdlBuilder.class);
- private Environment _environment;
+ private WSDMAdapterEnvironment _environment;
private Document _document;
private Element schema;
-
- private ObjectSerializer serializer = new ObjectSerializer();
-
+ private Element _wsrpProperties;
+ private ObjectSerializer _serializer;
private ObjectName _objectName;
-
- private boolean mapTypeHasBeenDeclared;
- private boolean uuidTypeHasBeenDeclared;
private Map<String, String> arrayTypesAlreadyDeclared = new HashMap<String, String>();
+ private Element _arrayComplexType;
+ private Element _nestedArrayType;
+
+ /**
+ * For each attibute the corresponding xml type definition must be inserted on the QMan
+ * schema related section.
+ * After that, a reference to that definition must be declared on the wsrp element .
+ *
+ * @param attributeMetadata the attribute metadata.
+ * @throws BuilderException only if this builder wasn't able to get a reference (via XPath)
+ * to QMan schema section.
+ */
public void onAttribute(MBeanAttributeInfo attributeMetadata) throws BuilderException
{
try
{
- /*
- <xs:element name='accountAttributes'>
- <xs:complexType>
- <xs:sequence>
- <xs:element maxOccurs='unbounded' minOccurs='0' name='entry'>
- <xs:complexType>
- <xs:sequence>
- <xs:element minOccurs='0' name='key' type='xs:string'/>
- <xs:element minOccurs='0' name='value' type='xs:anyType'/>
- </xs:sequence>
- </xs:complexType>
- </xs:element>
- </xs:sequence>
- </xs:complexType>
- </xs:element>
-*/
- schema.appendChild(defineSchemaFor(attributeMetadata.getType(), attributeMetadata.getName()));
- Element wsrpProperties = (Element) XPathAPI.selectSingleNode(
- _document,
- "/wsdl:definitions/wsdl:types/xsd:schema[" +
- "@targetNamespace='http://amqp.apache.org/qpid/management/qman']" +
- "/xsd:element[@name='QManWsResourceProperties']/xsd:complexType/xsd:sequence");
+ String attributeName = attributeMetadata.getName();
+ schema.appendChild(defineSchemaFor(attributeMetadata.getType(), attributeName));
Element propertyRef= XmlUtils.createElement(_document, XSD_ELEMENT_QNAME);
+ propertyRef.setAttribute(MIN_OCCURS, "0");
propertyRef.setAttribute(
- "ref",
- Names.PREFIX+":"+attributeMetadata.getName());
- propertyRef.setAttribute("minOccurs", "0");
- wsrpProperties.appendChild(propertyRef);
-
+ REF_ATTRIBUTE,
+ Names.PREFIX+":"+attributeName);
+
+ _wsrpProperties.appendChild(propertyRef);
} catch(Exception exception)
{
throw new BuilderException(exception);
}
}
- private final static QName XSD_ELEMENT_QNAME = new QName(XMLConstants.W3C_XML_SCHEMA_NS_URI,"element","xsd");
- private final static QName XSD_COMPLEX_TYPE_QNAME = new QName(XMLConstants.W3C_XML_SCHEMA_NS_URI,"complexType","xsd");
- private final static QName XSD_SEQUENCE_QNAME = new QName(XMLConstants.W3C_XML_SCHEMA_NS_URI,"sequence","xsd");
-
@SuppressWarnings("unchecked")
private Element defineSchemaFor(String type, String attributeName) throws Exception
{
- if (type.equals("java.util.Map"))
+ Element propertyDeclaration = XmlUtils.createElement(_document, XSD_ELEMENT_QNAME);
+ String xmlType = null;
+ if (type.equals(Map.class.getName()))
{
- if (!mapTypeHasBeenDeclared)
- {
- Element complexType = XmlUtils.createElement(_document, XSD_COMPLEX_TYPE_QNAME);
- complexType.setAttribute("name","map");
- Element sequence = XmlUtils.createElement(_document, XSD_SEQUENCE_QNAME);
-
- Element entry = XmlUtils.createElement(_document, XSD_ELEMENT_QNAME);
- entry.setAttribute("name", "entry");
- entry.setAttribute("minOccurs", "0");
- entry.setAttribute("maxOccurs", "unbounded");
-
- Element complexType2 = XmlUtils.createElement(_document, XSD_COMPLEX_TYPE_QNAME);
- Element sequence2 = XmlUtils.createElement(_document, XSD_SEQUENCE_QNAME);
-
- Element key = XmlUtils.createElement(_document, XSD_ELEMENT_QNAME);
- key.setAttribute("name", "key");
- key.setAttribute("type", "xsd:string");
-
- Element value = XmlUtils.createElement(_document, XSD_ELEMENT_QNAME);
- value.setAttribute("name", "value");
- value.setAttribute("type", "xsd:anyType");
-
- sequence2.appendChild(key);
- sequence2.appendChild(value);
- complexType2.appendChild(sequence2);
- entry.appendChild(complexType2);
- sequence.appendChild(entry);
- complexType.appendChild(sequence);
- schema.appendChild(complexType);
- mapTypeHasBeenDeclared = true;
- }
- Element propertyDeclaration = XmlUtils.createElement(_document, XSD_ELEMENT_QNAME);
- propertyDeclaration.setAttribute("name",attributeName);
- propertyDeclaration.setAttribute("type", "qman:map");
- return propertyDeclaration;
-
- } else if ("java.util.UUID".equals(type))
- {
- if (!uuidTypeHasBeenDeclared)
- {
- Element complexType = XmlUtils.createElement(_document, XSD_COMPLEX_TYPE_QNAME);
- complexType.setAttribute("name", "uuid");
- Element sequence = XmlUtils.createElement(_document, XSD_SEQUENCE_QNAME);
- Element uuid = XmlUtils.createElement(_document, XSD_ELEMENT_QNAME);
- uuid.setAttribute("name", "uuid");
- uuid.setAttribute("type", "xsd:string");
- sequence.appendChild(uuid);
- complexType.appendChild(sequence);
- schema.appendChild(complexType);
- uuidTypeHasBeenDeclared = true;
- }
- Element propertyDeclaration = XmlUtils.createElement(_document, XSD_ELEMENT_QNAME);
- propertyDeclaration.setAttribute("name",attributeName);
- propertyDeclaration.setAttribute("type", "qman:uuid");
- return propertyDeclaration;
+ xmlType="qman:map";
+ } else if (UUID.class.getName().equals(type))
+ {
+ xmlType = "qman:uuid";
} else if (type.startsWith("["))
{
Class arrayClass = Class.forName(type);
@@ -177,143 +114,40 @@ class WsdlBuilder implements IArtifactBuilder {
arrayType = Character.toUpperCase(arrayType.charAt(0))+arrayType.substring(1);
if (!arrayTypesAlreadyDeclared.containsKey(type))
{
- Element complexType = XmlUtils.createElement(_document, XSD_COMPLEX_TYPE_QNAME);
- complexType.setAttribute("name", "arrayOf"+arrayType);
- Element sequence = XmlUtils.createElement(_document, XSD_SEQUENCE_QNAME);
- Element entry = XmlUtils.createElement(_document, XSD_ELEMENT_QNAME);
- entry.setAttribute("name", "entry");
- entry.setAttribute("type", serializer.getXmlType(clazz));
- sequence.appendChild(entry);
- complexType.appendChild(sequence);
- schema.appendChild(complexType);
+ _arrayComplexType.setAttribute(NAME_ATTRIBUTE, "arrayOf"+arrayType);
+ _nestedArrayType.setAttribute(TYPE_ATTRIBUTE, _serializer.getXmlType(clazz));
+ schema.appendChild(_arrayComplexType);
arrayTypesAlreadyDeclared.put(type, arrayType);
}
- Element propertyDeclaration = XmlUtils.createElement(_document, XSD_ELEMENT_QNAME);
- propertyDeclaration.setAttribute("name",attributeName);
- propertyDeclaration.setAttribute("type", "qman:arrayOf"+arrayTypesAlreadyDeclared.get(type));
- return propertyDeclaration;
+ xmlType = "qman:arrayOf"+arrayTypesAlreadyDeclared.get(type);
}
- else {
- Element propertyDeclaration = XmlUtils.createElement(_document, XSD_ELEMENT_QNAME);
- propertyDeclaration.setAttribute("name",attributeName);
- propertyDeclaration.setAttribute("type", serializer.getXmlType(Class.forName(type)));
-
- return propertyDeclaration;
+ else
+ {
+ xmlType = _serializer.getXmlType(Class.forName(type));
}
+ propertyDeclaration.setAttribute(NAME_ATTRIBUTE,attributeName);
+ propertyDeclaration.setAttribute(TYPE_ATTRIBUTE, xmlType);
+ return propertyDeclaration;
}
-
+
+ /**
+ * Initializes this builder.
+ *
+ * @param objectName the name of the current JMX entity.
+ * @throws BuilderException when it's not possible to proceed with the initialization.
+ */
public void begin(ObjectName objectName) throws BuilderException
{
this._objectName = objectName;
- try
- {
- Attr location = (Attr) XPathAPI.selectSingleNode(
- _document,
- "/wsdl:definitions/wsdl:service/wsdl:port/wsdl-soap:address/@location");
-
- StringBuilder builder = new StringBuilder("http://")
- .append(InetAddress.getLocalHost().getHostName())
- .append(':')
- .append(System.getProperty(Names.ADAPTER_PORT_PROPERTY_NAME,"8080"))
- .append('/')
- .append("qman")
- .append('/')
- .append("services/QManWsResource");
- location.setValue(builder.toString());
- } catch(Exception exception)
- {
- LOGGER.error(
- exception,
- Messages.QMAN_100026_SOAP_ADDRESS_REPLACEMENT_FAILURE);
- throw new BuilderException(exception);
- }
-
- try
- {
- schema = (Element) XPathAPI.selectSingleNode(
- _document.getDocumentElement(),
- "/wsdl:definitions/wsdl:types/xsd:schema[@targetNamespace='http://amqp.apache.org/qpid/management/qman']");
- } catch(Exception exception)
- {
- LOGGER.error(
- exception,
- Messages.QMAN_100034_WSDL_SCHEMA_SECTION_NOT_FOUND);
- throw new BuilderException(exception);
- }
-/*
- <xs:complexType name='InvocationResult'>
- <xs:sequence>
- <xs:element name='statusCode' type="xsd:long" />
- <xs:element name='statusText' type="xsd:string" />
- <xs:element name='outputParameters'>
- <xs:complexType>
- <xs:sequence>
-
- <xs:element maxOccurs='unbounded' minOccurs='0' name='entry'>
-
- <xs:complexType>
- <xs:sequence>
- <xs:element minOccurs='0' name="name' type='xs:string'/>
- <xs:element minOccurs='0' name="value" type='xs:anyType'/>
- </xs:sequence>
- </xs:complexType>
- </xs:element>
- </xs:sequence>
- </xs:complexType>
- </xs:element>
- </xs:sequence>
- </xs:complexType>
-*/
- Element complexTypeResult = _document.createElement("xsd:complexType");
- complexTypeResult.setAttribute("name", "result");
- Element sequence = _document.createElement("xsd:sequence");
- complexTypeResult.appendChild(sequence);
-
- Element statusCode = _document.createElement("xsd:element");
- statusCode.setAttribute("name", "statusCode");
- statusCode.setAttribute("type", "xsd:long");
-
- Element statusText = _document.createElement("xsd:element");
- statusText.setAttribute("name", "statusText");
- statusText.setAttribute("type", "xsd:string");
-
- sequence.appendChild(statusCode);
- sequence.appendChild(statusText);
-
- Element outputParams = _document.createElement("xsd:complexType");
- outputParams.setAttribute("name", "outputParameters");
- sequence.appendChild(outputParams);
-
- Element complexTypeOutput = _document.createElement("xsd:complexType");
- Element outputSequence = _document.createElement("xsd:sequence");
+ this._serializer = (ObjectSerializer) SerializerRegistry.getInstance().getSerializer(Object.class);
- outputParams.appendChild(complexTypeOutput);
- complexTypeOutput.appendChild(outputSequence);
+ createWsrpPropertiesElement();
- Element entry = _document.createElement("xsd:element");
- entry.setAttribute("maxOccurs", "unbounded");
- entry.setAttribute("minOccurs", "0");
- entry.setAttribute("name", "entry");
+ createReusableArrayComplextType();
- outputSequence.appendChild(entry);
+ replaceDummyServiceLocationOnWsdl();
- Element entryComplexType = _document.createElement("xsd:complexType");
- Element entrySequence = _document.createElement("xsd:sequence");
- entryComplexType.appendChild(entrySequence);
- entry.appendChild(entryComplexType);
-
- Element name = _document.createElement("xsd:name");
- name.setAttribute("name", "key");
- name.setAttribute("type", "xsd:string");
-
- Element value = _document.createElement("xsd:element");
- value.setAttribute("name", "value");
- value.setAttribute("type", "xsd:anyType");
-
- entrySequence.appendChild(name);
- entrySequence.appendChild(value);
-
- schema.appendChild(complexTypeResult);
+ createSchemaElement();
}
public void onOperation(MBeanOperationInfo operationMetadata) throws BuilderException
@@ -350,9 +184,9 @@ class WsdlBuilder implements IArtifactBuilder {
<xs:sequence />
</xs:complexType>
*/
+
try
{
- // <xs:element name='purgeRequest' type='qman:purgeRequest' />
// <xsd:element xmlns="" name="purgeRequest" type="qman:purgeRequest"/>
Element methodRequestElement= _document.createElement("xsd:element");
@@ -361,13 +195,13 @@ class WsdlBuilder implements IArtifactBuilder {
methodRequestElement.setAttribute("type", "qman:"+methodNameRequest);
// <xs:element name='purgeResponse' type='qman:purgeResponse' />
- Element methodResponseElement= _document.createElement("xsd:element");
+// Element methodResponseElement= _document.createElement("xsd:element");
String methodNameResponse= operationMetadata.getName()+"Response";
- methodResponseElement.setAttribute("name", methodNameResponse);
- methodResponseElement.setAttribute("type", "qman:"+methodNameResponse);
+// methodResponseElement.setAttribute("name", methodNameResponse);
+// methodResponseElement.setAttribute("type", "qman:result");//+methodNameResponse);
schema.appendChild(methodRequestElement);
- schema.appendChild(methodResponseElement);
+// schema.appendChild(methodResponseElement);
/*
<xs:complexType name='purgeRequest'>
@@ -391,19 +225,6 @@ class WsdlBuilder implements IArtifactBuilder {
methodNameRequestComplexType.appendChild(methodNameRequestComplexTypeSequence);
schema.appendChild(methodNameRequestComplexType);
- Element methodNameResponseComplexType = _document.createElement("xsd:complexType");
- methodNameResponseComplexType.setAttribute("name", methodNameResponse);
-
- Element methodNameResponseSequence = _document.createElement("xsd:sequence");
- methodNameResponseComplexType.appendChild(methodNameResponseSequence);
-
- Element result = _document.createElement("xsd:element");
- result.setAttribute("name", "result");
- result.setAttribute("type", "qman:result");
- methodNameResponseSequence.appendChild(result);
-
- schema.appendChild(methodNameResponseComplexType);
-
/*
<message name="purgeResponseMessage">
<part element='qman:purgeResponse' name='purgeResponse'></part>
@@ -428,7 +249,7 @@ class WsdlBuilder implements IArtifactBuilder {
Element responseMessage = _document.createElement("wsdl:message");
responseMessage.setAttribute("name", responseMessageName);
Element responsePart = _document.createElement("wsdl:part");
- responsePart.setAttribute("element", "qman:"+methodNameResponse);
+ responsePart.setAttribute("element", "qman:result");//+methodNameResponse);
responsePart.setAttribute("name", methodNameResponse);
responseMessage.appendChild(responsePart);
@@ -506,29 +327,134 @@ class WsdlBuilder implements IArtifactBuilder {
}
}
+ /**
+ * Director callback : all attributes have been notified.
+ * Nothing to do here.
+ */
public void endAttributes()
{
// N.A.
}
+ /**
+ * Director callback : all operations have been notified.
+ * Nothing to do here.
+ */
public void endOperations()
{
-
+ // N.A.
}
+ /**
+ * Returns the WSDL built by this builder.
+ *
+ * @return the WSDL built by this builder.
+ */
public Document getWsdl()
{
WsdlDebugger.debug(_objectName,_document);
return _document;
}
+ /**
+ * Injects the application context environment
+ * on this builder.
+ *
+ * @param environment the application context environment.
+ */
public void setEnvironment(Environment environment)
{
- this._environment = environment;
+ this._environment = (WSDMAdapterEnvironment)environment;
}
+ /**
+ * Injects the path of the wsdl document.
+ *
+ * @param wsdlPath the path of the wsdl document.
+ */
public void setWsdlPath(String wsdlPath)
{
_document = WsdlUtils.createWSDL(_environment, wsdlPath, true);
}
-}
+
+ /**
+ * Create a reference to the WSRP properties element.
+ *
+ * @throws BuilderException in case of XPath evaluation problem.
+ */
+ private void createWsrpPropertiesElement() throws BuilderException
+ {
+ try
+ {
+ _wsrpProperties = (Element) XPathAPI.selectSingleNode(
+ _document,
+ WSRP_PROPERTIES_XPATH);
+ } catch (TransformerException exception)
+ {
+ LOGGER.error(Messages.QMAN_100040_UNABLE_TO_LOCATE_WSRP_PROPERTIES);
+ throw new BuilderException(exception);
+ }
+ }
+
+ /**
+ * Creates a template element that will be used for array
+ * type schema declaration(s).
+ */
+ private void createReusableArrayComplextType()
+ {
+ _arrayComplexType = XmlUtils.createElement(_document, XSD_COMPLEX_TYPE_QNAME);
+ Element sequence = XmlUtils.createElement(_document, XSD_SEQUENCE_QNAME);
+ _nestedArrayType = XmlUtils.createElement(_document, XSD_ELEMENT_QNAME);
+ _nestedArrayType.setAttribute(NAME_ATTRIBUTE, "entry");
+ sequence.appendChild(_nestedArrayType);
+ _arrayComplexType.appendChild(sequence);
+ }
+
+ private void createSchemaElement() throws BuilderException
+ {
+ try
+ {
+ schema = (Element) XPathAPI.selectSingleNode(
+ _document.getDocumentElement(),
+ QMAN_SCHEMA_XPATH);
+ } catch(Exception exception)
+ {
+ LOGGER.error(
+ exception,
+ Messages.QMAN_100034_WSDL_SCHEMA_SECTION_NOT_FOUND);
+ throw new BuilderException(exception);
+ }
+ }
+
+ /**
+ * The template WSDL contains a dummy URL as service location that
+ * needs to be replaced with the real service address.
+ *
+ * @throws BuilderException when replacement fails (XPath problem).
+ */
+ private void replaceDummyServiceLocationOnWsdl() throws BuilderException
+ {
+ try
+ {
+ Attr location = (Attr) XPathAPI.selectSingleNode(
+ _document,
+ SERVICE_LOCATION_XPATH);
+
+ StringBuilder builder = new StringBuilder("http://")
+ .append(InetAddress.getLocalHost().getHostName())
+ .append(':')
+ .append(System.getProperty(Names.ADAPTER_PORT_PROPERTY_NAME,"8080"))
+ .append('/')
+ .append(_environment.getContextPath())
+ .append('/')
+ .append("services/QManWsResource");
+ location.setValue(builder.toString());
+ } catch(Exception exception)
+ {
+ LOGGER.error(
+ exception,
+ Messages.QMAN_100026_SOAP_ADDRESS_REPLACEMENT_FAILURE);
+ throw new BuilderException(exception);
+ }
+ }
+} \ No newline at end of file
diff --git a/qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/common/EntityInstanceNotFoundFault.java b/qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/common/EntityInstanceNotFoundFault.java
index 25bb871e75..116d74727a 100644
--- a/qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/common/EntityInstanceNotFoundFault.java
+++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/common/EntityInstanceNotFoundFault.java
@@ -50,6 +50,9 @@ public class EntityInstanceNotFoundFault extends QManFault
*/
public EntityInstanceNotFoundFault(EndpointReference endpointReference, ObjectName targetEntityName)
{
- super(endpointReference,EXCEPTION_QNAME, targetEntityName.getCanonicalName());
+ super(
+ endpointReference,
+ EXCEPTION_QNAME,
+ targetEntityName.getCanonicalName());
}
} \ No newline at end of file
diff --git a/qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/common/ThreadSession.java b/qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/common/ThreadSession.java
index bc214b8b25..588879b951 100644
--- a/qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/common/ThreadSession.java
+++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/common/ThreadSession.java
@@ -25,7 +25,6 @@ import javax.management.ObjectName;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
-
/**
* Thread-scoped session.
*
@@ -35,7 +34,8 @@ public class ThreadSession
{
private ObjectName _objectName;
private Document _wsdl;
- private Element [] additionalProperties;
+ private Element [] _wsrmdProperties;
+
/**
* Empty constructor.
*/
@@ -90,7 +90,7 @@ public class ThreadSession
*/
public Element[] getResourceMetadataDescriptor()
{
- return additionalProperties;
+ return _wsrmdProperties;
}
/**
@@ -100,6 +100,6 @@ public class ThreadSession
*/
public void setResourceMetadataDescriptor(Element[] rmd)
{
- this.additionalProperties = rmd;
+ this._wsrmdProperties = rmd;
}
} \ No newline at end of file
diff --git a/qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/muse/engine/WSDMAdapterEnvironment.java b/qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/muse/engine/WSDMAdapterEnvironment.java
index f47a587830..b5d978e0e5 100644
--- a/qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/muse/engine/WSDMAdapterEnvironment.java
+++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/muse/engine/WSDMAdapterEnvironment.java
@@ -64,6 +64,11 @@ public class WSDMAdapterEnvironment extends AbstractEnvironment
return _realDirectory;
}
+ /**
+ * Returns the default endpoint reference URI.
+ *
+ * @return the default endpoint reference URI.
+ */
public String getDefaultURIPrefix()
{
return new StringBuilder()
@@ -79,4 +84,14 @@ public class WSDMAdapterEnvironment extends AbstractEnvironment
.append("/services/")
.toString();
}
+
+ /**
+ * Returns the context path name of QMan application.
+ *
+ * @return the context path name of QMan application.
+ */
+ public String getContextPath()
+ {
+ return _servletContext.getContextPath();
+ }
} \ No newline at end of file
diff --git a/qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/muse/serializer/InvocationResultSerializer.java b/qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/muse/serializer/InvocationResultSerializer.java
index 0af570eacf..b819d52ad1 100644
--- a/qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/muse/serializer/InvocationResultSerializer.java
+++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/muse/serializer/InvocationResultSerializer.java
@@ -38,8 +38,6 @@ import org.w3c.dom.Element;
*/
public class InvocationResultSerializer implements Serializer
{
- private Serializer _longSerializer = SerializerRegistry.getInstance().getSerializer(long.class);
- private Serializer _stringSerializer = SerializerRegistry.getInstance().getSerializer(String.class);
private Serializer _mapSerializer = SerializerRegistry.getInstance().getSerializer(Map.class);
/**
@@ -51,26 +49,8 @@ public class InvocationResultSerializer implements Serializer
@SuppressWarnings("unchecked")
public Object fromXML(Element elementData) throws SoapFault
{
- long statusCode = 0;
- String statusText = null;
- Map<String, Object> outputSection = null;
-
- Element[] elements = XmlUtils.getAllElements(elementData);
- for (Element element : elements)
- {
- if ("statusCode".equals(element.getNodeName()))
- {
- statusCode = (Long) _longSerializer.fromXML(element);
- } else if ("statusText".equals(element.getNodeName()))
- {
- statusText = (String) _stringSerializer.fromXML(element);
- } else if ("outputParameters".equals(element.getNodeName()))
- {
- outputSection = (Map<String, Object>) _mapSerializer.fromXML(element);
- }
- }
-
- return new Result(statusCode,statusText,outputSection);
+ Element outputParameters = XmlUtils.getFirstElement(elementData);
+ return new Result((Map<String, Object>) _mapSerializer.fromXML(outputParameters));
}
/**
@@ -95,17 +75,11 @@ public class InvocationResultSerializer implements Serializer
{
Result result = (Result) obj;
Element root = XmlUtils.createElement(qname);
- Element statusCode = SerializerRegistry.getInstance().getSerializer(long.class).toXML(result.getStatusCode(), new QName("statusCode"));
- Element statusText = SerializerRegistry.getInstance().getSerializer(String.class).toXML(result.getStatusText(), new QName("statusText"));
-
- root.appendChild(statusCode);
- root.appendChild(statusText);
if (result.getOutputParameters() != null)
{
Element outputSection = SerializerRegistry.getInstance().getSerializer(Map.class).toXML(result.getOutputParameters(), new QName("outputParameters"));
root.appendChild(outputSection);
}
- return root;
-
+ return root;
}
} \ No newline at end of file
diff --git a/qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/muse/serializer/MapSerializer.java b/qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/muse/serializer/MapSerializer.java
index 1d0d02c669..07e1dfdc56 100644
--- a/qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/muse/serializer/MapSerializer.java
+++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/wsdm/muse/serializer/MapSerializer.java
@@ -62,25 +62,29 @@ public class MapSerializer implements Serializer
public Object fromXML(Element xml) throws SoapFault
{
Map<Object,Object> result = new HashMap<Object,Object>();
- Element[] children = XmlUtils.getAllElements(xml);
- Serializer objectDeserializer = SerializerRegistry.getInstance().getSerializer(Object.class);
- for (Element entry : children)
+ if (xml != null)
{
- Element[] keysAndValues = XmlUtils.getAllElements(entry);
- Object key = null;
- Object value = null;
- for (Element element : keysAndValues)
+ Element[] children = XmlUtils.getAllElements(xml);
+ Serializer objectDeserializer = SerializerRegistry.getInstance().getSerializer(Object.class);
+
+ for (Element entry : children)
{
- if (Names.KEY.equals(element.getLocalName()))
- {
- key = _stringSerializer.fromXML(element);
- } else if (Names.VALUE.equals(element.getLocalName()))
+ Element[] keysAndValues = XmlUtils.getAllElements(entry);
+ Object key = null;
+ Object value = null;
+ for (Element element : keysAndValues)
{
- value = objectDeserializer.fromXML(element);
+ if (Names.KEY.equals(element.getLocalName()))
+ {
+ key = _stringSerializer.fromXML(element);
+ } else if (Names.VALUE.equals(element.getLocalName()))
+ {
+ value = objectDeserializer.fromXML(element);
+ }
}
+ result.put(key, value);
}
- result.put(key, value);
}
return result;
}
diff --git a/qpid/java/management/client/src/main/java/wsdl/QManWsResource.wsdl b/qpid/java/management/client/src/main/java/wsdl/QManWsResource.wsdl
index 69647521ba..16169c9b78 100644
--- a/qpid/java/management/client/src/main/java/wsdl/QManWsResource.wsdl
+++ b/qpid/java/management/client/src/main/java/wsdl/QManWsResource.wsdl
@@ -93,7 +93,33 @@
</xsd:complexContent>
</xsd:complexType>
</xsd:element>
- </xsd:schema>
+
+ <xsd:complexType name="uuid">
+ <xsd:sequence>
+ <xsd:element name="uuid" type="xsd:string"/>
+ </xsd:sequence>
+ </xsd:complexType>
+
+ <xsd:complexType name="map">
+ <xsd:sequence>
+ <xsd:element name="entry" minOccurs="0" maxOccurs="unbounded">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element name="key" type="xsd:string"/>
+ <xsd:element name="value" type="xsd:anyType"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ </xsd:element>
+ </xsd:sequence>
+ </xsd:complexType>
+
+ <xsd:complexType name="result">
+ <xsd:sequence>
+ <xsd:element name="outputParameters" type="qman:map"/>
+ </xsd:sequence>
+ </xsd:complexType>
+
+ </xsd:schema>
</wsdl:types>
<wsdl:message name="GetMetadataMsg">
<wsdl:part name="GetMetadataMsg" element="wsx:GetMetadata" />
diff --git a/qpid/java/management/client/src/main/java/wsdl/WS-BaseNotification-1_3.wsdl b/qpid/java/management/client/src/main/java/wsdl/WS-BaseNotification-1_3.wsdl
index 8764c18fc9..d53bf60f3a 100644
--- a/qpid/java/management/client/src/main/java/wsdl/WS-BaseNotification-1_3.wsdl
+++ b/qpid/java/management/client/src/main/java/wsdl/WS-BaseNotification-1_3.wsdl
@@ -424,23 +424,22 @@ This document and the information contained herein is provided on an "AS IS" bas
<wsdl:fault name="InvalidResourcePropertyQNameFault" message="wsrf-rpw:InvalidResourcePropertyQNameFault" />
</wsdl:operation>
- </wsdl:portType>
+<!-- </wsdl:portType>
-<!-- ====== PausableSubscriptionManager PortType Definition ======= -->
<wsdl:portType name="PausableSubscriptionManager">
-
+-->
<!-- === PausableSubscriptionManager specific operations === -->
<wsdl:operation name="PauseSubscription">
- <wsdl:input message="wsntw:PauseSubscriptionRequest"/>
- <wsdl:output message="wsntw:PauseSubscriptionResponse"/>
+ <wsdl:input message="wsntw:PauseSubscriptionRequest" wsa:Action="http://docs.oasis-open.org/wsn/bw-2/SubscriptionManager/PauseSubscriptionRequest"/>
+ <wsdl:output message="wsntw:PauseSubscriptionResponse" wsa:Action="http://docs.oasis-open.org/wsn/bw-2/SubscriptionManager/PauseSubscriptionResponse"/>
<wsdl:fault name="ResourceUnknownFault"
message="wsrf-rw:ResourceUnknownFault" />
<wsdl:fault name="PauseFailedFault"
message="wsntw:PauseFailedFault" />
</wsdl:operation>
<wsdl:operation name="ResumeSubscription">
- <wsdl:input message="wsntw:ResumeSubscriptionRequest"/>
- <wsdl:output message="wsntw:ResumeSubscriptionResponse"/>
+ <wsdl:input message="wsntw:ResumeSubscriptionRequest" wsa:Action="http://docs.oasis-open.org/wsn/bw-2/SubscriptionManager/ResumeSubscriptionRequest"/>
+ <wsdl:output message="wsntw:ResumeSubscriptionResponse" wsa:Action="http://docs.oasis-open.org/wsn/bw-2/SubscriptionManager/ResumeSubscriptionResponse"/>
<wsdl:fault name="ResourceUnknownFault"
message="wsrf-rw:ResourceUnknownFault" />
<wsdl:fault name="ResumeFailedFault"
diff --git a/qpid/java/management/client/src/main/java/wsdl/WS-ServiceGroupEntry-1_2.wsdl b/qpid/java/management/client/src/main/java/wsdl/WS-ServiceGroupEntry-1_2.wsdl
index dc4581d8a8..379382c18d 100644
--- a/qpid/java/management/client/src/main/java/wsdl/WS-ServiceGroupEntry-1_2.wsdl
+++ b/qpid/java/management/client/src/main/java/wsdl/WS-ServiceGroupEntry-1_2.wsdl
@@ -200,7 +200,7 @@
</wsdl:binding>
<wsdl:service name="ServiceGroupEntryService">
<wsdl:port name="ServiceGroupEntryPort" binding="tns:ServiceGroupEntryBinding">
- <wsdl-soap:address location="http://romagazzarini:8080/wsrf/services/ServiceGroupEntry"/>
+ <wsdl-soap:address location="http://localhost:8080/wsrf/services/ServiceGroupEntry"/>
</wsdl:port>
</wsdl:service>
</wsdl:definitions>
diff --git a/qpid/java/management/client/src/test/java/org/apache/qpid/management/TestConstants.java b/qpid/java/management/client/src/test/java/org/apache/qpid/management/TestConstants.java
index 12ba1fab73..9abcd08eef 100644
--- a/qpid/java/management/client/src/test/java/org/apache/qpid/management/TestConstants.java
+++ b/qpid/java/management/client/src/test/java/org/apache/qpid/management/TestConstants.java
@@ -63,5 +63,5 @@ public interface TestConstants
int SAMPLE_ACCESS_CODE = 1;
String YEARS = "years";
int SAMPLE_MIN_VALUE = 1;
- int SAMPLE_MAX_VALUE = 120;
+ int SAMPLE_MAX_VALUE = 120;
} \ No newline at end of file
diff --git a/qpid/java/management/client/src/test/java/org/apache/qpid/management/configuration/ConfigurationTest.java b/qpid/java/management/client/src/test/java/org/apache/qpid/management/configuration/ConfigurationTest.java
index 8e9c3ccd6b..72bd45f70f 100644
--- a/qpid/java/management/client/src/test/java/org/apache/qpid/management/configuration/ConfigurationTest.java
+++ b/qpid/java/management/client/src/test/java/org/apache/qpid/management/configuration/ConfigurationTest.java
@@ -23,16 +23,13 @@ package org.apache.qpid.management.configuration;
import java.util.Map;
import java.util.UUID;
+import junit.framework.TestCase;
+
import org.apache.qpid.management.TestConstants;
import org.apache.qpid.management.domain.handler.base.IMessageHandler;
import org.apache.qpid.management.domain.handler.impl.ConfigurationMessageHandler;
import org.apache.qpid.management.domain.handler.impl.InstrumentationMessageHandler;
import org.apache.qpid.management.domain.handler.impl.SchemaResponseMessageHandler;
-import org.apache.qpid.management.domain.model.AccessMode;
-import org.apache.qpid.management.domain.model.type.Type;
-import org.apache.qpid.management.domain.model.type.Uint8;
-
-import junit.framework.TestCase;
/**
* Test case for Configuration singleton.
@@ -46,22 +43,7 @@ public class ConfigurationTest extends TestCase
{
assertSame(Configuration.getInstance(),Configuration.getInstance());
}
-
- /**
- * Tests the execution of getType() method when a valid code is supplied.
- *
- * <br>precondition : the requested type already exist on the configuration.
- * <br>postcondition : the requested type is returned and no exception is thrown.
- */
- public void testGetTypeOk() throws UnknownTypeCodeException
- {
- TypeMapping mapping = new TypeMapping(TestConstants.VALID_CODE,new Uint8());
- Configuration.getInstance().addTypeMapping(mapping);
- Type type = Configuration.getInstance().getType(TestConstants.VALID_CODE);
- assertTrue(type instanceof Uint8);
- }
-
/**
* Tests the execution of getType() method when a unknown code is supplied.
*
@@ -79,22 +61,7 @@ public class ConfigurationTest extends TestCase
assertEquals(TestConstants.VALID_CODE*10001,expected.getCode());
}
}
-
- /**
- * Tests the execution of getAccessMode() method when a valid code is supplied.
- *
- * <br>precondition : the requested access mode already exist on the configuration.
- * <br>postcondition : the requested access mode is returned and no exception is thrown.
- */
- public void testGetAccessModeOk() throws UnknownAccessCodeException
- {
- AccessModeMapping mapping = new AccessModeMapping(TestConstants.VALID_CODE,AccessMode.RW);
- Configuration.getInstance().addAccessModeMapping(mapping);
- AccessMode accessMode = Configuration.getInstance().getAccessMode(TestConstants.VALID_CODE);
-
- assertSame(AccessMode.RW,accessMode);
- }
-
+
/**
* Tests the execution of getAccessMode() method when a unknown code is supplied.
*
diff --git a/qpid/java/management/client/src/test/java/org/apache/qpid/management/wsdm/BaseWsDmAdapterTestCase.java b/qpid/java/management/client/src/test/java/org/apache/qpid/management/wsdm/BaseWsDmAdapterTestCase.java
new file mode 100644
index 0000000000..900d14c72e
--- /dev/null
+++ b/qpid/java/management/client/src/test/java/org/apache/qpid/management/wsdm/BaseWsDmAdapterTestCase.java
@@ -0,0 +1,143 @@
+/*
+ *
+ * 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.management.wsdm;
+
+import java.lang.management.ManagementFactory;
+import java.net.URI;
+import java.util.UUID;
+
+import javax.management.MBeanInfo;
+import javax.management.MBeanServer;
+import javax.management.ObjectName;
+
+import junit.framework.TestCase;
+
+import org.apache.muse.ws.addressing.EndpointReference;
+import org.apache.muse.ws.resource.remote.WsResourceClient;
+import org.apache.muse.ws.resource.sg.remote.ServiceGroupClient;
+import org.apache.qpid.management.Names;
+import org.apache.qpid.management.Protocol;
+import org.apache.qpid.management.TestConstants;
+
+/**
+ * Test case for WS-Resource lifecycle management.
+ *
+ * @author Andrea Gazzarini
+ */
+public abstract class BaseWsDmAdapterTestCase extends TestCase implements TestConstants{
+
+ protected MBeanServer _managementServer;
+ protected ObjectName _resourceObjectName;
+
+ protected WsResourceClient _resourceClient;
+ protected MBeanInfo _mbeanInfo;
+
+ /**
+ * Set up fixture for this test case.
+ *
+ * @throws Exception when the test case intialization fails.
+ */
+ protected void setUp() throws Exception
+ {
+ _managementServer = ManagementFactory.getPlatformMBeanServer();
+
+ ServiceGroupClient serviceGroup = getServiceGroupClient();
+ WsResourceClient [] members = serviceGroup.getMembers();
+
+ assertEquals(
+ "No resource has been yet created so how is " +
+ "it possible that service group children list is not empty?",
+ 0,
+ members.length);
+
+ _managementServer.invoke(
+ Names.QPID_EMULATOR_OBJECT_NAME,
+ "createQueue",
+ new Object[]{_resourceObjectName = createResourceName()},
+ new String[]{ObjectName.class.getName()});
+
+ members = serviceGroup.getMembers();
+ assertEquals(
+ "One resource has just been created so " +
+ "I expect to find it on service group children list...",
+ 1,
+ members.length);
+
+ _resourceClient = members[0];
+ _mbeanInfo = _managementServer.getMBeanInfo(_resourceObjectName);
+ }
+
+ /**
+ * Shutdown procedure for this test case.
+ *
+ * @throws Exception when either the server or some resource fails to shutdown.
+ */
+ @Override
+ protected void tearDown() throws Exception
+ {
+ ServiceGroupClient serviceGroup = getServiceGroupClient();
+ WsResourceClient [] members = serviceGroup.getMembers();
+
+ _managementServer.invoke(
+ Names.QPID_EMULATOR_OBJECT_NAME,
+ "unregister",
+ new Object[]{_resourceObjectName},
+ new String[]{ObjectName.class.getName()});
+
+ members = serviceGroup.getMembers();
+
+ assertEquals(
+ "No resource has been yet created so how is it possible that service group children list is not empty?",
+ 0,
+ members.length);
+ }
+
+ /**
+ * Creates a service group client reference.
+ *
+ * @return a service group client reference.
+ */
+ private ServiceGroupClient getServiceGroupClient()
+ {
+ URI address = URI.create(
+ Protocol.DEFAULT_ENDPOINT_URI.replaceFirst("8080",System.getProperty(Names.ADAPTER_PORT_PROPERTY_NAME)));
+ return new ServiceGroupClient(new EndpointReference(address));
+ }
+
+ /**
+ * In order to test the behaviour of the WS-DM adapter, at
+ * least one resource must be created. This is the method that
+ * returns the name (ObjectName on JMX side, Resource-ID on WSDM side)
+ * of that resource
+ *
+ * @return the name of the MBean instance that will be created.
+ * @throws Exception when the name if malformed. Practically never.
+ */
+ private ObjectName createResourceName() throws Exception
+ {
+ return new ObjectName(
+ "Q-MAN:objectId="+UUID.randomUUID()+
+ ", brokerID="+UUID.randomUUID()+
+ ",class=queue"+
+ ",package=org.apache.qpid"+
+ ",name="+System.currentTimeMillis());
+ }
+} \ No newline at end of file
diff --git a/qpid/java/management/client/src/test/java/org/apache/qpid/management/wsdm/GetMultipleResourcePropertiesTestCase.java b/qpid/java/management/client/src/test/java/org/apache/qpid/management/wsdm/GetMultipleResourcePropertiesTestCase.java
new file mode 100644
index 0000000000..d59e7a39e5
--- /dev/null
+++ b/qpid/java/management/client/src/test/java/org/apache/qpid/management/wsdm/GetMultipleResourcePropertiesTestCase.java
@@ -0,0 +1,125 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.qpid.management.wsdm;
+
+import java.util.Date;
+import java.util.UUID;
+
+import javax.management.MBeanAttributeInfo;
+import javax.xml.namespace.QName;
+
+import org.apache.muse.ws.addressing.soap.SoapFault;
+import org.apache.muse.ws.resource.WsrfConstants;
+import org.apache.qpid.management.Names;
+import org.w3c.dom.Element;
+
+/**
+ * Test case for Web Service Resource Properties interfaces.
+ * Those interfaces are defined on http://docs.oasis-open.org/wsrf/wsrf-ws_resource_properties-1.2-spec-os.pdf
+ * (Web Services Resource Properties 1.2 - (WS-ResourceProperties).
+ * For a better explanation see chapter 5 of the specification above.
+ *
+ * @author Andrea Gazzarini
+ */
+public class GetMultipleResourcePropertiesTestCase extends BaseWsDmAdapterTestCase
+{
+ /**
+ * Tests the GetMultipleResourceProperties interface when the request contains
+ * an unknwon target resource.
+ *
+ * <br>precondition : the GetMultipleResourceProperties request contains an unknwon resource.
+ * <br>postcondition : a SoapFault is thrown and the corresponding detail contains an
+ * UnknownResourceFault element.
+ */
+ public void testGetMultipleResourcePropertiesKO_WithUnknownResourceFault() throws Exception
+ {
+ try
+ {
+ _resourceClient.getEndpointReference().removeParameter(Names.RESOURCE_ID_QNAME);
+ _resourceClient.getEndpointReference().addParameter(Names.RESOURCE_ID_QNAME,"lablabalbal");
+
+ _resourceClient.getMultipleResourceProperties(new QName[]{});
+ } catch(SoapFault expected)
+ {
+ assertEquals(
+ WsrfConstants.RESOURCE_UNKNOWN_QNAME.getLocalPart(),
+ expected.getDetail().getLocalName());
+ }
+ }
+
+ /**
+ * Test the WS-RP GetResourceProperties interface of the WS-DM adapter.
+ *
+ * <br>precondition : a ws resource exists and is registered.
+ * <br>postcondition : Properties are correctly returned according to WSRP interface and they (their value)
+ * are matching with corresponding MBean properties.
+ */
+ public void testGetMultipleResourcePropertiesOK() throws Exception
+ {
+ MBeanAttributeInfo [] attributesMetadata = _mbeanInfo.getAttributes();
+ QName[] names = new QName[attributesMetadata.length];
+
+ int index = 0;
+ for (MBeanAttributeInfo attributeMetadata : _mbeanInfo.getAttributes())
+ {
+ QName qname = new QName(Names.NAMESPACE_URI,attributeMetadata.getName(),Names.PREFIX);
+ names[index++] = qname;
+ }
+
+ Element[] properties =_resourceClient.getMultipleResourceProperties(names);
+ for (Element element : properties)
+ {
+ String name = element.getLocalName();
+ Object value = _managementServer.getAttribute(_resourceObjectName, name);
+ if ("Name".equals(name))
+ {
+ assertEquals(
+ value,
+ element.getTextContent());
+ } else if ("Durable".equals(name))
+ {
+ assertEquals(
+ value,
+ Boolean.valueOf(element.getTextContent()));
+ } else if ("ExpireTime".equals(name))
+ {
+ assertEquals(
+ value,
+ new Date(Long.valueOf(element.getTextContent())));
+ } else if ("MsgTotalEnqueues".equals(name))
+ {
+ assertEquals(
+ value,
+ Long.valueOf(element.getTextContent()));
+ } else if ("ConsumerCount".equals(name))
+ {
+ assertEquals(
+ value,
+ Integer.valueOf(element.getTextContent()));
+ }else if ("VhostRef".equals(name))
+ {
+ assertEquals(
+ value,
+ UUID.fromString(element.getTextContent()));
+ }
+ }
+ }
+}
diff --git a/qpid/java/management/client/src/test/java/org/apache/qpid/management/wsdm/GetResourcePropertiesTestCase.java b/qpid/java/management/client/src/test/java/org/apache/qpid/management/wsdm/GetResourcePropertiesTestCase.java
new file mode 100644
index 0000000000..e18e928cf4
--- /dev/null
+++ b/qpid/java/management/client/src/test/java/org/apache/qpid/management/wsdm/GetResourcePropertiesTestCase.java
@@ -0,0 +1,105 @@
+/*
+ *
+ * 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.management.wsdm;
+
+import java.lang.reflect.Array;
+
+import javax.management.MBeanAttributeInfo;
+import javax.xml.namespace.QName;
+
+import org.apache.muse.ws.addressing.soap.SoapFault;
+import org.apache.muse.ws.resource.WsrfConstants;
+import org.apache.qpid.management.Names;
+
+/**
+ * Test case for Web Service Resource Properties interfaces.
+ * Those interfaces are defined on http://docs.oasis-open.org/wsrf/wsrf-ws_resource_properties-1.2-spec-os.pdf
+ * (Web Services Resource Properties 1.2 - (WS-ResourceProperties).
+ * For a better explanation see chapter 5 of the specification above.
+ *
+ * @author Andrea Gazzarini
+ */
+public class GetResourcePropertiesTestCase extends BaseWsDmAdapterTestCase
+{
+
+ /**
+ * Test the WS-RP GetResourceProperty interface of the WS-DM adapter.
+ *
+ * <br>precondition : a ws resource exists and is registered.
+ * <br>postcondition : property values coming from WS-DM resource are the same of the JMX interface.
+ */
+ public void testGetResourcePropertiesOK() throws Exception
+ {
+ MBeanAttributeInfo [] attributesMetadata = _mbeanInfo.getAttributes();
+ for (MBeanAttributeInfo attributeMetadata : attributesMetadata)
+ {
+ String name = attributeMetadata.getName();
+ Object propertyValues = _resourceClient.getPropertyAsObject(
+ new QName(
+ Names.NAMESPACE_URI,
+ name,
+ Names.PREFIX),
+ Class.forName(attributeMetadata.getType()));
+
+ int length = Array.getLength(propertyValues);
+ if (length != 0)
+ {
+ Object propertyValue = Array.get(propertyValues, 0);
+
+ assertEquals(
+ "Comparison failed for property "+name,
+ _managementServer.getAttribute(_resourceObjectName,name),
+ propertyValue);
+ } else {
+ assertNull(
+ String.format(
+ "\"%s\" property value shouldn't be null. Its value is %s",
+ name,
+ _managementServer.getAttribute(_resourceObjectName,name)),
+ _managementServer.getAttribute(_resourceObjectName,name));
+ }
+ }
+ }
+
+ /**
+ * Tests the GetMultipleResourceProperties interface when the request contains
+ * an unknwon target resource.
+ *
+ * <br>precondition : the GetMultipleResourceProperties request contains an unknwon resource.
+ * <br>postcondition : a SoapFault is thrown and the corresponding detail contains an
+ * UnknownResourceFault element.
+ */
+ public void testGetResourcePropertiesKO_WithUnknownResourceFault() throws Exception
+ {
+ try
+ {
+ _resourceClient.getEndpointReference().removeParameter(Names.RESOURCE_ID_QNAME);
+ _resourceClient.getEndpointReference().addParameter(Names.RESOURCE_ID_QNAME,"lablabalbal");
+
+ _resourceClient.getResourceProperty(new QName("a","b","c"));
+ } catch(SoapFault expected)
+ {
+ assertEquals(
+ WsrfConstants.RESOURCE_UNKNOWN_QNAME.getLocalPart(),
+ expected.getDetail().getLocalName());
+ }
+ }
+}
diff --git a/qpid/java/management/client/src/test/java/org/apache/qpid/management/wsdm/GetResourcePropertyDocumentTestCase.java b/qpid/java/management/client/src/test/java/org/apache/qpid/management/wsdm/GetResourcePropertyDocumentTestCase.java
new file mode 100644
index 0000000000..862115f841
--- /dev/null
+++ b/qpid/java/management/client/src/test/java/org/apache/qpid/management/wsdm/GetResourcePropertyDocumentTestCase.java
@@ -0,0 +1,134 @@
+/*
+ *
+ * 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.management.wsdm;
+
+import javax.xml.namespace.QName;
+
+import org.apache.muse.util.xml.XmlUtils;
+import org.apache.muse.ws.addressing.soap.SoapFault;
+import org.apache.muse.ws.resource.WsrfConstants;
+import org.apache.qpid.management.Names;
+import org.w3c.dom.Element;
+
+/**
+ * Test case for Web Service Resource Properties interfaces.
+ * Those interfaces are defined on http://docs.oasis-open.org/wsrf/wsrf-ws_resource_properties-1.2-spec-os.pdf
+ * (Web Services Resource Properties 1.2 - (WS-ResourceProperties).
+ * For a better explanation see chapter 5 of the specification above.
+ *
+ * @author Andrea Gazzarini
+ */
+public class GetResourcePropertyDocumentTestCase extends BaseWsDmAdapterTestCase
+{
+ /**
+ * Tests the GetResourcePropertyDocument interface when the request contains
+ * an unknwon target resource.
+ *
+ * <br>precondition : the GetResourcePropertyDocument contains an unknwon resource.
+ * <br>postcondition : a SoapFault is thrown and the corresponding detail contains an
+ * UnknownResourceFault element.
+ */
+ public void testGetResourcePropertyDocumentKO_WithUnknownResourceFault() throws Exception
+ {
+ try
+ {
+ _resourceClient.getEndpointReference().removeParameter(Names.RESOURCE_ID_QNAME);
+ _resourceClient.getEndpointReference().addParameter(Names.RESOURCE_ID_QNAME,"lablabalbal");
+ _resourceClient.setTrace(true);
+
+ _resourceClient.getResourcePropertyDocument();
+ } catch(SoapFault expected)
+ {
+ assertEquals(
+ WsrfConstants.RESOURCE_UNKNOWN_QNAME.getLocalPart(),
+ expected.getDetail().getLocalName());
+ }
+ }
+
+ /**
+ * Tests the WS-RP PutResourcePropertyDocument interface of the WS-DM adapter.
+ *
+ * <br>precondition : a ws resource exists and is registered.
+ * <br>postcondition : A read / write property is correctly set according to WSRP interface.
+ */
+ public void testGetAndPutResourcePropertyDocumentOK() throws Exception
+ {
+ String expectedMgmtPubIntervalValue = "4321";
+ String propertyName = "MgmtPubInterval";
+
+ Element propertiesDocument = _resourceClient.getResourcePropertyDocument();
+ Element [] properties = XmlUtils.getAllElements(propertiesDocument);
+
+ for (Element element : properties)
+ {
+ if (propertyName.equals(element.getLocalName())) {
+ element.setTextContent(expectedMgmtPubIntervalValue);
+ } else {
+ propertiesDocument.removeChild(element);
+ }
+ }
+
+ _resourceClient.putResourcePropertyDocument(propertiesDocument);
+
+ Element newProperties = _resourceClient.getResourcePropertyDocument();
+
+ Element mgmtPubInterval = XmlUtils.getElement(
+ newProperties, new QName(
+ Names.NAMESPACE_URI,
+ propertyName,
+ Names.PREFIX));
+
+ assertEquals(expectedMgmtPubIntervalValue,mgmtPubInterval.getTextContent());
+ }
+
+ /**
+ * Tests the WS-RP PutResourcePropertyDocument interface of the WS-DM adapter.
+ * Specifically it tries to update the value of a read-only property.
+ *
+ * <br>precondition : a ws resource exists, it is registered and has at least one read-only property.
+ * <br>postcondition : An exception is thrown indicating the failure.
+ */
+ public void testGetAndPutResourcePropertyDocumentKO_WithReadOnlyProperty() throws Exception
+ {
+ String propertyName = "Name";
+
+ Element propertiesDocument = _resourceClient.getResourcePropertyDocument();
+ Element [] properties = XmlUtils.getAllElements(propertiesDocument);
+
+ for (Element element : properties)
+ {
+ if (propertyName.equals(element.getLocalName())) {
+ element.setTextContent("ThisIsTheNewValueOfNameProperty");
+ } else {
+ propertiesDocument.removeChild(element);
+ }
+ }
+
+ try
+ {
+ _resourceClient.putResourcePropertyDocument(propertiesDocument);
+ fail("It's not possible to update the value of a read-only property.");
+ } catch (SoapFault expected)
+ {
+
+ }
+ }
+}
diff --git a/qpid/java/management/client/src/test/java/org/apache/qpid/management/wsdm/MetadataExchangeInterfaceTestCase.java b/qpid/java/management/client/src/test/java/org/apache/qpid/management/wsdm/MetadataExchangeInterfaceTestCase.java
new file mode 100644
index 0000000000..046f2226e6
--- /dev/null
+++ b/qpid/java/management/client/src/test/java/org/apache/qpid/management/wsdm/MetadataExchangeInterfaceTestCase.java
@@ -0,0 +1,169 @@
+/*
+ *
+ * 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.management.wsdm;
+
+import javax.xml.namespace.QName;
+
+import org.apache.muse.core.proxy.ProxyHandler;
+import org.apache.muse.core.proxy.ReflectionProxyHandler;
+import org.apache.muse.util.xml.XmlUtils;
+import org.apache.muse.ws.addressing.soap.SoapFault;
+import org.apache.muse.ws.metadata.WsxConstants;
+import org.apache.muse.ws.resource.WsrfConstants;
+import org.apache.muse.ws.resource.metadata.WsrmdConstants;
+import org.apache.qpid.management.Names;
+import org.w3c.dom.Element;
+
+/**
+ * Test case for QMan metadata exchange interface.
+ *
+ * @author Andrea Gazzarini
+ */
+public class MetadataExchangeInterfaceTestCase extends BaseWsDmAdapterTestCase
+{
+ /**
+ * Test the MetadataExchange interface when the corresponding
+ * request doesn't contain a dialect. According to WS-MetadataExchange specs this should be
+ * intended as a "give-me-all-metadata" for that resource.
+ *
+ * <br>precondition : the GetMetadata request doesn't contain a dialect.
+ * <br>postcondition : the whole metadata document is returned with all metadata .
+ * It will contain both WSDL and RMD.
+ */
+ @SuppressWarnings("unchecked")
+ public void testGetMetadataOK_WithoutDialect() throws Exception
+ {
+ Element[] result = (Element[]) _resourceClient.invoke(
+ getProxyHandler(),
+ new Object[]{""});
+
+ assertEquals(2,result.length);
+
+ Element rmdMetadataSection = result[0];
+ Element wsdlMetadataSection = result[1];
+
+ Element rmd = XmlUtils.getFirstElement(rmdMetadataSection);
+ Element wsdl = XmlUtils.getFirstElement(wsdlMetadataSection);
+
+ assertEquals("MetadataDescriptor",rmd.getLocalName());
+ assertEquals("definitions",wsdl.getLocalName());
+ }
+
+ /**
+ * Test the MetadataExchange interface when the WSDL dialect is specified on the request.
+ *
+ * <br>precondition : the GetMetadata request contains WSDL dialect.
+ * <br>postcondition : the resource WSDL metadata document is returned.
+ */
+ @SuppressWarnings("unchecked")
+ public void testGetMetadataOK_WithWSDLDialect() throws Exception
+ {
+ Element[] result = (Element[]) _resourceClient.invoke(
+ getProxyHandler(),
+ new Object[]{WsxConstants.WSDL_DIALECT});
+
+ assertEquals(1,result.length);
+
+ Element wsdlMetadataSection = result[0];
+
+ Element wsdl = XmlUtils.getFirstElement(wsdlMetadataSection);
+
+ assertEquals("definitions",wsdl.getLocalName());
+ }
+
+ /**
+ * Test the MetadataExchange interface when the RMD dialect is specified on the request.
+ *
+ * <br>precondition : the GetMetadata request contains RMD dialect.
+ * <br>postcondition : the RMD metadata document is returned.
+ */
+ @SuppressWarnings("unchecked")
+ public void testGetMetadataOK_WithRMDDialect() throws Exception
+ {
+ Element[] result = (Element[]) _resourceClient.invoke(
+ getProxyHandler(),
+ new Object[]{WsrmdConstants.NAMESPACE_URI});
+
+ assertEquals(1,result.length);
+
+ Element rmdMetadataSection = result[0];
+
+ Element wsdl = XmlUtils.getFirstElement(rmdMetadataSection);
+
+ assertEquals("MetadataDescriptor",wsdl.getLocalName());
+ }
+
+ /**
+ * Test the MetadataExchange interface with an unknown metadata dialect.
+ *
+ * <br>precondition : the GetMetadata request contains an unknown dialect.
+ * <br>postcondition : the returned metadata section is empty.
+ */
+ @SuppressWarnings("unchecked")
+ public void testGetMetadataKO_WithoutUnknownDialect() throws Exception
+ {
+ Element [] metadata = (Element[]) _resourceClient.invoke(
+ getProxyHandler(),
+ new Object[]{"HopeThisIsAnUnknownDialect"});
+
+ assertEquals(0,metadata.length);
+ }
+
+ /**
+ * Test the MetadataExchange interface with an unknown metadata dialect.
+ *
+ * <br>precondition : the GetMetadata request contains an unknown dialect.
+ * <br>postcondition : the returned metadata section is empty.
+ */
+ @SuppressWarnings("unchecked")
+ public void testGetMetadataKO_WithoutUnknownResourceFault() throws Exception
+ {
+ try
+ {
+ _resourceClient.getEndpointReference().removeParameter(Names.RESOURCE_ID_QNAME);
+ _resourceClient.getEndpointReference().addParameter(Names.RESOURCE_ID_QNAME,"lablabalbal");
+
+ _resourceClient.invoke(getProxyHandler(), new Object[]{""});
+ } catch(SoapFault expected)
+ {
+ assertEquals(
+ WsrfConstants.RESOURCE_UNKNOWN_QNAME.getLocalPart(),
+ expected.getDetail().getLocalName());
+ }
+ }
+
+ /**
+ * Returns a proxy handler used for working with metadata exchange
+ * interface.
+ *
+ * @return a metadata proxy handler.
+ */
+ private ProxyHandler getProxyHandler()
+ {
+ ProxyHandler getMetadataHandler = new ReflectionProxyHandler();
+ getMetadataHandler.setAction("http://schemas.xmlsoap.org/ws/2004/09/mex/GetMetadata");
+ getMetadataHandler.setRequestName(new QName("http://schemas.xmlsoap.org/ws/2004/09/mex", "GetMetadata", "wsx"));
+ getMetadataHandler.setRequestParameterNames(new QName[]{new QName("http://schemas.xmlsoap.org/ws/2004/09/mex", "Dialect", "wsx")});
+ getMetadataHandler.setResponseName(new QName("http://schemas.xmlsoap.org/ws/2004/09/mex", "Metadata", "wsx"));
+ getMetadataHandler.setReturnType(Element[].class);
+ return getMetadataHandler;
+ }
+} \ No newline at end of file
diff --git a/qpid/java/management/client/src/test/java/org/apache/qpid/management/wsdm/OperationInvocationInterfaceTestCase.java b/qpid/java/management/client/src/test/java/org/apache/qpid/management/wsdm/OperationInvocationInterfaceTestCase.java
new file mode 100644
index 0000000000..afc4a62085
--- /dev/null
+++ b/qpid/java/management/client/src/test/java/org/apache/qpid/management/wsdm/OperationInvocationInterfaceTestCase.java
@@ -0,0 +1,580 @@
+/*
+ *
+ * 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.management.wsdm;
+
+import java.lang.reflect.Array;
+import java.lang.reflect.Method;
+import java.net.URI;
+import java.util.Arrays;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.UUID;
+
+import javax.xml.namespace.QName;
+
+import org.apache.muse.core.proxy.ProxyHandler;
+import org.apache.muse.core.proxy.ReflectionProxyHandler;
+import org.apache.muse.ws.addressing.soap.SoapFault;
+import org.apache.qpid.management.Names;
+import org.apache.qpid.management.wsdm.capabilities.Result;
+
+/**
+ * Test case for QMan operation invocation interface.
+ *
+ * @author Andrea Gazzarini
+ */
+public class OperationInvocationInterfaceTestCase extends BaseWsDmAdapterTestCase
+{
+ private Map<String, ProxyHandler> _invocationHandlers = createInvocationHandlers();
+
+ /**
+ * Test operation invocation on WS-Resource.
+ * This method tests the exchange of a byte type array between requestor
+ * and service provider.
+ *
+ * <br>precondition : a WS-Resource exists and is registered and the requested
+ * operation is available on that.
+ * <br>postcondition : invocations are executed successfully, no exception is thrown
+ * and byte array are correctly returned.
+ */
+ @SuppressWarnings("unchecked")
+ public void testOperationInvocationOK_withByteArray() throws Exception
+ {
+ byte [] expectedByteResult = {1,3,4,2,2,44,22,3,3,55,66};
+
+ Object result = _resourceClient.invoke(
+ _invocationHandlers.get("echoWithByteArray"),
+ new Object[]{expectedByteResult});
+
+ Method getOutputParameters = result.getClass().getMethod("getOutputParameters");
+
+ Map<String,Object> out = (Map<String, Object>) getOutputParameters.invoke(result);
+
+ assertEquals("Output parameters must be 1.",1,out.size());
+ assertArrayEquals(expectedByteResult, out.get(byte[].class.getName()));
+ }
+
+ /**
+ * Test a simple operation invocation on a WS-Resource.
+ * This method tests a simple operation without any input and output parameters.
+ *
+ * <br>precondition : a ws resource exists and is registered and the requested operation
+ * is available on that.
+ * <br>postcondition : invocations are executed successfully an no exception is thrown.
+ */
+ @SuppressWarnings("unchecked")
+ public void testSimpleOperationInvocationOK() throws Exception
+ {
+ Object result = _resourceClient.invoke(
+ _invocationHandlers.get("voidWithoutArguments"),
+ null);
+
+ assertNotNull(result);
+ }
+
+ /**
+ * Test a the invocation on a WS-Resource with a method that throws an exception..
+ *
+ * <br>precondition : a ws resource exists and is registered and the requested
+ * operation is available on that.
+ * <br>postcondition : an exception is thrown by the requested method.
+ */
+ @SuppressWarnings("unchecked")
+ public void testInvocationException_OK() throws Exception
+ {
+ try
+ {
+ _resourceClient.invoke(
+ _invocationHandlers.get("throwsException"),
+ null);
+ fail("The requested operation has thrown an exception so a Soap Fault is expected...");
+ } catch(SoapFault expected)
+ {
+ }
+ }
+
+ /**
+ * Test operation invocation on WS-Resource.
+ * This method tests the exchange of UUID type between requestor and service provider.
+ *
+ * <br>precondition : a WS-Resource exists and is registered and the requested operation
+ * is available on that.
+ * <br>postcondition : invocations are executed successfully, no exception is thrown
+ * and parameters are correctly returned.
+ */
+ @SuppressWarnings("unchecked")
+ public void testOperationInvocationOK_withUUID() throws Exception
+ {
+ UUID expectedUuid = UUID.randomUUID();
+
+ Object result = _resourceClient.invoke(
+ _invocationHandlers.get("echoWithUUID"),
+ new Object[]{expectedUuid});
+
+ Method getOutputParameters = result.getClass().getMethod("getOutputParameters");
+
+ Map<String,Object> out = (Map<String, Object>) getOutputParameters.invoke(result);
+
+ assertEquals("Output parameters must be 1.",1,out.size());
+ assertEquals(expectedUuid, out.get("uuid"));
+ }
+
+ /**
+ * Test operation invocation on WS-Resource.
+ * This method tests the exchange of Map type between requestor and service provider.
+ * For this test exchanged arrays contain :
+ *
+ * <br>precondition : a ws resource exists and is registered and the requested
+ * operation is available on that.
+ * <br>postcondition : invocations are executed successfully, no exception is
+ * thrown and parameters are correctly returned.
+ */
+ @SuppressWarnings("unchecked")
+ public void testOperationInvocationOK_withMap() throws Exception
+ {
+ Map<String,Object> expectedMap = new HashMap<String, Object>();
+ expectedMap.put("p1", new Long(1));
+ expectedMap.put("p2", Boolean.TRUE);
+ expectedMap.put("p3", 1234d);
+ expectedMap.put("p4", 11.2f);
+ expectedMap.put("p5", 1272);
+ expectedMap.put("p6", (short)12);
+ expectedMap.put("p7", "aString");
+ expectedMap.put("p8", "http://qpid.apache.org");
+ expectedMap.put("p9", new Date(12383137128L));
+ expectedMap.put("p10", new byte[]{1,2,2,3,3,4});
+
+ Object result = _resourceClient.invoke(
+ _invocationHandlers.get("echoWithMap"),
+ new Object[]{expectedMap});
+
+ Method getOutputParameters = result.getClass().getMethod("getOutputParameters");
+
+ Map<String,Object> out = (Map<String, Object>) ((Map<String, Object>) getOutputParameters.invoke(result)).get("map");
+
+ assertEquals("Output parameters must be 10.",10,out.size());
+ assertEquals(expectedMap.get("p1"),out.get("p1"));
+ assertEquals(expectedMap.get("p2"),out.get("p2"));
+ assertEquals(expectedMap.get("p3"),out.get("p3"));
+ assertEquals(expectedMap.get("p4"),out.get("p4"));
+ assertEquals(expectedMap.get("p5"),out.get("p5"));
+ assertEquals(expectedMap.get("p6"),out.get("p6"));
+ assertEquals(expectedMap.get("p7"),out.get("p7"));
+ assertEquals(expectedMap.get("p8"),out.get("p8"));
+ assertEquals(expectedMap.get("p9"),out.get("p9"));
+ assertTrue( Arrays.equals((byte[])expectedMap.get("p10"),(byte[])out.get("p10")));
+ }
+
+ /**
+ * Test operation invocation on WS-Resource.
+ * This method tests the exchange of simple types between requestor and
+ * service provider.
+ *
+ * With simple types we mean :
+ *
+ * <ul>
+ * <li>java.lang.Long / long (xsd:long)
+ * <li>java.lang.Integer / int (xsd:int / xsd:integer)
+ * <li>java.lang.Double/ double (xsd:double)
+ * <li>java.lang.Float / float (xsd:float)
+ * <li>java.lang.Short / short (xsd:short)
+ * <li>java.lang.Boolean / boolean (xsd:boolean)
+ * <li>java.lang.String (xsd:string)
+ * <li>java.net.URI (xsd:anyURI)
+ * <li>java.util.Date(xsd:dateTime)
+ * </ul>
+ *
+ * <br>precondition : a ws resource exists and is registered and the requested operation is
+ * available on that.
+ * <br>postcondition : invocations are executed successfully, no exception is thrown and
+ * parameters are correctly returned.
+ */
+ @SuppressWarnings("unchecked")
+ public void testOperationInvocationOK_withSimpleTypes() throws Exception
+ {
+ Long expectedLongResult = new Long(1373);
+ Boolean expectedBooleanResult = Boolean.TRUE;
+ Double expectedDoubleResult = new Double(12763.44);
+ Float expectedFloatResult = new Float(2727.233f);
+ Integer expectedIntegerResult = new Integer(28292);
+ Short expectedShortResult = new Short((short)227);
+ String expectedStringResult = "expectedStringResult";
+ URI expectedUriResult = URI.create("http://qpid.apache.org/");
+ Date expectedDateResult = new Date();
+
+ Object result = _resourceClient.invoke(
+ _invocationHandlers.get("echoWithSimpleTypes"),
+ new Object[]{
+ expectedLongResult,
+ expectedBooleanResult,
+ expectedDoubleResult,
+ expectedFloatResult,
+ expectedIntegerResult,
+ expectedShortResult,
+ expectedStringResult,
+ expectedUriResult,
+ expectedDateResult});
+
+ Method getOutputParameters = result.getClass().getMethod("getOutputParameters");
+ Map<String,Object> out = (Map<String, Object>) getOutputParameters.invoke(result);
+
+ assertEquals("Output parameters must be 9.",9,out.size());
+ assertTrue("Long output parameter not found on result object.",out.containsValue(expectedLongResult));
+ assertTrue("Boolean output parameter not found on result object.",out.containsValue(expectedBooleanResult));
+ assertTrue("Double output parameter not found on result object.",out.containsValue(expectedDoubleResult));
+ assertTrue("Float output parameter not found on result object.",out.containsValue(expectedFloatResult));
+ assertTrue("Integer output parameter not found on result object.",out.containsValue(expectedIntegerResult));
+ assertTrue("Short output parameter not found on result object.",out.containsValue(expectedShortResult));
+ assertTrue("String output parameter not found on result object.",out.containsValue(expectedStringResult));
+ assertTrue("URI output parameter not found on result object.",out.containsValue(expectedUriResult));
+ assertTrue("Date output parameter not found on result object.",out.containsValue(expectedDateResult));
+ }
+
+ /**
+ * Test operation invocation on WS-Resource.
+ * This method tests the exchange of arrays between requestor and service provider.
+ * For this test exchanged arrays contain :
+ *
+ * <ul>
+ * <li>java.lang.Long (xsd:long)
+ * <li>java.lang.Integer (xsd:int / xsd:integer)
+ * <li>java.lang.Double (xsd:double)
+ * <li>java.lang.Float (xsd:float)
+ * <li>java.lang.Short (xsd:short)
+ * <li>java.lang.Boolean (xsd:boolean)
+ * <li>java.lang.String (xsd:string)
+ * <li>java.net.URI (xsd:anyURI)
+ * <li>java.util.Date(xsd:dateTime)
+ * </ul>
+ *
+ * <br>precondition : a ws resource exists and is registered and the requested operation is available on that.
+ * <br>postcondition : invocations are executed successfully, no exception is thrown and parameters are correctly returned.
+ */
+ @SuppressWarnings("unchecked")
+ public void testOperationInvocationOK_withWrapperArrays() throws Exception
+ {
+ Long [] expectedLongResult = {new Long(2),new Long(1),new Long(3),new Long(4)};
+ Boolean [] expectedBooleanResult = { Boolean.TRUE,Boolean.FALSE,Boolean.FALSE};
+ Double [] expectedDoubleResult = {12763.44d,2832.33d,2292.33d,22293.22d};
+ Float [] expectedFloatResult = {2727.233f,1f,2f,4f,5.4f,33.2f};
+ Integer [] expectedIntegerResult = {1,2,3,4,55,66,77,88,99};
+ Short [] expectedShortResult = {(short)227,(short)23,(short)9};
+ String [] expectedStringResult = {"s1","s2","s333","s4"};
+ URI [] expectedUriResult = {
+ URI.create("http://qpid.apache.org/"),
+ URI.create("http://www.apache.org"),
+ URI.create("http://projects.apache.org")};
+
+ Date [] expectedDateResult = {
+ new Date(),
+ new Date(38211897),
+ new Date(903820382)};
+
+ Object result = _resourceClient.invoke(
+ _invocationHandlers.get("echoWithArrays"),
+ new Object[]{
+ expectedLongResult,
+ expectedBooleanResult,
+ expectedDoubleResult,
+ expectedFloatResult,
+ expectedIntegerResult,
+ expectedShortResult,
+ expectedStringResult,
+ expectedUriResult,
+ expectedDateResult});
+
+ Method getOutputParameters = result.getClass().getMethod("getOutputParameters");
+ Map<String,Object> out = (Map<String, Object>) getOutputParameters.invoke(result);
+
+ assertEquals("Output parameters must be 9.",9,out.size());
+ assertTrue("Long array doesn't match.",Arrays.equals(expectedLongResult, (Long[])out.get(Long.class.getName())));
+ assertTrue("Boolean array doesn't match.",Arrays.equals(expectedBooleanResult, (Boolean[])out.get(Boolean.class.getName())));
+ assertTrue("Double array doesn't match.",Arrays.equals(expectedDoubleResult, (Double[])out.get(Double.class.getName())));
+ assertTrue("Float array doesn't match.",Arrays.equals(expectedFloatResult, (Float[])out.get(Float.class.getName())));
+ assertTrue("Integer array doesn't match.", Arrays.equals(expectedIntegerResult, (Integer[])out.get(Integer.class.getName())));
+ assertTrue("Short array doesn't match.",Arrays.equals(expectedShortResult, (Short[])out.get(Short.class.getName())));
+ assertTrue("String array doesn't match.",Arrays.equals(expectedStringResult, (String[])out.get(String.class.getName())));
+ assertTrue("URI array doesn't match.",Arrays.equals(expectedUriResult, (URI[])out.get(URI.class.getName())));
+ assertTrue("Date array doesn't match.",Arrays.equals(expectedDateResult, (Date[])out.get(Date.class.getName())));
+ }
+
+ /**
+ * Test operation invocation on WS-Resource.
+ * This method tests the exchange of primitive type arrays between requestor and service provider.
+ * NOte that even the sent array contain primtiive type QMan deals only with objects so in the result
+ * object you will find the corresponding wrapper types.
+ *
+ * For this test exchanged arrays contain :
+ *
+ * <ul>
+ * <li>java.lang.Long / long (xsd:long)
+ * <li>java.lang.Integer / int (xsd:int / xsd:integer)
+ * <li>java.lang.Double/ double (xsd:double)
+ * <li>java.lang.Float / float (xsd:float)
+ * <li>java.lang.Short / short (xsd:short)
+ * <li>java.lang.Boolean / boolean (xsd:boolean)
+ * </ul>
+ *
+ * <br>precondition : a ws resource exists and is registered and the requested operation is available on that.
+ * <br>postcondition : invocations are executed successfully, no exception is thrown and parameters are correctly returned.
+ */
+ @SuppressWarnings("unchecked")
+ public void testOperationInvocationOK_withPrimitiveArrays() throws Exception
+ {
+ long [] expectedLongResult = {1L,2L,3L,4L};
+ boolean [] expectedBooleanResult = { true,false,false};
+ double [] expectedDoubleResult = {12763.44d,2832.33d,2292.33d,22293.22d};
+ float [] expectedFloatResult = {2727.233f,1f,2f,4f,5.4f,33.2f};
+ int [] expectedIntegerResult = {1,2,3,4,55,66,77,88,99};
+ short [] expectedShortResult = {(short)227,(short)23,(short)9};
+
+ Object result = _resourceClient.invoke(
+ _invocationHandlers.get("echoWithSimpleTypeArrays"),
+ new Object[]{
+ expectedLongResult,
+ expectedBooleanResult,
+ expectedDoubleResult,
+ expectedFloatResult,
+ expectedIntegerResult,
+ expectedShortResult});
+
+ Method getOutputParameters = result.getClass().getMethod("getOutputParameters");
+ Map<String,Object> out = (Map<String, Object>) getOutputParameters.invoke(result);
+
+ assertEquals("Output parameters must be 6.",6,out.size());
+ assertArrayEquals(expectedLongResult, out.get(long.class.getName()));
+ assertArrayEquals(expectedBooleanResult, out.get(boolean.class.getName()));
+ assertArrayEquals(expectedDoubleResult, out.get(double.class.getName()));
+ assertArrayEquals(expectedFloatResult, out.get(float.class.getName()));
+ assertArrayEquals(expectedIntegerResult, out.get(int.class.getName()));
+ assertArrayEquals(expectedShortResult, out.get(short.class.getName()));
+ }
+
+ /**
+ * Internal method used for array comparison using reflection.
+ *
+ * @param expectedArray the expected array.
+ * @param resultArray the array that must match the expected one.
+ */
+ private void assertArrayEquals(Object expectedArray, Object resultArray)
+ {
+ int expectedArrayLength = Array.getLength(expectedArray);
+ int resultArrayLength = Array.getLength(resultArray);
+
+ assertEquals(expectedArrayLength,resultArrayLength);
+
+ for (int index = 0; index < expectedArrayLength; index++)
+ {
+ Object expected = Array.get(expectedArray, index);
+ Object result = Array.get(resultArray, index);
+
+ assertEquals(expected,result);
+ }
+ }
+
+ private Map<String,ProxyHandler> createInvocationHandlers()
+ {
+ Map<String, ProxyHandler> handlers = new HashMap<String, ProxyHandler>();
+
+ ProxyHandler handler = new ReflectionProxyHandler();
+ handler.setAction(Names.NAMESPACE_URI+"/"+"voidWithoutArguments");
+ handler.setRequestName(
+ new QName(
+ Names.NAMESPACE_URI,
+ "voidWithoutArgumentsRequest",
+ Names.PREFIX));
+ handler.setRequestParameterNames(new QName[]{});
+ handler.setResponseName(
+ new QName(
+ Names.NAMESPACE_URI,
+ "voidWithoutArgumentsResponse",
+ Names.PREFIX));
+ handler.setReturnType(Result.class);
+
+ ProxyHandler exceptionHandler = new ReflectionProxyHandler();
+ exceptionHandler.setAction(Names.NAMESPACE_URI+"/"+"throwsException");
+ exceptionHandler.setRequestName(
+ new QName(
+ Names.NAMESPACE_URI,
+ "throwsExceptionRequest",
+ Names.PREFIX));
+
+ exceptionHandler.setRequestParameterNames(new QName[]{});
+ exceptionHandler.setResponseName(
+ new QName(
+ Names.NAMESPACE_URI,
+ "throwsExceptionResponse",
+ Names.PREFIX));
+
+ exceptionHandler.setReturnType(Result.class);
+
+ ProxyHandler echoWithWrapperTypesHandler = new ReflectionProxyHandler();
+ echoWithWrapperTypesHandler.setAction(Names.NAMESPACE_URI+"/"+"echoWithSimpleTypes");
+ echoWithWrapperTypesHandler.setRequestName(
+ new QName(
+ Names.NAMESPACE_URI,
+ "echoWithSimpleTypesRequest",
+ Names.PREFIX));
+
+ echoWithWrapperTypesHandler.setRequestParameterNames(new QName[]{
+ new QName(Names.NAMESPACE_URI,"p1",Names.PREFIX),
+ new QName(Names.NAMESPACE_URI,"p2",Names.PREFIX),
+ new QName(Names.NAMESPACE_URI,"p3",Names.PREFIX),
+ new QName(Names.NAMESPACE_URI,"p4",Names.PREFIX),
+ new QName(Names.NAMESPACE_URI,"p5",Names.PREFIX),
+ new QName(Names.NAMESPACE_URI,"p6",Names.PREFIX),
+ new QName(Names.NAMESPACE_URI,"p7",Names.PREFIX),
+ new QName(Names.NAMESPACE_URI,"p8",Names.PREFIX),
+ new QName(Names.NAMESPACE_URI,"p9",Names.PREFIX),
+ });
+
+ echoWithWrapperTypesHandler.setResponseName(
+ new QName(
+ Names.NAMESPACE_URI,
+ "echoWithSimpleTypesResponse",
+ Names.PREFIX));
+
+ echoWithWrapperTypesHandler.setReturnType(Result.class);
+
+ ProxyHandler echoWithArrayOfWrapperTypes = new ReflectionProxyHandler();
+ echoWithArrayOfWrapperTypes.setAction(Names.NAMESPACE_URI+"/"+"echoWithArrays");
+ echoWithArrayOfWrapperTypes.setRequestName(
+ new QName(
+ Names.NAMESPACE_URI,
+ "echoWithArraysRequest",
+ Names.PREFIX));
+
+ echoWithArrayOfWrapperTypes.setRequestParameterNames(new QName[]{
+ new QName(Names.NAMESPACE_URI,"p1",Names.PREFIX),
+ new QName(Names.NAMESPACE_URI,"p2",Names.PREFIX),
+ new QName(Names.NAMESPACE_URI,"p3",Names.PREFIX),
+ new QName(Names.NAMESPACE_URI,"p4",Names.PREFIX),
+ new QName(Names.NAMESPACE_URI,"p5",Names.PREFIX),
+ new QName(Names.NAMESPACE_URI,"p6",Names.PREFIX),
+ new QName(Names.NAMESPACE_URI,"p7",Names.PREFIX),
+ new QName(Names.NAMESPACE_URI,"p8",Names.PREFIX),
+ new QName(Names.NAMESPACE_URI,"p9",Names.PREFIX),
+ });
+
+ echoWithArrayOfWrapperTypes.setResponseName(
+ new QName(
+ Names.NAMESPACE_URI,
+ "echoWithArraysResponse",
+ Names.PREFIX));
+
+ echoWithArrayOfWrapperTypes.setReturnType(Result.class);
+
+ ProxyHandler echoWithArrayOfPrimitiveTypes = new ReflectionProxyHandler();
+ echoWithArrayOfPrimitiveTypes.setAction(Names.NAMESPACE_URI+"/"+"echoWithSimpleTypeArrays");
+ echoWithArrayOfPrimitiveTypes.setRequestName(
+ new QName(
+ Names.NAMESPACE_URI,
+ "echoWithSimpleTypeArraysRequest",
+ Names.PREFIX));
+
+ echoWithArrayOfPrimitiveTypes.setRequestParameterNames(new QName[]{
+ new QName(Names.NAMESPACE_URI,"p1",Names.PREFIX),
+ new QName(Names.NAMESPACE_URI,"p2",Names.PREFIX),
+ new QName(Names.NAMESPACE_URI,"p3",Names.PREFIX),
+ new QName(Names.NAMESPACE_URI,"p4",Names.PREFIX),
+ new QName(Names.NAMESPACE_URI,"p5",Names.PREFIX),
+ new QName(Names.NAMESPACE_URI,"p6",Names.PREFIX)});
+
+ echoWithArrayOfPrimitiveTypes.setResponseName(
+ new QName(
+ Names.NAMESPACE_URI,
+ "echoWithSimpleTypeArraysResponse",
+ Names.PREFIX));
+
+ echoWithArrayOfPrimitiveTypes.setReturnType(Result.class);
+
+ ProxyHandler echoWithByteArray = new EnhancedReflectionProxyHandler();
+ echoWithByteArray.setAction(Names.NAMESPACE_URI+"/"+"echoWithByteArray");
+ echoWithByteArray.setRequestName(
+ new QName(
+ Names.NAMESPACE_URI,
+ "echoWithByteArrayRequest",
+ Names.PREFIX));
+
+ echoWithByteArray.setRequestParameterNames(
+ new QName[]{
+ new QName(Names.NAMESPACE_URI,"p1",Names.PREFIX)});
+
+ echoWithByteArray.setResponseName(
+ new QName(
+ Names.NAMESPACE_URI,
+ "echoWithByteArrayResponse",
+ Names.PREFIX));
+
+ echoWithByteArray.setReturnType(Result.class);
+
+ ProxyHandler echoWithUUID = new EnhancedReflectionProxyHandler();
+ echoWithUUID.setAction(Names.NAMESPACE_URI+"/"+"echoWithUUID");
+ echoWithUUID.setRequestName(
+ new QName(
+ Names.NAMESPACE_URI,
+ "echoWithUUIDRequest",
+ Names.PREFIX));
+
+ echoWithUUID.setRequestParameterNames(
+ new QName[]{
+ new QName(Names.NAMESPACE_URI,"p1",Names.PREFIX)});
+
+ echoWithUUID.setResponseName(
+ new QName(
+ Names.NAMESPACE_URI,
+ "echoWithUUIDResponse",
+ Names.PREFIX));
+
+ echoWithUUID.setReturnType(Result.class);
+
+ ProxyHandler echoWithMap = new EnhancedReflectionProxyHandler();
+ echoWithMap.setAction(Names.NAMESPACE_URI+"/"+"echoWithMap");
+ echoWithMap.setRequestName(
+ new QName(
+ Names.NAMESPACE_URI,
+ "echoWithMapRequest",
+ Names.PREFIX));
+
+ echoWithMap.setRequestParameterNames(
+ new QName[]{
+ new QName(Names.NAMESPACE_URI,"p1",Names.PREFIX)});
+
+ echoWithMap.setResponseName(
+ new QName(
+ Names.NAMESPACE_URI,
+ "echoWithMapResponse",
+ Names.PREFIX));
+
+ echoWithMap.setReturnType(Result.class);
+
+ handlers.put("voidWithoutArguments",handler);
+ handlers.put("echoWithSimpleTypes",echoWithWrapperTypesHandler);
+ handlers.put("echoWithArrays",echoWithArrayOfWrapperTypes);
+ handlers.put("echoWithSimpleTypeArrays", echoWithArrayOfPrimitiveTypes);
+ handlers.put("echoWithByteArray", echoWithByteArray);
+ handlers.put("echoWithUUID", echoWithUUID);
+ handlers.put("echoWithMap", echoWithMap);
+ handlers.put("throwsException",exceptionHandler);
+ return handlers;
+ }
+} \ No newline at end of file
diff --git a/qpid/java/management/client/src/test/java/org/apache/qpid/management/wsdm/SetResourcePropertiesTestCase.java b/qpid/java/management/client/src/test/java/org/apache/qpid/management/wsdm/SetResourcePropertiesTestCase.java
new file mode 100644
index 0000000000..87f8905e01
--- /dev/null
+++ b/qpid/java/management/client/src/test/java/org/apache/qpid/management/wsdm/SetResourcePropertiesTestCase.java
@@ -0,0 +1,219 @@
+/*
+ *
+ * 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.management.wsdm;
+
+import java.lang.reflect.Array;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.UUID;
+
+import javax.management.MBeanAttributeInfo;
+import javax.xml.namespace.QName;
+
+import org.apache.muse.ws.addressing.soap.SoapFault;
+import org.apache.muse.ws.resource.WsrfConstants;
+import org.apache.qpid.management.Names;
+
+/**
+ * Test case for Set Resource Properties interfaces.
+ *
+ * @author Andrea Gazzarini
+ */
+public class SetResourcePropertiesTestCase extends BaseWsDmAdapterTestCase
+{
+ /**
+ * Test the WS-RP SetResourceProperty interface of the WS-DM adapter.
+ *
+ * <br>precondition : a WS-Resource exists and is registered.
+ * <br>postcondition : property values are correctly updated on the target WS-Resource..
+ */
+ public void testSetResourcePropertiesOK() throws Exception
+ {
+ Map<String, Object> sampleMap = new HashMap<String, Object>();
+ sampleMap.put("Key1", "BLABALABLABALBAL");
+ sampleMap.put("Key2", 182838484l);
+ sampleMap.put("Key3", -928376362);
+ sampleMap.put("Key4", 23762736276.33D);
+ sampleMap.put("Key4", 2327363.2F);
+
+ Map<String, Object> sampleValues = new HashMap<String, Object>();
+ sampleValues.put(String.class.getName(),"SAMPLE_STRING");
+ sampleValues.put(UUID.class.getName(),UUID.randomUUID());
+ sampleValues.put(Boolean.class.getName(),Boolean.FALSE);
+ sampleValues.put(Map.class.getName(),sampleMap);
+ sampleValues.put(Long.class.getName(),283781273L);
+ sampleValues.put(Integer.class.getName(),12727);
+ sampleValues.put(Short.class.getName(),new Short((short)22));
+ sampleValues.put(Date.class.getName(),new Date());
+
+ MBeanAttributeInfo [] attributesMetadata = _mbeanInfo.getAttributes();
+ boolean atLeastThereIsOneWritableProperty = false;
+
+ for (MBeanAttributeInfo attributeMetadata : attributesMetadata)
+ {
+ String name = attributeMetadata.getName();
+
+ if (attributeMetadata.isWritable())
+ {
+ atLeastThereIsOneWritableProperty = true;
+ Object sampleValue = sampleValues.get(attributeMetadata.getType());
+ Object []values = new Object[]{sampleValue};
+
+ Object result = _managementServer.getAttribute(_resourceObjectName, name);
+ if (result == null)
+ {
+ _resourceClient.insertResourceProperty(
+ new QName(
+ Names.NAMESPACE_URI,
+ name,
+ Names.PREFIX),
+ values);
+ } else
+ {
+ _resourceClient.updateResourceProperty(
+ new QName(
+ Names.NAMESPACE_URI,
+ name,
+ Names.PREFIX),
+ values);
+ }
+
+ Object propertyValues = _resourceClient.getPropertyAsObject(
+ new QName(
+ Names.NAMESPACE_URI,
+ name,
+ Names.PREFIX),
+ Class.forName(attributeMetadata.getType()));
+ int length = Array.getLength(propertyValues);
+ if (length != 0)
+ {
+ Object propertyValue = Array.get(propertyValues, 0);
+
+ assertEquals(
+ "Comparison failed for property "+name,
+ sampleValue,
+ propertyValue);
+ } else {
+ assertNull(
+ String.format(
+ "\"%s\" property value shouldn't be null. Its value is %s",
+ name,
+ _managementServer.getAttribute(_resourceObjectName,name)),
+ sampleValue);
+ }
+ }
+ }
+ assertTrue(
+ "It's not possibile to run successfully this test case if " +
+ "the target WS-Resource has no at least one writable property",
+ atLeastThereIsOneWritableProperty);
+ }
+
+ /**
+ * Test the WS-RP SetResourceProperty interface of the WS-DM adapter when the
+ * target property is null.
+ * According to WS-RP specs this operation is not allowed because in this case a SetResourceProperty with an "Insert"
+ * message should be sent in order to initialize the property.
+ *
+ * <br>precondition : a ws resource exists and is registered. The value of the target property is null.
+ * <br>postcondition : a Soap fault is received indicating the failuire.
+ */
+ public void testSetResourcePropertiesKO() throws Exception
+ {
+ Object typePropertyValue = _managementServer.getAttribute(_resourceObjectName, "Type");
+ assertNull(typePropertyValue);
+
+ try
+ {
+ _resourceClient.updateResourceProperty(
+ new QName(
+ Names.NAMESPACE_URI,
+ "Type",
+ Names.PREFIX),
+ new Object[]{"sampleValue"});
+ fail(
+ "If the property is null on the target ws resource, according " +
+ "to WS-RP specs, an update of its value is not possible.");
+ } catch(SoapFault expected)
+ {
+
+ }
+ }
+
+ /**
+ * Tests the SetResourceProperties (update) interface when the request contains
+ * an unknwon target resource.
+ *
+ * <br>precondition : the SetResourceProperties contains an unknwon resource.
+ * <br>postcondition : a SoapFault is thrown and the corresponding detail contains an
+ * UnknownResourceFault element.
+ */
+ public void testUpdateResourcePropertiesKO_WithUnknownResourceFault() throws Exception
+ {
+ try
+ {
+ _resourceClient.getEndpointReference().removeParameter(Names.RESOURCE_ID_QNAME);
+ _resourceClient.getEndpointReference().addParameter(Names.RESOURCE_ID_QNAME,"lablabalbal");
+
+ _resourceClient.updateResourceProperty(
+ new QName(
+ Names.NAMESPACE_URI,
+ "Type",
+ Names.PREFIX),
+ new Object[]{"sampleValue"});
+ } catch(SoapFault expected)
+ {
+ assertEquals(
+ WsrfConstants.RESOURCE_UNKNOWN_QNAME.getLocalPart(),
+ expected.getDetail().getLocalName());
+ }
+ }
+
+ /**
+ * Tests the SetResourceProperties (insert) interface when the request contains
+ * an unknwon target resource.
+ *
+ * <br>precondition : the SetResourceProperties contains an unknwon resource.
+ * <br>postcondition : a SoapFault is thrown and the corresponding detail contains an
+ * UnknownResourceFault element.
+ */
+ public void testInsertResourcePropertiesKO_WithUnknownResourceFault() throws Exception
+ {
+ try
+ {
+ _resourceClient.getEndpointReference().removeParameter(Names.RESOURCE_ID_QNAME);
+ _resourceClient.getEndpointReference().addParameter(Names.RESOURCE_ID_QNAME,"lablabalbal");
+
+ _resourceClient.insertResourceProperty(
+ new QName(
+ Names.NAMESPACE_URI,
+ "Type",
+ Names.PREFIX),
+ new Object[]{"sampleValue"});
+ } catch(SoapFault expected)
+ {
+ assertEquals(
+ WsrfConstants.RESOURCE_UNKNOWN_QNAME.getLocalPart(),
+ expected.getDetail().getLocalName());
+ }
+ }
+}
diff --git a/qpid/java/management/client/src/test/java/org/apache/qpid/management/wsdm/WsDmAdapterTest.java b/qpid/java/management/client/src/test/java/org/apache/qpid/management/wsdm/WsDmAdapterTest.java
index 6644b5ae25..07395b3be9 100644
--- a/qpid/java/management/client/src/test/java/org/apache/qpid/management/wsdm/WsDmAdapterTest.java
+++ b/qpid/java/management/client/src/test/java/org/apache/qpid/management/wsdm/WsDmAdapterTest.java
@@ -21,36 +21,13 @@
package org.apache.qpid.management.wsdm;
import java.io.IOException;
-import java.lang.management.ManagementFactory;
-import java.lang.reflect.Array;
-import java.lang.reflect.Method;
import java.net.ServerSocket;
-import java.net.URI;
-import java.util.Arrays;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
-import javax.management.MBeanAttributeInfo;
-import javax.management.MBeanInfo;
-import javax.management.MBeanServer;
-import javax.management.ObjectName;
-import javax.xml.namespace.QName;
-
-import junit.extensions.TestSetup;
-import junit.framework.Test;
-import junit.framework.TestCase;
-import junit.framework.TestSuite;
-
-import org.apache.muse.core.proxy.ProxyHandler;
-import org.apache.muse.core.proxy.ReflectionProxyHandler;
import org.apache.muse.core.serializer.SerializerRegistry;
-import org.apache.muse.util.xml.XmlUtils;
-import org.apache.muse.ws.addressing.EndpointReference;
-import org.apache.muse.ws.addressing.soap.SoapFault;
-import org.apache.muse.ws.resource.remote.WsResourceClient;
-import org.apache.muse.ws.resource.sg.remote.ServiceGroupClient;
import org.apache.qpid.management.Names;
import org.apache.qpid.management.Protocol;
import org.apache.qpid.management.wsdm.capabilities.Result;
@@ -61,26 +38,14 @@ import org.apache.qpid.management.wsdm.muse.serializer.ObjectSerializer;
import org.apache.qpid.management.wsdm.muse.serializer.UUIDSerializer;
import org.mortbay.component.LifeCycle;
import org.mortbay.component.LifeCycle.Listener;
-import org.w3c.dom.Element;
-/**
- * Test case for WS-Resource lifecycle management.
- *
- * @author Andrea Gazzarini
- */
-public class WsDmAdapterTest extends TestCase {
-
- private MBeanServer _managementServer;
- private ObjectName _resourceObjectName;
-
- private WsResourceClient _resourceClient;
- private MBeanInfo _mbeanInfo;
-
- private Map<String, ProxyHandler> _invocationHandlers = createInvocationHandlers();
- final Long retCodeOk = new Long(0);
+import junit.extensions.TestSetup;
+import junit.framework.Test;
+import junit.framework.TestSuite;
+
+public class WsDmAdapterTest
+{
- private static ServerThread _server;
-
/**
* Test case wide set up.
* Provides Server startup & shutdown global procedure.
@@ -102,6 +67,7 @@ public class WsDmAdapterTest extends TestCase {
}
};
+ private ServerThread _server;
/**
* Builds a new test setup with for the given test.
@@ -153,927 +119,30 @@ public class WsDmAdapterTest extends TestCase {
};
/**
- * Set up fixture for this test case.
- *
- * @throws Exception when the test case intialization fails.
- */
- protected void setUp() throws Exception
- {
- _managementServer = ManagementFactory.getPlatformMBeanServer();
-
- ServiceGroupClient serviceGroup = getServiceGroupClient();
- WsResourceClient [] members = serviceGroup.getMembers();
-
- assertEquals(
- "No resource has been yet created so how is " +
- "it possible that service group children list is not empty?",
- 0,
- members.length);
-
- _managementServer.invoke(
- Names.QPID_EMULATOR_OBJECT_NAME,
- "createQueue", new Object[]{_resourceObjectName = createResourceName()},
- new String[]{ObjectName.class.getName()});
-
- members = serviceGroup.getMembers();
- assertEquals(
- "One resource has just been created so " +
- "I expect to find it on service group children list...",
- 1,
- members.length);
-
- _resourceClient = members[0];
- _mbeanInfo = _managementServer.getMBeanInfo(_resourceObjectName);
- }
-
- /**
- * Shutdown procedure for this test case.
- *
- * @throws Exception when either the server or some resource fails to shutdown.
- */
- @Override
- protected void tearDown() throws Exception
- {
- ServiceGroupClient serviceGroup = getServiceGroupClient();
- WsResourceClient [] members = serviceGroup.getMembers();
-
- _managementServer.invoke(
- Names.QPID_EMULATOR_OBJECT_NAME,
- "unregister",
- new Object[]{_resourceObjectName},
- new String[]{ObjectName.class.getName()});
-
- members = serviceGroup.getMembers();
-
- assertEquals(
- "No resource has been yet created so how is it possible that service group children list is not empty?",
- 0,
- members.length);
- }
-
- /**
- * Test the WS-RP GetResourceProperty interface of the WS-DM adapter.
- *
- * <br>precondition : a ws resource exists and is registered.
- * <br>postcondition : property values coming from WS-DM resource are the same of the JMX interface.
- */
- public void testGetResourcePropertiesOK() throws Exception
- {
- MBeanAttributeInfo [] attributesMetadata = _mbeanInfo.getAttributes();
- for (MBeanAttributeInfo attributeMetadata : attributesMetadata)
- {
- String name = attributeMetadata.getName();
- Object propertyValues = _resourceClient.getPropertyAsObject(
- new QName(
- Names.NAMESPACE_URI,
- name,
- Names.PREFIX),
- Class.forName(attributeMetadata.getType()));
-
- int length = Array.getLength(propertyValues);
- if (length != 0)
- {
- Object propertyValue = Array.get(propertyValues, 0);
-
- assertEquals(
- "Comparison failed for property "+name,
- _managementServer.getAttribute(_resourceObjectName,name),
- propertyValue);
- } else {
- assertNull(
- String.format(
- "\"%s\" property value shouldn't be null. Its value is %s",
- name,
- _managementServer.getAttribute(_resourceObjectName,name)),
- _managementServer.getAttribute(_resourceObjectName,name));
- }
- }
- }
-
- /**
- * Test the WS-RP SetResourceProperty interface of the WS-DM adapter.
+ * Gets the test suite composition.
*
- * <br>precondition : a WS-Resource exists and is registered.
- * <br>postcondition : property values are correctly updated on the target WS-Resource..
+ * @return the test suite composition.
*/
- public void testSetResourcePropertiesOK() throws Exception
+ public static Test suite()
{
- Map<String, Object> sampleMap = new HashMap<String, Object>();
- sampleMap.put("Key1", "BLABALABLABALBAL");
- sampleMap.put("Key2", 182838484l);
- sampleMap.put("Key3", -928376362);
- sampleMap.put("Key4", 23762736276.33D);
- sampleMap.put("Key4", 2327363.2F);
-
- Map<String, Object> sampleValues = new HashMap<String, Object>();
- sampleValues.put(String.class.getName(),"SAMPLE_STRING");
- sampleValues.put(UUID.class.getName(),UUID.randomUUID());
- sampleValues.put(Boolean.class.getName(),Boolean.FALSE);
- sampleValues.put(Map.class.getName(),sampleMap);
- sampleValues.put(Long.class.getName(),283781273L);
- sampleValues.put(Integer.class.getName(),12727);
- sampleValues.put(Short.class.getName(),new Short((short)22));
- sampleValues.put(Date.class.getName(),new Date());
-
- MBeanAttributeInfo [] attributesMetadata = _mbeanInfo.getAttributes();
- boolean atLeastThereIsOneWritableProperty = false;
-
- for (MBeanAttributeInfo attributeMetadata : attributesMetadata)
- {
- String name = attributeMetadata.getName();
-
- if (attributeMetadata.isWritable())
- {
- atLeastThereIsOneWritableProperty = true;
- Object sampleValue = sampleValues.get(attributeMetadata.getType());
- Object []values = new Object[]{sampleValue};
-
- Object result = _managementServer.getAttribute(_resourceObjectName, name);
- if (result == null)
- {
- _resourceClient.insertResourceProperty(
- new QName(
- Names.NAMESPACE_URI,
- name,
- Names.PREFIX),
- values);
- } else
- {
- _resourceClient.updateResourceProperty(
- new QName(
- Names.NAMESPACE_URI,
- name,
- Names.PREFIX),
- values);
- }
-
- Object propertyValues = _resourceClient.getPropertyAsObject(
- new QName(
- Names.NAMESPACE_URI,
- name,
- Names.PREFIX),
- Class.forName(attributeMetadata.getType()));
- int length = Array.getLength(propertyValues);
- if (length != 0)
- {
- Object propertyValue = Array.get(propertyValues, 0);
-
- assertEquals(
- "Comparison failed for property "+name,
- sampleValue,
- propertyValue);
- } else {
- assertNull(
- String.format(
- "\"%s\" property value shouldn't be null. Its value is %s",
- name,
- _managementServer.getAttribute(_resourceObjectName,name)),
- sampleValue);
- }
- }
- }
- assertTrue(
- "It's not possibile to run successfully this test case if " +
- "the target WS-Resource has no at least one writable property",
- atLeastThereIsOneWritableProperty);
- }
-
- /**
- * Test the WS-RP SetResourceProperty interface of the WS-DM adapter when the
- * target property is null.
- * According to WS-RP specs this operation is not allowed because in this case a SetResourceProperty with an "Insert"
- * message should be sent in order to initialize the property.
- *
- * <br>precondition : a ws resource exists and is registered. The value of the target property is null.
- * <br>postcondition : a Soap fault is received indicating the failuire.
- */
- public void testSetResourcePropertiesKO() throws Exception
- {
- Object typePropertyValue = _managementServer.getAttribute(_resourceObjectName, "Type");
- assertNull(typePropertyValue);
-
- try
- {
- _resourceClient.updateResourceProperty(
- new QName(
- Names.NAMESPACE_URI,
- "Type",
- Names.PREFIX),
- new Object[]{"sampleValue"});
- fail(
- "If the property is null on the target ws resource, according " +
- "to WS-RP specs, an update of its value is not possible.");
- } catch(SoapFault expected)
- {
-
- }
- }
-
- /**
- * Tests the WS-RP PutResourcePropertyDocument interface of the WS-DM adapter.
- *
- * <br>precondition : a ws resource exists and is registered.
- * <br>postcondition : A read / write property is correctly set according to WSRP interface.
- */
- public void testGetAndPutResourcePropertyDocumentOK() throws Exception
- {
- String expectedMgmtPubIntervalValue = "4321";
- String propertyName = "MgmtPubInterval";
-
- Element propertiesDocument = _resourceClient.getResourcePropertyDocument();
- Element [] properties = XmlUtils.getAllElements(propertiesDocument);
-
- for (Element element : properties)
- {
- if (propertyName.equals(element.getLocalName())) {
- element.setTextContent(expectedMgmtPubIntervalValue);
- } else {
- propertiesDocument.removeChild(element);
- }
- }
-
- _resourceClient.putResourcePropertyDocument(propertiesDocument);
-
- Element newProperties = _resourceClient.getResourcePropertyDocument();
-
- Element mgmtPubInterval = XmlUtils.getElement(
- newProperties, new QName(
- Names.NAMESPACE_URI,
- propertyName,
- Names.PREFIX));
-
- assertEquals(expectedMgmtPubIntervalValue,mgmtPubInterval.getTextContent());
- }
-
- /**
- * Tests the WS-RP PutResourcePropertyDocument interface of the WS-DM adapter.
- * Specifically it tries to update the value of a read-only property.
- *
- * <br>precondition : a ws resource exists, it is registered and has at least one read-only property.
- * <br>postcondition : An exception is thrown indicating the failure.
- */
- public void testGetAndPutResourcePropertyDocumentKO_WithReadOnlyProperty() throws Exception
- {
- String propertyName = "Name";
-
- Element propertiesDocument = _resourceClient.getResourcePropertyDocument();
- Element [] properties = XmlUtils.getAllElements(propertiesDocument);
-
- for (Element element : properties)
- {
- if (propertyName.equals(element.getLocalName())) {
- element.setTextContent("ThisIsTheNewValueOfNameProperty");
- } else {
- propertiesDocument.removeChild(element);
- }
- }
-
- try
- {
- _resourceClient.putResourcePropertyDocument(propertiesDocument);
- fail("It's not possible to update the value of a read-only property.");
- } catch (SoapFault expected)
- {
-
- }
- }
-
- /**
- * Test the WS-RP GetResourceProperties interface of the WS-DM adapter.
- *
- * <br>precondition : a ws resource exists and is registered.
- * <br>postcondition : Properties are correctly returned according to WSRP interface and they (their value)
- * are matching with corresponding MBean properties.
- */
- public void testGetMultipleResourcePropertiesOK() throws Exception
- {
- MBeanAttributeInfo [] attributesMetadata = _mbeanInfo.getAttributes();
- QName[] names = new QName[attributesMetadata.length];
-
- int index = 0;
- for (MBeanAttributeInfo attributeMetadata : _mbeanInfo.getAttributes())
- {
- QName qname = new QName(Names.NAMESPACE_URI,attributeMetadata.getName(),Names.PREFIX);
- names[index++] = qname;
- }
-
- Element[] properties =_resourceClient.getMultipleResourceProperties(names);
- for (Element element : properties)
- {
- String name = element.getLocalName();
- Object value = _managementServer.getAttribute(_resourceObjectName, name);
- if ("Name".equals(name))
- {
- assertEquals(
- value,
- element.getTextContent());
- } else if ("Durable".equals(name))
- {
- assertEquals(
- value,
- Boolean.valueOf(element.getTextContent()));
- } else if ("ExpireTime".equals(name))
- {
- assertEquals(
- value,
- new Date(Long.valueOf(element.getTextContent())));
- } else if ("MsgTotalEnqueues".equals(name))
- {
- assertEquals(
- value,
- Long.valueOf(element.getTextContent()));
- } else if ("ConsumerCount".equals(name))
- {
- assertEquals(
- value,
- Integer.valueOf(element.getTextContent()));
- }else if ("VhostRef".equals(name))
- {
- assertEquals(
- value,
- UUID.fromString(element.getTextContent()));
- }
- }
- }
-
- /**
- * Test operation invocation on WS-Resource.
- * This method tests the exchange of simple types between requestor and service provider.
- * With simple types we mean :
- *
- * <ul>
- * <li>java.lang.Long / long (xsd:long)
- * <li>java.lang.Integer / int (xsd:int / xsd:integer)
- * <li>java.lang.Double/ double (xsd:double)
- * <li>java.lang.Float / float (xsd:float)
- * <li>java.lang.Short / short (xsd:short)
- * <li>java.lang.Boolean / boolean (xsd:boolean)
- * <li>java.lang.String (xsd:string)
- * <li>java.net.URI (xsd:anyURI)
- * <li>java.util.Date(xsd:dateTime)
- * </ul>
- *
- * <br>precondition : a ws resource exists and is registered and the requested operation is available on that.
- * <br>postcondition : invocations are executed successfully, no exception is thrown and parameters are correctly returned.
- */
- @SuppressWarnings("unchecked")
- public void testOperationInvocationOK_withSimpleTypes() throws Exception
- {
- Long expectedLongResult = new Long(1373);
- Boolean expectedBooleanResult = Boolean.TRUE;
- Double expectedDoubleResult = new Double(12763.44);
- Float expectedFloatResult = new Float(2727.233f);
- Integer expectedIntegerResult = new Integer(28292);
- Short expectedShortResult = new Short((short)227);
- String expectedStringResult = "expectedStringResult";
- URI expectedUriResult = URI.create("http://qpid.apache.org/");
- Date expectedDateResult = new Date();
-
- Object result = _resourceClient.invoke(
- _invocationHandlers.get("echoWithSimpleTypes"),
- new Object[]{
- expectedLongResult,
- expectedBooleanResult,
- expectedDoubleResult,
- expectedFloatResult,
- expectedIntegerResult,
- expectedShortResult,
- expectedStringResult,
- expectedUriResult,
- expectedDateResult});
-
- Method getStatusCode = result.getClass().getMethod("getStatusCode");
- Method getOutputParameters = result.getClass().getMethod("getOutputParameters");
- assertEquals(retCodeOk,getStatusCode.invoke(result));
- Map<String,Object> out = (Map<String, Object>) getOutputParameters.invoke(result);
-
- assertEquals("Output parameters must be 9.",9,out.size());
- assertTrue("Long output parameter not found on result object.",out.containsValue(expectedLongResult));
- assertTrue("Boolean output parameter not found on result object.",out.containsValue(expectedBooleanResult));
- assertTrue("Double output parameter not found on result object.",out.containsValue(expectedDoubleResult));
- assertTrue("Float output parameter not found on result object.",out.containsValue(expectedFloatResult));
- assertTrue("Integer output parameter not found on result object.",out.containsValue(expectedIntegerResult));
- assertTrue("Short output parameter not found on result object.",out.containsValue(expectedShortResult));
- assertTrue("String output parameter not found on result object.",out.containsValue(expectedStringResult));
- assertTrue("URI output parameter not found on result object.",out.containsValue(expectedUriResult));
- assertTrue("Date output parameter not found on result object.",out.containsValue(expectedDateResult));
- }
-
- /**
- * Test operation invocation on WS-Resource.
- * This method tests the exchange of arrays between requestor and service provider.
- * For this test exchanged arrays contain :
- *
- * <ul>
- * <li>java.lang.Long (xsd:long)
- * <li>java.lang.Integer (xsd:int / xsd:integer)
- * <li>java.lang.Double (xsd:double)
- * <li>java.lang.Float (xsd:float)
- * <li>java.lang.Short (xsd:short)
- * <li>java.lang.Boolean (xsd:boolean)
- * <li>java.lang.String (xsd:string)
- * <li>java.net.URI (xsd:anyURI)
- * <li>java.util.Date(xsd:dateTime)
- * </ul>
- *
- * <br>precondition : a ws resource exists and is registered and the requested operation is available on that.
- * <br>postcondition : invocations are executed successfully, no exception is thrown and parameters are correctly returned.
- */
- @SuppressWarnings("unchecked")
- public void testOperationInvocationOK_withWrapperArrays() throws Exception
- {
- Long [] expectedLongResult = {new Long(2),new Long(1),new Long(3),new Long(4)};
- Boolean [] expectedBooleanResult = { Boolean.TRUE,Boolean.FALSE,Boolean.FALSE};
- Double [] expectedDoubleResult = {12763.44d,2832.33d,2292.33d,22293.22d};
- Float [] expectedFloatResult = {2727.233f,1f,2f,4f,5.4f,33.2f};
- Integer [] expectedIntegerResult = {1,2,3,4,55,66,77,88,99};
- Short [] expectedShortResult = {(short)227,(short)23,(short)9};
- String [] expectedStringResult = {"s1","s2","s333","s4"};
- URI [] expectedUriResult = {
- URI.create("http://qpid.apache.org/"),
- URI.create("http://www.apache.org"),
- URI.create("http://projects.apache.org")};
-
- Date [] expectedDateResult = {
- new Date(),
- new Date(38211897),
- new Date(903820382)};
-
- Object result = _resourceClient.invoke(
- _invocationHandlers.get("echoWithArrays"),
- new Object[]{
- expectedLongResult,
- expectedBooleanResult,
- expectedDoubleResult,
- expectedFloatResult,
- expectedIntegerResult,
- expectedShortResult,
- expectedStringResult,
- expectedUriResult,
- expectedDateResult});
-
- Method getStatusCode = result.getClass().getMethod("getStatusCode");
- Method getOutputParameters = result.getClass().getMethod("getOutputParameters");
- assertEquals(retCodeOk,getStatusCode.invoke(result));
- Map<String,Object> out = (Map<String, Object>) getOutputParameters.invoke(result);
-
- assertEquals("Output parameters must be 9.",9,out.size());
- assertTrue("Long array doesn't match.",Arrays.equals(expectedLongResult, (Long[])out.get(Long.class.getName())));
- assertTrue("Boolean array doesn't match.",Arrays.equals(expectedBooleanResult, (Boolean[])out.get(Boolean.class.getName())));
- assertTrue("Double array doesn't match.",Arrays.equals(expectedDoubleResult, (Double[])out.get(Double.class.getName())));
- assertTrue("Float array doesn't match.",Arrays.equals(expectedFloatResult, (Float[])out.get(Float.class.getName())));
- assertTrue("Integer array doesn't match.", Arrays.equals(expectedIntegerResult, (Integer[])out.get(Integer.class.getName())));
- assertTrue("Short array doesn't match.",Arrays.equals(expectedShortResult, (Short[])out.get(Short.class.getName())));
- assertTrue("String array doesn't match.",Arrays.equals(expectedStringResult, (String[])out.get(String.class.getName())));
- assertTrue("URI array doesn't match.",Arrays.equals(expectedUriResult, (URI[])out.get(URI.class.getName())));
- assertTrue("Date array doesn't match.",Arrays.equals(expectedDateResult, (Date[])out.get(Date.class.getName())));
- }
-
- /**
- * Test operation invocation on WS-Resource.
- * This method tests the exchange of primitive type arrays between requestor and service provider.
- * NOte that even the sent array contain primtiive type QMan deals only with objects so in the result
- * object you will find the corresponding wrapper types.
- *
- * For this test exchanged arrays contain :
- *
- * <ul>
- * <li>java.lang.Long / long (xsd:long)
- * <li>java.lang.Integer / int (xsd:int / xsd:integer)
- * <li>java.lang.Double/ double (xsd:double)
- * <li>java.lang.Float / float (xsd:float)
- * <li>java.lang.Short / short (xsd:short)
- * <li>java.lang.Boolean / boolean (xsd:boolean)
- * </ul>
- *
- * <br>precondition : a ws resource exists and is registered and the requested operation is available on that.
- * <br>postcondition : invocations are executed successfully, no exception is thrown and parameters are correctly returned.
- */
- @SuppressWarnings("unchecked")
- public void testOperationInvocationOK_withPrimitiveArrays() throws Exception
- {
- long [] expectedLongResult = {1L,2L,3L,4L};
- boolean [] expectedBooleanResult = { true,false,false};
- double [] expectedDoubleResult = {12763.44d,2832.33d,2292.33d,22293.22d};
- float [] expectedFloatResult = {2727.233f,1f,2f,4f,5.4f,33.2f};
- int [] expectedIntegerResult = {1,2,3,4,55,66,77,88,99};
- short [] expectedShortResult = {(short)227,(short)23,(short)9};
-
- Object result = _resourceClient.invoke(
- _invocationHandlers.get("echoWithSimpleTypeArrays"),
- new Object[]{
- expectedLongResult,
- expectedBooleanResult,
- expectedDoubleResult,
- expectedFloatResult,
- expectedIntegerResult,
- expectedShortResult});
-
- Method getStatusCode = result.getClass().getMethod("getStatusCode");
- Method getOutputParameters = result.getClass().getMethod("getOutputParameters");
- assertEquals(retCodeOk,getStatusCode.invoke(result));
- Map<String,Object> out = (Map<String, Object>) getOutputParameters.invoke(result);
-
- assertEquals("Output parameters must be 6.",6,out.size());
- assertArrayEquals(expectedLongResult, out.get(long.class.getName()));
- assertArrayEquals(expectedBooleanResult, out.get(boolean.class.getName()));
- assertArrayEquals(expectedDoubleResult, out.get(double.class.getName()));
- assertArrayEquals(expectedFloatResult, out.get(float.class.getName()));
- assertArrayEquals(expectedIntegerResult, out.get(int.class.getName()));
- assertArrayEquals(expectedShortResult, out.get(short.class.getName()));
- }
-
- /**
- * Test operation invocation on WS-Resource.
- * This method tests the exchange of a byte type array between requestor and service provider.
- *
- * <br>precondition : a WS-Resource exists and is registered and the requested operation is available on that.
- * <br>postcondition : invocations are executed successfully, no exception is thrown and byte array are correctly returned.
- */
- @SuppressWarnings("unchecked")
- public void testOperationInvocationOK_withByteArray() throws Exception
- {
- byte [] expectedByteResult = {1,3,4,2,2,44,22,3,3,55,66};
-
- Object result = _resourceClient.invoke(
- _invocationHandlers.get("echoWithByteArray"),
- new Object[]{expectedByteResult});
-
- Method getStatusCode = result.getClass().getMethod("getStatusCode");
- Method getOutputParameters = result.getClass().getMethod("getOutputParameters");
-
- assertEquals(retCodeOk,getStatusCode.invoke(result));
- Map<String,Object> out = (Map<String, Object>) getOutputParameters.invoke(result);
-
- assertEquals("Output parameters must be 1.",1,out.size());
- assertArrayEquals(expectedByteResult, out.get(byte[].class.getName()));
- }
-
- /**
- * Test a simple operation invocation on a WS-Resource.
- * This method tests a simple operation without any input and output parameters.
- *
- * <br>precondition : a ws resource exists and is registered and the requested operation is available on that.
- * <br>postcondition : invocations are executed successfully an no exception is thrown.
- */
- @SuppressWarnings("unchecked")
- public void testSimpleOperationInvocationOK() throws Exception
- {
- Object result = _resourceClient.invoke(
- _invocationHandlers.get("voidWithoutArguments"),
- null);
-
- Method getStatusCode = result.getClass().getMethod("getStatusCode");
- assertEquals(
- "Something was wrong...expected return code is "+retCodeOk,
- retCodeOk,
- getStatusCode.invoke(result));
- }
-
- /**
- * Test a the invocation on a WS-Resource with a method that throws an exception..
- *
- * <br>precondition : a ws resource exists and is registered and the requested operation is available on that.
- * <br>postcondition : an exception is thrown by the requested method.
- */
- @SuppressWarnings("unchecked")
- public void testInvocationException_OK() throws Exception
- {
- try
- {
- _resourceClient.invoke(
- _invocationHandlers.get("throwsException"),
- null);
- fail("The requested operation has thrown an exception so a Soap Fault is expected...");
- } catch(SoapFault expected)
- {
- }
- }
-
- /**
- * Test operation invocation on WS-Resource.
- * This method tests the exchange of UUID type between requestor and service provider.
- *
- * <br>precondition : a WS-Resource exists and is registered and the requested operation is available on that.
- * <br>postcondition : invocations are executed successfully, no exception is thrown and parameters are correctly returned.
- */
- @SuppressWarnings("unchecked")
- public void testOperationInvocationOK_withUUID() throws Exception
- {
- UUID expectedUuid = UUID.randomUUID();
-
- Object result = _resourceClient.invoke(
- _invocationHandlers.get("echoWithUUID"),
- new Object[]{expectedUuid});
-
- Method getStatusCode = result.getClass().getMethod("getStatusCode");
- Method getOutputParameters = result.getClass().getMethod("getOutputParameters");
-
- assertEquals(retCodeOk,getStatusCode.invoke(result));
- Map<String,Object> out = (Map<String, Object>) getOutputParameters.invoke(result);
-
- assertEquals("Output parameters must be 1.",1,out.size());
- assertEquals(expectedUuid, out.get("uuid"));
- }
-
- /**
- * Test operation invocation on WS-Resource.
- * This method tests the exchange of Map type between requestor and service provider.
- * For this test exchanged arrays contain :
- *
- * <br>precondition : a ws resource exists and is registered and the requested operation is available on that.
- * <br>postcondition : invocations are executed successfully, no exception is thrown and parameters are correctly returned.
- */
- @SuppressWarnings("unchecked")
- public void testOperationInvocationOK_withMap() throws Exception
- {
- Map<String,Object> expectedMap = new HashMap<String, Object>();
- expectedMap.put("p1", new Long(1));
- expectedMap.put("p2", Boolean.TRUE);
- expectedMap.put("p3", 1234d);
- expectedMap.put("p4", 11.2f);
- expectedMap.put("p5", 1272);
- expectedMap.put("p6", (short)12);
- expectedMap.put("p7", "aString");
- expectedMap.put("p8", "http://qpid.apache.org");
- expectedMap.put("p9", new Date(12383137128L));
- expectedMap.put("p10", new byte[]{1,2,2,3,3,4});
-
- Object result = _resourceClient.invoke(
- _invocationHandlers.get("echoWithMap"),
- new Object[]{expectedMap});
-
- Method getStatusCode = result.getClass().getMethod("getStatusCode");
- Method getOutputParameters = result.getClass().getMethod("getOutputParameters");
-
- assertEquals(retCodeOk,getStatusCode.invoke(result));
- Map<String,Object> out = (Map<String, Object>) ((Map<String, Object>) getOutputParameters.invoke(result)).get("map");
-
- assertEquals("Output parameters must be 10.",10,out.size());
- assertEquals(expectedMap.get("p1"),out.get("p1"));
- assertEquals(expectedMap.get("p2"),out.get("p2"));
- assertEquals(expectedMap.get("p3"),out.get("p3"));
- assertEquals(expectedMap.get("p4"),out.get("p4"));
- assertEquals(expectedMap.get("p5"),out.get("p5"));
- assertEquals(expectedMap.get("p6"),out.get("p6"));
- assertEquals(expectedMap.get("p7"),out.get("p7"));
- assertEquals(expectedMap.get("p8"),out.get("p8"));
- assertEquals(expectedMap.get("p9"),out.get("p9"));
- assertTrue( Arrays.equals((byte[])expectedMap.get("p10"),(byte[])out.get("p10")));
- }
-
- /**
- * Main entry point for running this test case.
- *
- * @return the decorated test case.
- */
- public static Test suite() {
- TestSuite suite = new TestSuite("Test Suite for WS-DM Adapter");
- suite.addTestSuite(WsDmAdapterTest.class);
+ TestSuite suite = new TestSuite("Test suite for QMan WS-DM.");
+ suite.addTestSuite(MetadataExchangeInterfaceTestCase.class);
+ suite.addTestSuite(OperationInvocationInterfaceTestCase.class);
+ suite.addTestSuite(GetResourcePropertyDocumentTestCase.class);
+ suite.addTestSuite(SetResourcePropertiesTestCase.class);
+ suite.addTestSuite(GetMultipleResourcePropertiesTestCase.class);
+ suite.addTestSuite(GetResourcePropertiesTestCase.class);
return new WsDmAdapterTestSetup(suite);
}
/**
- * Creates a service group client reference.
- *
- * @return a service group client reference.
- */
- private ServiceGroupClient getServiceGroupClient()
- {
- URI address = URI.create(
- Protocol.DEFAULT_ENDPOINT_URI.replaceFirst("8080",System.getProperty(Names.ADAPTER_PORT_PROPERTY_NAME)));
- return new ServiceGroupClient(new EndpointReference(address));
- }
-
- /**
- * In order to test the behaviour of the WS-DM adapter, at
- * least one resource must be created. This is the method that
- * returns the name (ObjectName on JMX side, Resource-ID on WSDM side)
- * of that resource
- *
- * @return the name of the MBean instance that will be created.
- * @throws Exception when the name if malformed. Practically never.
- */
- private ObjectName createResourceName() throws Exception
- {
- return new ObjectName(
- "Q-MAN:objectId="+UUID.randomUUID()+
- ", brokerID="+UUID.randomUUID()+
- ",class=queue"+
- ",package=org.apache.qpid"+
- ",name="+System.currentTimeMillis());
- }
-
- private Map<String,ProxyHandler> createInvocationHandlers()
- {
- Map<String, ProxyHandler> handlers = new HashMap<String, ProxyHandler>();
-
- ProxyHandler handler = new ReflectionProxyHandler();
- handler.setAction(Names.NAMESPACE_URI+"/"+"voidWithoutArguments");
- handler.setRequestName(
- new QName(
- Names.NAMESPACE_URI,
- "voidWithoutArgumentsRequest",
- Names.PREFIX));
- handler.setRequestParameterNames(new QName[]{});
- handler.setResponseName(
- new QName(
- Names.NAMESPACE_URI,
- "voidWithoutArgumentsResponse",
- Names.PREFIX));
- handler.setReturnType(Result.class);
-
- ProxyHandler exceptionHandler = new ReflectionProxyHandler();
- exceptionHandler.setAction(Names.NAMESPACE_URI+"/"+"throwsException");
- exceptionHandler.setRequestName(
- new QName(
- Names.NAMESPACE_URI,
- "throwsExceptionRequest",
- Names.PREFIX));
-
- exceptionHandler.setRequestParameterNames(new QName[]{});
- exceptionHandler.setResponseName(
- new QName(
- Names.NAMESPACE_URI,
- "throwsExceptionResponse",
- Names.PREFIX));
-
- exceptionHandler.setReturnType(Result.class);
-
- ProxyHandler echoWithWrapperTypesHandler = new ReflectionProxyHandler();
- echoWithWrapperTypesHandler.setAction(Names.NAMESPACE_URI+"/"+"echoWithSimpleTypes");
- echoWithWrapperTypesHandler.setRequestName(
- new QName(
- Names.NAMESPACE_URI,
- "echoWithSimpleTypesRequest",
- Names.PREFIX));
-
- echoWithWrapperTypesHandler.setRequestParameterNames(new QName[]{
- new QName(Names.NAMESPACE_URI,"p1",Names.PREFIX),
- new QName(Names.NAMESPACE_URI,"p2",Names.PREFIX),
- new QName(Names.NAMESPACE_URI,"p3",Names.PREFIX),
- new QName(Names.NAMESPACE_URI,"p4",Names.PREFIX),
- new QName(Names.NAMESPACE_URI,"p5",Names.PREFIX),
- new QName(Names.NAMESPACE_URI,"p6",Names.PREFIX),
- new QName(Names.NAMESPACE_URI,"p7",Names.PREFIX),
- new QName(Names.NAMESPACE_URI,"p8",Names.PREFIX),
- new QName(Names.NAMESPACE_URI,"p9",Names.PREFIX),
- });
-
- echoWithWrapperTypesHandler.setResponseName(
- new QName(
- Names.NAMESPACE_URI,
- "echoWithSimpleTypesResponse",
- Names.PREFIX));
-
- echoWithWrapperTypesHandler.setReturnType(Result.class);
-
- ProxyHandler echoWithArrayOfWrapperTypes = new ReflectionProxyHandler();
- echoWithArrayOfWrapperTypes.setAction(Names.NAMESPACE_URI+"/"+"echoWithArrays");
- echoWithArrayOfWrapperTypes.setRequestName(
- new QName(
- Names.NAMESPACE_URI,
- "echoWithArraysRequest",
- Names.PREFIX));
-
- echoWithArrayOfWrapperTypes.setRequestParameterNames(new QName[]{
- new QName(Names.NAMESPACE_URI,"p1",Names.PREFIX),
- new QName(Names.NAMESPACE_URI,"p2",Names.PREFIX),
- new QName(Names.NAMESPACE_URI,"p3",Names.PREFIX),
- new QName(Names.NAMESPACE_URI,"p4",Names.PREFIX),
- new QName(Names.NAMESPACE_URI,"p5",Names.PREFIX),
- new QName(Names.NAMESPACE_URI,"p6",Names.PREFIX),
- new QName(Names.NAMESPACE_URI,"p7",Names.PREFIX),
- new QName(Names.NAMESPACE_URI,"p8",Names.PREFIX),
- new QName(Names.NAMESPACE_URI,"p9",Names.PREFIX),
- });
-
- echoWithArrayOfWrapperTypes.setResponseName(
- new QName(
- Names.NAMESPACE_URI,
- "echoWithArraysResponse",
- Names.PREFIX));
-
- echoWithArrayOfWrapperTypes.setReturnType(Result.class);
-
- ProxyHandler echoWithArrayOfPrimitiveTypes = new ReflectionProxyHandler();
- echoWithArrayOfPrimitiveTypes.setAction(Names.NAMESPACE_URI+"/"+"echoWithSimpleTypeArrays");
- echoWithArrayOfPrimitiveTypes.setRequestName(
- new QName(
- Names.NAMESPACE_URI,
- "echoWithSimpleTypeArraysRequest",
- Names.PREFIX));
-
- echoWithArrayOfPrimitiveTypes.setRequestParameterNames(new QName[]{
- new QName(Names.NAMESPACE_URI,"p1",Names.PREFIX),
- new QName(Names.NAMESPACE_URI,"p2",Names.PREFIX),
- new QName(Names.NAMESPACE_URI,"p3",Names.PREFIX),
- new QName(Names.NAMESPACE_URI,"p4",Names.PREFIX),
- new QName(Names.NAMESPACE_URI,"p5",Names.PREFIX),
- new QName(Names.NAMESPACE_URI,"p6",Names.PREFIX)});
-
- echoWithArrayOfPrimitiveTypes.setResponseName(
- new QName(
- Names.NAMESPACE_URI,
- "echoWithSimpleTypeArraysResponse",
- Names.PREFIX));
-
- echoWithArrayOfPrimitiveTypes.setReturnType(Result.class);
-
- ProxyHandler echoWithByteArray = new EnhancedReflectionProxyHandler();
- echoWithByteArray.setAction(Names.NAMESPACE_URI+"/"+"echoWithByteArray");
- echoWithByteArray.setRequestName(
- new QName(
- Names.NAMESPACE_URI,
- "echoWithByteArrayRequest",
- Names.PREFIX));
-
- echoWithByteArray.setRequestParameterNames(
- new QName[]{
- new QName(Names.NAMESPACE_URI,"p1",Names.PREFIX)});
-
- echoWithByteArray.setResponseName(
- new QName(
- Names.NAMESPACE_URI,
- "echoWithByteArrayResponse",
- Names.PREFIX));
-
- echoWithByteArray.setReturnType(Result.class);
-
- ProxyHandler echoWithUUID = new EnhancedReflectionProxyHandler();
- echoWithUUID.setAction(Names.NAMESPACE_URI+"/"+"echoWithUUID");
- echoWithUUID.setRequestName(
- new QName(
- Names.NAMESPACE_URI,
- "echoWithUUIDRequest",
- Names.PREFIX));
-
- echoWithUUID.setRequestParameterNames(
- new QName[]{
- new QName(Names.NAMESPACE_URI,"p1",Names.PREFIX)});
-
- echoWithUUID.setResponseName(
- new QName(
- Names.NAMESPACE_URI,
- "echoWithUUIDResponse",
- Names.PREFIX));
-
- echoWithUUID.setReturnType(Result.class);
-
- ProxyHandler echoWithMap = new EnhancedReflectionProxyHandler();
- echoWithMap.setAction(Names.NAMESPACE_URI+"/"+"echoWithMap");
- echoWithMap.setRequestName(
- new QName(
- Names.NAMESPACE_URI,
- "echoWithMapRequest",
- Names.PREFIX));
-
- echoWithMap.setRequestParameterNames(
- new QName[]{
- new QName(Names.NAMESPACE_URI,"p1",Names.PREFIX)});
-
- echoWithMap.setResponseName(
- new QName(
- Names.NAMESPACE_URI,
- "echoWithMapResponse",
- Names.PREFIX));
-
- echoWithMap.setReturnType(Result.class);
-
- handlers.put("voidWithoutArguments",handler);
- handlers.put("echoWithSimpleTypes",echoWithWrapperTypesHandler);
- handlers.put("echoWithArrays",echoWithArrayOfWrapperTypes);
- handlers.put("echoWithSimpleTypeArrays", echoWithArrayOfPrimitiveTypes);
- handlers.put("echoWithByteArray", echoWithByteArray);
- handlers.put("echoWithUUID", echoWithUUID);
- handlers.put("echoWithMap", echoWithMap);
- handlers.put("throwsException",exceptionHandler);
- return handlers;
- }
-
- /**
- * Internal method used for array comparison using reflection.
+ * Finds a free port that will be used to run the embedded
+ * web server.
*
- * @param expectedArray the expected array.
- * @param resultArray the array that must match the expected one.
+ * @return a free port that will be used to run the
+ * embedded web server.
*/
- private void assertArrayEquals(Object expectedArray, Object resultArray)
- {
- int expectedArrayLength = Array.getLength(expectedArray);
- int resultArrayLength = Array.getLength(resultArray);
-
- assertEquals(expectedArrayLength,resultArrayLength);
-
- for (int index = 0; index < expectedArrayLength; index++)
- {
- Object expected = Array.get(expectedArray, index);
- Object result = Array.get(resultArray, index);
-
- assertEquals(expected,result);
- }
- }
-
- public static int getFreePort() throws IOException {
+ private static int getFreePort() throws IOException {
ServerSocket server = null;
try
{
diff --git a/qpid/java/management/client/web.xml b/qpid/java/management/client/web.xml
index 0f8992d1bf..29eb64a268 100644
--- a/qpid/java/management/client/web.xml
+++ b/qpid/java/management/client/web.xml
@@ -8,11 +8,7 @@
Java Management Extensions (JMX) and / or WS-DM.
</description>
<display-name>QManEE</display-name>
- <context-param>
- <param-name>tapestry.app-package</param-name>
- <param-value>org.apache.qpid.management.web.console</param-value>
- </context-param>
- <listener>
+ <listener>
<description>
Provides lifecycle management for QMan module.
</description>
@@ -25,52 +21,52 @@
<servlet-class>org.apache.qpid.management.servlet.WSDMAdapter</servlet-class>
<load-on-startup>2</load-on-startup>
</servlet>
- <servlet>
- <display-name>View Console (System Overview) Action</display-name>
- <servlet-name>ViewConsole</servlet-name>
- <servlet-class>org.apache.qpid.management.web.action.ConsoleAction</servlet-class>
- <load-on-startup>5</load-on-startup>
- </servlet>
- <servlet>
- <display-name>View Resources</display-name>
- <servlet-name>ResourceManagement</servlet-name>
- <servlet-class>org.apache.qpid.management.web.action.ResourcesManagementAction</servlet-class>
- </servlet>
- <servlet>
- <display-name>JMX Perspective</display-name>
- <servlet-name>JmxPerspective</servlet-name>
- <servlet-class>org.apache.qpid.management.web.action.JmxPerspectiveAction</servlet-class>
- </servlet>
- <servlet>
- <display-name>WSDM Properties Perspective</display-name>
- <servlet-name>WsdmPropertiesPerspective</servlet-name>
- <servlet-class>org.apache.qpid.management.web.action.WsdmPropertiesPerspectiveAction</servlet-class>
- </servlet>
- <servlet>
- <display-name>WSDM Operations Perspective</display-name>
- <servlet-name>WsdmOperationsPerspective</servlet-name>
- <servlet-class>org.apache.qpid.management.web.action.WsdmOperationsPerspectiveAction</servlet-class>
- </servlet>
- <servlet>
- <display-name>WSDM WSDL Perspective</display-name>
- <servlet-name>WsdmWsdlPerspective</servlet-name>
- <servlet-class>org.apache.qpid.management.web.action.WsdmWsdlPerspectiveAction</servlet-class>
- </servlet>
- <servlet>
- <display-name>WSDM RMD Perspective</display-name>
- <servlet-name>WsdmRmdPerspective</servlet-name>
- <servlet-class>org.apache.qpid.management.web.action.WsdmRmdPerspectiveAction</servlet-class>
- </servlet>
- <servlet>
- <display-name>Logging Configurator</display-name>
- <servlet-name>LoggingConfiguration</servlet-name>
- <servlet-class>org.apache.qpid.management.web.action.LoggingConfigurationAction</servlet-class>
- </servlet>
- <servlet>
- <display-name>Brokers Management</display-name>
- <servlet-name>BrokersManagement</servlet-name>
- <servlet-class>org.apache.qpid.management.web.action.BrokersManagementAction</servlet-class>
- </servlet>
+ <servlet>
+ <display-name>View Console (System Overview) Action</display-name>
+ <servlet-name>ViewConsole</servlet-name>
+ <servlet-class>org.apache.qpid.management.web.action.ConsoleAction</servlet-class>
+ <load-on-startup>5</load-on-startup>
+ </servlet>
+ <servlet>
+ <display-name>View Resources</display-name>
+ <servlet-name>ResourceManagement</servlet-name>
+ <servlet-class>org.apache.qpid.management.web.action.ResourcesManagementAction</servlet-class>
+ </servlet>
+ <servlet>
+ <display-name>JMX Perspective</display-name>
+ <servlet-name>JmxPerspective</servlet-name>
+ <servlet-class>org.apache.qpid.management.web.action.JmxPerspectiveAction</servlet-class>
+ </servlet>
+ <servlet>
+ <display-name>WSDM Properties Perspective</display-name>
+ <servlet-name>WsdmPropertiesPerspective</servlet-name>
+ <servlet-class>org.apache.qpid.management.web.action.WsdmPropertiesPerspectiveAction</servlet-class>
+ </servlet>
+ <servlet>
+ <display-name>WSDM Operations Perspective</display-name>
+ <servlet-name>WsdmOperationsPerspective</servlet-name>
+ <servlet-class>org.apache.qpid.management.web.action.WsdmOperationsPerspectiveAction</servlet-class>
+ </servlet>
+ <servlet>
+ <display-name>WSDM WSDL Perspective</display-name>
+ <servlet-name>WsdmWsdlPerspective</servlet-name>
+ <servlet-class>org.apache.qpid.management.web.action.WsdmWsdlPerspectiveAction</servlet-class>
+ </servlet>
+ <servlet>
+ <display-name>WSDM RMD Perspective</display-name>
+ <servlet-name>WsdmRmdPerspective</servlet-name>
+ <servlet-class>org.apache.qpid.management.web.action.WsdmRmdPerspectiveAction</servlet-class>
+ </servlet>
+ <servlet>
+ <display-name>Logging Configurator</display-name>
+ <servlet-name>LoggingConfiguration</servlet-name>
+ <servlet-class>org.apache.qpid.management.web.action.LoggingConfigurationAction</servlet-class>
+ </servlet>
+ <servlet>
+ <display-name>Brokers Management</display-name>
+ <servlet-name>BrokersManagement</servlet-name>
+ <servlet-class>org.apache.qpid.management.web.action.BrokersManagementAction</servlet-class>
+ </servlet>
<servlet>
<description>
Connects QMAn to one or more brokers depending from what is
@@ -81,43 +77,43 @@
<servlet-name>ConnectQManToBroker</servlet-name>
<servlet-class>org.apache.qpid.management.servlet.ConnectQManToBroker</servlet-class>
<load-on-startup>1</load-on-startup>
- </servlet>
- <servlet-mapping>
- <servlet-name>ResourceManagement</servlet-name>
- <url-pattern>/resources_management</url-pattern>
- </servlet-mapping>
- <servlet-mapping>
- <servlet-name>WsdmWsdlPerspective</servlet-name>
- <url-pattern>/wsdm_wsdl_perspective</url-pattern>
- </servlet-mapping>
- <servlet-mapping>
- <servlet-name>WsdmRmdPerspective</servlet-name>
- <url-pattern>/wsdm_rmd_perspective</url-pattern>
- </servlet-mapping>
- <servlet-mapping>
- <servlet-name>WsdmOperationsPerspective</servlet-name>
- <url-pattern>/wsdm_operations_perspective</url-pattern>
- </servlet-mapping>
- <servlet-mapping>
- <servlet-name>WsdmPropertiesPerspective</servlet-name>
- <url-pattern>/wsdm_properties_perspective</url-pattern>
- </servlet-mapping>
- <servlet-mapping>
- <servlet-name>BrokersManagement</servlet-name>
- <url-pattern>/brokers_management</url-pattern>
- </servlet-mapping>
- <servlet-mapping>
- <servlet-name>JmxPerspective</servlet-name>
- <url-pattern>/jmx_perspective</url-pattern>
+ </servlet>
+ <servlet-mapping>
+ <servlet-name>ResourceManagement</servlet-name>
+ <url-pattern>/resources_management</url-pattern>
+ </servlet-mapping>
+ <servlet-mapping>
+ <servlet-name>WsdmWsdlPerspective</servlet-name>
+ <url-pattern>/wsdm_wsdl_perspective</url-pattern>
+ </servlet-mapping>
+ <servlet-mapping>
+ <servlet-name>WsdmRmdPerspective</servlet-name>
+ <url-pattern>/wsdm_rmd_perspective</url-pattern>
+ </servlet-mapping>
+ <servlet-mapping>
+ <servlet-name>WsdmOperationsPerspective</servlet-name>
+ <url-pattern>/wsdm_operations_perspective</url-pattern>
+ </servlet-mapping>
+ <servlet-mapping>
+ <servlet-name>WsdmPropertiesPerspective</servlet-name>
+ <url-pattern>/wsdm_properties_perspective</url-pattern>
+ </servlet-mapping>
+ <servlet-mapping>
+ <servlet-name>BrokersManagement</servlet-name>
+ <url-pattern>/brokers_management</url-pattern>
</servlet-mapping>
- <servlet-mapping>
- <servlet-name>LoggingConfiguration</servlet-name>
- <url-pattern>/logging_configuration</url-pattern>
- </servlet-mapping>
- <servlet-mapping>
- <servlet-name>ViewConsole</servlet-name>
- <url-pattern>/console</url-pattern>
- </servlet-mapping>
+ <servlet-mapping>
+ <servlet-name>JmxPerspective</servlet-name>
+ <url-pattern>/jmx_perspective</url-pattern>
+ </servlet-mapping>
+ <servlet-mapping>
+ <servlet-name>LoggingConfiguration</servlet-name>
+ <url-pattern>/logging_configuration</url-pattern>
+ </servlet-mapping>
+ <servlet-mapping>
+ <servlet-name>ViewConsole</servlet-name>
+ <url-pattern>/console</url-pattern>
+ </servlet-mapping>
<servlet-mapping>
<servlet-name>ConnectQManToBroker</servlet-name>
<url-pattern>/test/*</url-pattern>
diff --git a/qpid/java/management/eclipse-plugin/META-INF/MANIFEST.MF b/qpid/java/management/eclipse-plugin/META-INF/MANIFEST.MF
index 32d1b7a1b2..9b5a240bb6 100644
--- a/qpid/java/management/eclipse-plugin/META-INF/MANIFEST.MF
+++ b/qpid/java/management/eclipse-plugin/META-INF/MANIFEST.MF
@@ -10,8 +10,8 @@ Bundle-Localization: plugin
Require-Bundle: org.eclipse.ui,
org.eclipse.core.runtime,
org.eclipse.ui.forms,
- jmxremote.sasl;resolution:=optional,
- qpid-management-common
+ qpid-management-common,
+ org.apache.commons.codec;bundle-version="1.3.0"
Eclipse-LazyStart: true
Export-Package: org.apache.qpid.management.ui,
org.apache.qpid.management.ui.actions,
diff --git a/qpid/java/management/eclipse-plugin/build-release-linux-gtk-x86_64.properties b/qpid/java/management/eclipse-plugin/build-release-linux-gtk-x86_64.properties
new file mode 100644
index 0000000000..f1c35c82e8
--- /dev/null
+++ b/qpid/java/management/eclipse-plugin/build-release-linux-gtk-x86_64.properties
@@ -0,0 +1,36 @@
+#
+#
+# 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.
+#
+#
+
+release.name=${module.namever}-linux-gtk-x86_64
+
+release.subdir=${module.release.base}/${release.name}
+
+release.tar.gz=${module.release.base}/${release.name}.tar.gz
+
+qpidmc.ini=src/main/resources/linux-gtk-x86_64/qpidmc.ini
+
+qpidmc.executable=src/main/resources/linux-gtk-x86_64/qpidmc
+
+qpidmc.companion.library=src/main/resources/linux-gtk-x86_64/libcairo-swt.so
+
+rcp.libs=${management-eclipse-plugin-linux-gtk-x86_64.libs}
+
+rcp.configuration.dir=src/main/resources/linux-gtk-x86_64/Configuration
diff --git a/qpid/java/management/eclipse-plugin/build-release-solaris-gtk-sparc.properties b/qpid/java/management/eclipse-plugin/build-release-solaris-gtk-sparc.properties
new file mode 100644
index 0000000000..7d5b613e06
--- /dev/null
+++ b/qpid/java/management/eclipse-plugin/build-release-solaris-gtk-sparc.properties
@@ -0,0 +1,39 @@
+#
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+#
+
+release.name=${module.namever}-solaris-gtk-sparc
+
+release.subdir=${module.release.base}/${release.name}
+
+release.tar.gz=${module.release.base}/${release.name}.tar.gz
+
+qpidmc.ini=src/main/resources/solaris-gtk-sparc/qpidmc.ini
+
+qpidmc.solaris.xpm.files=src/main/resources/solaris-gtk-sparc/Qpidmc.l.pm \
+ src/main/resources/solaris-gtk-sparc/Qpidmc.m.pm \
+ src/main/resources/solaris-gtk-sparc/Qpidmc.s.pm \
+ src/main/resources/solaris-gtk-sparc/Qpidmc.t.pm
+
+qpidmc.executable=src/main/resources/solaris-gtk-sparc/qpidmc
+
+rcp.libs=${management-eclipse-plugin-solaris-gtk-sparc.libs}
+
+rcp.configuration.dir=src/main/resources/solaris-gtk-sparc/Configuration
diff --git a/qpid/java/management/eclipse-plugin/build-release.xml b/qpid/java/management/eclipse-plugin/build-release.xml
index b396974c9a..3cb1af194f 100644
--- a/qpid/java/management/eclipse-plugin/build-release.xml
+++ b/qpid/java/management/eclipse-plugin/build-release.xml
@@ -44,6 +44,9 @@
For linux libcairo-swt.so file:
qpidmc.companion.library
+
+ For solaris .xpm files:
+ qpidmc.solaris.xpm.files
-->
</condition>
@@ -86,15 +89,22 @@
<fileset file="${qpidmc.companion.library}"/>
</copy>
</target>
+
+ <target name="release-bin-executable-solaris-xpm-files" if="qpidmc.solaris.xpm.files">
+ <!-- Copy the solaris xpm files -->
+ <copy todir="${release.subdir}" flatten="true" failonerror="true">
+ <fileset dir="${basedir}" includes="${qpidmc.solaris.xpm.files}"/>
+ </copy>
+ </target>
<target name="release-bin-rcp-deps" description="copy eclipse-rcp dependencies into module release"
- depends="release-bin-executable-companion-library">
+ depends="release-bin-executable-companion-library, release-bin-executable-solaris-xpm-files">
<!-- Copy the rcp executable file -->
<copy todir="${release.subdir}" flatten="true" failonerror="true">
<fileset file="${qpidmc.executable}"/>
</copy>
- <chmod dir="${release.subdir}" perm="u+rx" includes="**/*"/>
+ <chmod dir="${release.subdir}" perm="u+rx" includes="qpidmc*"/>
<!-- Copy remaining startup & license files -->
<copy todir="${release.subdir}" flatten="true" failonerror="true">
diff --git a/qpid/java/management/eclipse-plugin/build.xml b/qpid/java/management/eclipse-plugin/build.xml
index 4dd279f721..8513c6487d 100644
--- a/qpid/java/management/eclipse-plugin/build.xml
+++ b/qpid/java/management/eclipse-plugin/build.xml
@@ -70,6 +70,19 @@
<property file="build-release-linux-gtk-x86.properties"/>
<property file="build-release-common.properties"/>
</ant>
+
+ <!-- linux gtk x86_64 -->
+ <ant antfile="build-release.xml">
+ <property file="build-release-linux-gtk-x86_64.properties"/>
+ <property file="build-release-common.properties"/>
+ </ant>
+
+ <!-- solaris gtk sparc -->
+ <ant antfile="build-release.xml">
+ <property file="build-release-solaris-gtk-sparc.properties"/>
+ <property file="build-release-common.properties"/>
+ </ant>
+
<!-- mac os x -->
<ant antfile="build-release-macosx.xml">
<property file="build-release-macosx.properties"/>
diff --git a/qpid/java/management/eclipse-plugin/icons/splash.bmp b/qpid/java/management/eclipse-plugin/icons/splash.bmp
index b528a508c5..cf3b93d523 100644
--- a/qpid/java/management/eclipse-plugin/icons/splash.bmp
+++ b/qpid/java/management/eclipse-plugin/icons/splash.bmp
Binary files differ
diff --git a/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/Constants.java b/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/Constants.java
index 5e05375e28..5a6b3f8856 100644
--- a/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/Constants.java
+++ b/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/Constants.java
@@ -28,12 +28,13 @@ package org.apache.qpid.management.ui;
public class Constants
{
public final static String APPLICATION_NAME = "Qpid Management Console";
+ public static final String DEFAULT_DOMAIN = "org.apache.qpid";
public final static String ACTION_REMOVE_MBEANNODE = "Remove from list";
public final static String VALUE = "value";
public final static String TYPE = "type";
+ public final static String VERSION = "version";
public final static String NODE_TYPE_SERVER = "server";
- public final static String NODE_TYPE_DOMAIN = "domain";
public final static String NODE_TYPE_MBEANTYPE = "mbeantype";
// currently used only for virtual host instances, but will work as general also
public final static String NODE_TYPE_TYPEINSTANCE = "mbeantype_instance";
@@ -80,8 +81,6 @@ public class Constants
public final static String[] EXCHANGE_TYPE_VALUES = {"direct", "fanout", "headers", "topic"};
public final static String[] BOOLEAN_TYPE_VALUES = {"false", "true"};
public final static String[] ATTRIBUTE_TABLE_TITLES = {"Attribute Name", "Value"};
- public static final String[] CONNECTION_PROTOCOLS ={"RMI"};
- public static final String DEFAULT_PROTOCOL = CONNECTION_PROTOCOLS[0];
public final static String ACTION_ADDSERVER = "New Connection";
public final static String ACTION_RECONNECT = "Reconnect";
diff --git a/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/ManagedBean.java b/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/ManagedBean.java
index 31825e925d..ae01f30f32 100644
--- a/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/ManagedBean.java
+++ b/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/ManagedBean.java
@@ -20,13 +20,17 @@
*/
package org.apache.qpid.management.ui;
-import static org.apache.qpid.management.ui.Constants.*;
+import static org.apache.qpid.management.ui.Constants.ADMIN_MBEAN_TYPE;
+import static org.apache.qpid.management.ui.Constants.CONNECTION;
+import static org.apache.qpid.management.ui.Constants.DEFAULT_VH;
+import static org.apache.qpid.management.ui.Constants.EXCHANGE;
+import static org.apache.qpid.management.ui.Constants.QUEUE;
+import static org.apache.qpid.management.ui.Constants.VIRTUAL_HOST;
+
import java.util.HashMap;
/**
* Class representing a managed bean on the managed server
- * @author Bhupendra Bhardwaj
- *
*/
public abstract class ManagedBean extends ManagedObject
{
@@ -36,27 +40,50 @@ public abstract class ManagedBean extends ManagedObject
private String _virtualHostName = null;
private ManagedServer _server = null;
private HashMap _properties = null;
-
+ private int _version;
+
public String getProperty(String key)
{
- return (String)_properties.get(key);
+ return (String) _properties.get(key);
}
-
+
public HashMap getProperties()
{
return _properties;
}
+
public void setProperties(HashMap properties)
{
this._properties = properties;
setName(getProperty("name"));
setType(getProperty("type"));
+ setVersion(getProperty("version"));
_virtualHostName = getProperty(VIRTUAL_HOST);
}
+
+ public void setVersion(String version)
+ {
+ try
+ {
+ _version = Integer.parseInt(version);
+ }
+ catch (NumberFormatException nfe)
+ {
+ _version = 1;
+ }
+
+ }
+
+ public int getVersion()
+ {
+ return _version;
+ }
+
public String getDomain()
{
return _domain;
}
+
public void setDomain(String domain)
{
this._domain = domain;
@@ -66,65 +93,75 @@ public abstract class ManagedBean extends ManagedObject
{
return _server;
}
+
public void setServer(ManagedServer server)
{
this._server = server;
}
+
public String getType()
{
return _type;
}
+
public void setType(String type)
{
this._type = type;
}
+
public String getUniqueName()
{
return _uniqueName;
}
+
public void setUniqueName(String uniqueName)
{
this._uniqueName = uniqueName;
}
-
+
public String getVirtualHostName()
{
// To make it work with the broker with no virtual host implementation
return _virtualHostName == null ? DEFAULT_VH : _virtualHostName;
}
-
+
/**
* Returns mbean instance name. MBeans which have only one instance, the type attribute will be returned
+ *
* @return
*/
public String getInstanceName()
{
if (getName() != null)
+ {
return getName();
+ }
else
+ {
return getType();
+ }
}
-
+
public boolean isQueue()
{
return _type.endsWith(QUEUE);
}
-
+
public boolean isConnection()
{
return _type.endsWith(CONNECTION);
}
-
+
public boolean isExchange()
{
return _type.endsWith(EXCHANGE);
}
-
+
public boolean isTempQueue()
{
return (isQueue() && getName().startsWith("tmp_"));
}
-
+
public boolean isAdmin()
{
return _type.endsWith(ADMIN_MBEAN_TYPE);
diff --git a/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/ManagedServer.java b/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/ManagedServer.java
index 480fdb429a..9ca8787bb5 100644
--- a/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/ManagedServer.java
+++ b/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/ManagedServer.java
@@ -20,20 +20,16 @@
*/
package org.apache.qpid.management.ui;
-import static org.apache.qpid.management.ui.Constants.DEFAULT_PROTOCOL;
/**
* Class representing a server being managed eg. MBeanServer
- * @author Bhupendra Bhardwaj
*/
public class ManagedServer extends ManagedObject
{
private String _host;
private int _port;
- private String _url;
private String _domain;
private String _user;
private String _password;
- private String _protocol = DEFAULT_PROTOCOL;
public ManagedServer(String host, int port, String domain)
{
@@ -46,7 +42,6 @@ public class ManagedServer extends ManagedObject
_host = host;
_port = port;
_domain = domain;
- _url = getRMIURL(host, port);
_user = user;
_password = password;
}
@@ -65,17 +60,7 @@ public class ManagedServer extends ManagedObject
{
return _port;
}
-
- public String getUrl()
- {
- return _url;
- }
- public String getProtocol()
- {
- return _protocol;
- }
-
public String getPassword()
{
return _password;
@@ -96,8 +81,4 @@ public class ManagedServer extends ManagedObject
_user = user;
}
- private String getRMIURL(String host, int port)
- {
- return "service:jmx:rmi:///jndi/rmi://" + host + ":" + port + "/jmxrmi";
- }
}
diff --git a/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/actions/AddServer.java b/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/actions/AddServer.java
index ce7d8816ba..e487c02a67 100644
--- a/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/actions/AddServer.java
+++ b/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/actions/AddServer.java
@@ -35,7 +35,6 @@ import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
-import org.eclipse.swt.widgets.Combo;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Display;
@@ -46,12 +45,9 @@ import org.eclipse.ui.IWorkbenchWindowActionDelegate;
public class AddServer extends AbstractAction implements IWorkbenchWindowActionDelegate
{
- private static final String[] _domains ={"org.apache.qpid"};
-
- private String _transport = DEFAULT_PROTOCOL;
private String _host;
private String _port;
- private String _domain;
+ private String _domain = DEFAULT_DOMAIN;
private String _user;
private String _password;
@@ -73,7 +69,7 @@ public class AddServer extends AbstractAction implements IWorkbenchWindowActionD
{
if (_addServer)
{
- getNavigationView().addNewServer(_transport, _host, Integer.parseInt(_port), _domain, _user, _password);
+ getNavigationView().addNewServer(_host, Integer.parseInt(_port), _domain, _user, _password);
}
}
catch(InfoRequiredException ex)
@@ -91,7 +87,6 @@ public class AddServer extends AbstractAction implements IWorkbenchWindowActionD
_addServer = false;
_host = null;
_port = null;
- _domain = null;
_user = null;
_password = null;
}
@@ -103,6 +98,8 @@ public class AddServer extends AbstractAction implements IWorkbenchWindowActionD
*/
private void createAddServerPopup()
{
+ final Shell appShell = _window.getShell();
+
Display display = Display.getCurrent();
final Shell shell = new Shell(display, SWT.BORDER | SWT.CLOSE);
shell.setText(ACTION_ADDSERVER);
@@ -112,21 +109,23 @@ public class AddServer extends AbstractAction implements IWorkbenchWindowActionD
createWidgets(shell);
shell.pack();
- //get current size dialog, and screen size
- int displayWidth = display.getBounds().width;
- int displayHeight = display.getBounds().height;
+ //get current size dialog, and application window size and location
+ int appWidth = appShell.getBounds().width;
+ int appHeight = appShell.getBounds().height;
+ int appLocX = appShell.getBounds().x;
+ int appLocY = appShell.getBounds().y;
int currentShellWidth = shell.getSize().x;
int currentShellHeight = shell.getSize().y;
//default sizes for the dialog
int minShellWidth = 425;
- int minShellHeight= 290;
+ int minShellHeight= 265;
//ensure this is large enough, increase it if its not
int newShellWidth = currentShellWidth > minShellWidth ? currentShellWidth : minShellWidth;
int newShellHeight = currentShellHeight > minShellHeight ? currentShellHeight : minShellHeight;
- //set the final size and centre the dialog
- shell.setBounds((displayWidth - newShellWidth)/2 , (displayHeight - newShellHeight)/2, newShellWidth, newShellHeight);
+ //set the final size and centre the dialog within the app window
+ shell.setBounds((appWidth - newShellWidth)/2 + appLocX, (appHeight - newShellHeight)/2 + appLocY, newShellWidth, newShellHeight);
shell.open();
_window.getShell().setEnabled(false);
@@ -189,17 +188,6 @@ public class AddServer extends AbstractAction implements IWorkbenchWindowActionD
// Verify if the value entered is numeric
textPort.addVerifyListener(new NumberVerifyListener());
-
- Label domain = new Label(composite, SWT.NONE);
- domain.setText("Domain");
- domain.setLayoutData(new GridData(SWT.TRAIL, SWT.TOP, false, false));
-
- final Combo comboDomain = new Combo(composite, SWT.DROP_DOWN | SWT.READ_ONLY);
- comboDomain.setItems(_domains);
- comboDomain.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false));
- comboDomain.select(0);
-
-
Label user = new Label(composite, SWT.NONE);
user.setText(USERNAME);
user.setLayoutData(new GridData(SWT.TRAIL, SWT.TOP, false, false));
@@ -228,7 +216,7 @@ public class AddServer extends AbstractAction implements IWorkbenchWindowActionD
if (event.character == SWT.ESC)
{
//Escape key acts as cancel on all widgets
- shell.close();
+ shell.dispose();
}
}
});
@@ -283,7 +271,6 @@ public class AddServer extends AbstractAction implements IWorkbenchWindowActionD
return;
}
- _domain = comboDomain.getText();
_addServer = true;
shell.dispose();
}
@@ -314,7 +301,7 @@ public class AddServer extends AbstractAction implements IWorkbenchWindowActionD
if (event.character == SWT.ESC)
{
//Escape key acts as cancel on all widgets
- shell.close();
+ shell.dispose();
}
}
});
diff --git a/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/actions/ReconnectServer.java b/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/actions/ReconnectServer.java
index ce9d80d49b..5eb9d9a168 100644
--- a/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/actions/ReconnectServer.java
+++ b/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/actions/ReconnectServer.java
@@ -99,6 +99,8 @@ public class ReconnectServer extends AbstractAction implements IWorkbenchWindowA
// Create the login popup fot th user to enter usernaem and password
private void createLoginPopup()
{
+ final Shell appShell = _window.getShell();
+
Display display = Display.getCurrent();
final Shell shell = new Shell(display, SWT.BORDER | SWT.CLOSE);
shell.setText(_title);
@@ -108,9 +110,11 @@ public class ReconnectServer extends AbstractAction implements IWorkbenchWindowA
createWidgets(shell);
shell.pack();
- //get current size dialog, and screen size
- int displayWidth = display.getBounds().width;
- int displayHeight = display.getBounds().height;
+ //get current size dialog, and application window size and location
+ int appWidth = appShell.getBounds().width;
+ int appHeight = appShell.getBounds().height;
+ int appLocX = appShell.getBounds().x;
+ int appLocY = appShell.getBounds().y;
int currentShellWidth = shell.getSize().x;
int currentShellHeight = shell.getSize().y;
@@ -121,8 +125,8 @@ public class ReconnectServer extends AbstractAction implements IWorkbenchWindowA
int newShellWidth = currentShellWidth > minShellWidth ? currentShellWidth : minShellWidth;
int newShellHeight = currentShellHeight > minShellHeight ? currentShellHeight : minShellHeight;
- //set the final size and centre the dialog
- shell.setBounds((displayWidth - newShellWidth)/2 , (displayHeight - newShellHeight)/2, newShellWidth, newShellHeight);
+ //set the final size and centre the dialog within the app window
+ shell.setBounds((appWidth - newShellWidth)/2 + appLocX, (appHeight - newShellHeight)/2 + appLocY, newShellWidth, newShellHeight);
shell.open();
_window.getShell().setEnabled(false);
@@ -182,7 +186,7 @@ public class ReconnectServer extends AbstractAction implements IWorkbenchWindowA
if (event.character == SWT.ESC)
{
//Escape key acts as cancel on all widgets
- shell.close();
+ shell.dispose();
}
}
});
@@ -248,7 +252,7 @@ public class ReconnectServer extends AbstractAction implements IWorkbenchWindowA
if (event.character == SWT.ESC)
{
//Escape key acts as cancel on all widgets
- shell.close();
+ shell.dispose();
}
}
});
diff --git a/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/jmx/ClientListener.java b/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/jmx/ClientListener.java
index 2be0ddbebf..c3348b32f0 100644
--- a/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/jmx/ClientListener.java
+++ b/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/jmx/ClientListener.java
@@ -45,7 +45,6 @@ public class ClientListener implements NotificationListener
{
ObjectName objName = null;
String type = notification.getType();
- MBeanUtility.printOutput(type + ":" + objName);
if (MBeanServerNotification.REGISTRATION_NOTIFICATION.equals(type))
{
@@ -60,6 +59,7 @@ public class ClientListener implements NotificationListener
else if (JMXConnectionNotification.FAILED.equals(type))
{
ApplicationRegistry.serverConnectionClosed(server);
+ MBeanUtility.printOutput("Recieved notification from " + server.getName() + ": " + type );
}
}
diff --git a/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/jmx/ClientNotificationListener.java b/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/jmx/ClientNotificationListener.java
index c6ecda4b4c..2af8e681ae 100644
--- a/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/jmx/ClientNotificationListener.java
+++ b/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/jmx/ClientNotificationListener.java
@@ -35,7 +35,6 @@ public class ClientNotificationListener extends ClientListener
public void handleNotification(Notification notification, Object handback)
{
ObjectName objName = (ObjectName)notification.getSource();
- //String type = notification.getType();
getServerRegistry().addNotification(objName, notification);
}
}
diff --git a/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/jmx/JMXServerRegistry.java b/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/jmx/JMXServerRegistry.java
index 945c63f19a..cf3db26f4b 100644
--- a/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/jmx/JMXServerRegistry.java
+++ b/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/jmx/JMXServerRegistry.java
@@ -164,7 +164,6 @@ public class JMXServerRegistry extends ServerRegistry
public void removeManagedObject(ManagedBean mbean)
{
- MBeanUtility.printOutput("Removing MBean:" + mbean.getUniqueName());
if (mbean.isQueue())
{
diff --git a/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/jmx/MBeanUtility.java b/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/jmx/MBeanUtility.java
index 29d7b9c557..479f68de03 100644
--- a/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/jmx/MBeanUtility.java
+++ b/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/jmx/MBeanUtility.java
@@ -440,18 +440,6 @@ public class MBeanUtility
return mbeans;
}
- /**
- * Returns all the domains for the given server. This method can be removed as now this RCP is specific to
- * Qpid and domain is also fixed
- */
- public static List<String> getAllDomains(ManagedServer server) throws Exception
- {
- JMXServerRegistry serverRegistry = (JMXServerRegistry)ApplicationRegistry.getServerRegistry(server);
- MBeanServerConnection mbsc = serverRegistry.getServerConnection();
- String[] domains = mbsc.getDomains();
- return Arrays.asList(domains);
- }
-
public static void printOutput(String statement)
{
if (ApplicationRegistry.debug)
diff --git a/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/MBeanTypeTabControl.java b/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/MBeanTypeTabControl.java
index d4b2ed1db6..7e04e9ac7a 100644
--- a/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/MBeanTypeTabControl.java
+++ b/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/MBeanTypeTabControl.java
@@ -191,7 +191,7 @@ public abstract class MBeanTypeTabControl
*/
protected void createAddButton(Composite parentComposite)
{
- Button _addButton = _toolkit.createButton(parentComposite, "<- Add to Navigation", SWT.PUSH);
+ Button _addButton = _toolkit.createButton(parentComposite, "<- Add selected " + _type + "(s) to navigation tree", SWT.PUSH);
GridData gridData = new GridData(SWT.CENTER, SWT.CENTER, false, false);
_addButton.setLayoutData(gridData);
_addButton.addSelectionListener(new SelectionAdapter(){
@@ -292,7 +292,7 @@ public abstract class MBeanTypeTabControl
protected void setLabelValues()
{
_labelName.setText("Type : " + _type);
- _labelDesc.setText("Select the " + _type + "(s) to add in the Navigation View");
+ _labelDesc.setText("Select the " + _type + "(s) to add to the navigation tree for further interaction.");
_labelList.setText("-- List of " + _type + "s --");
}
diff --git a/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/MBeanView.java b/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/MBeanView.java
index 5476c27871..3c8e52f1d2 100644
--- a/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/MBeanView.java
+++ b/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/MBeanView.java
@@ -30,6 +30,7 @@ import org.apache.qpid.management.ui.ServerRegistry;
import org.apache.qpid.management.ui.exceptions.InfoRequiredException;
import org.apache.qpid.management.ui.jmx.MBeanUtility;
import org.apache.qpid.management.ui.model.AttributeData;
+import org.apache.qpid.management.ui.model.NotificationInfoModel;
import org.apache.qpid.management.ui.model.OperationData;
import org.apache.qpid.management.ui.model.OperationDataModel;
import org.eclipse.jface.viewers.ISelection;
@@ -135,8 +136,7 @@ public class MBeanView extends ViewPart
{
try
{
- if (_selectedNode == null || NODE_TYPE_SERVER.equals(_selectedNode.getType()) ||
- NODE_TYPE_DOMAIN.equals(_selectedNode.getType()) )
+ if (_selectedNode == null || NODE_TYPE_SERVER.equals(_selectedNode.getType()))
{
return;
}
@@ -176,8 +176,7 @@ public class MBeanView extends ViewPart
*/
private void setServer()
{
- if (NODE_TYPE_SERVER.equals(_selectedNode.getType()) ||
- NODE_TYPE_DOMAIN.equals(_selectedNode.getType()) )
+ if (NODE_TYPE_SERVER.equals(_selectedNode.getType()))
{
_server = (ManagedServer)_selectedNode.getManagedObject();
_virtualHostName = null;
@@ -359,6 +358,13 @@ public class MBeanView extends ViewPart
private void createNotificationsTab(TabFolder tabFolder)
{
+ NotificationInfoModel[] items = MBeanUtility.getNotificationInfo(_mbean);
+ if (items == null || items.length == 0)
+ {
+ //the mbean has no notifications to subscribe for, do not create the tab.
+ return;
+ }
+
NotificationsTabControl controller = new NotificationsTabControl(tabFolder);
TabItem tab = new TabItem(tabFolder, SWT.NONE);
diff --git a/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/NavigationView.java b/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/NavigationView.java
index ec8a612d41..b3caf5e415 100644
--- a/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/NavigationView.java
+++ b/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/NavigationView.java
@@ -72,7 +72,8 @@ import org.eclipse.ui.part.ViewPart;
public class NavigationView extends ViewPart
{
public static final String ID = "org.apache.qpid.management.ui.navigationView";
- public static final String INI_FILENAME = System.getProperty("user.home") + File.separator + "qpidManagementConsole.ini";
+ public static final String APP_DIR = System.getProperty("user.home") + File.separator + ".qpidmc";
+ public static final String INI_FILENAME = APP_DIR + File.separator + "qpidmc_navigation.ini";
private static final String INI_SERVERS = "Servers";
private static final String INI_QUEUES = QUEUE + "s";
@@ -130,16 +131,26 @@ public class NavigationView extends ViewPart
{
public void treeExpanded(TreeExpansionEvent event)
{
- _treeViewer.setExpandedState(event.getElement(), true);
- // Following will cause the selection event to be sent, so commented
- // _treeViewer.setSelection(new StructuredSelection(event.getElement()));
- _treeViewer.refresh();
+ getSite().getShell().getDisplay().asyncExec(
+ new Runnable()
+ {
+ public void run()
+ {
+ _treeViewer.refresh();
+ }
+ });
}
public void treeCollapsed(TreeExpansionEvent event)
{
- _treeViewer.setExpandedState(event.getElement(), false);
- _treeViewer.refresh();
+ getSite().getShell().getDisplay().asyncExec(
+ new Runnable()
+ {
+ public void run()
+ {
+ _treeViewer.refresh();
+ }
+ });
}
});
@@ -201,11 +212,11 @@ public class NavigationView extends ViewPart
}
/**
- * Creates Qpid Server connection using JMX RMI protocol
+ * Creates Qpid Server connection
* @param server
* @throws Exception
*/
- private void createRMIServerConnection(ManagedServer server) throws Exception
+ private void createJMXServerConnection(ManagedServer server) throws Exception
{
// Currently Qpid Management Console only supports JMX MBeanServer
ServerRegistry serverRegistry = new JMXServerRegistry(server);
@@ -220,42 +231,32 @@ public class NavigationView extends ViewPart
* @param domain
* @throws Exception
*/
- public void addNewServer(String transportProtocol, String host, int port, String domain, String user, String pwd)
+ public void addNewServer(String host, int port, String domain, String user, String pwd)
throws Exception
{
- String serverAddress = host + ":" + port;
- String url = null;
ManagedServer managedServer = new ManagedServer(host, port, domain, user, pwd);
- if ("RMI".equals(transportProtocol))
+ String server = managedServer.getName();
+ List<TreeObject> list = _serversRootNode.getChildren();
+ for (TreeObject node : list)
{
- url = managedServer.getUrl();
- List<TreeObject> list = _serversRootNode.getChildren();
- for (TreeObject node : list)
+ ManagedServer nodeServer = (ManagedServer)node.getManagedObject();
+ if (server.equals(nodeServer.getName()))
{
- ManagedServer nodeServer = (ManagedServer)node.getManagedObject();
- if (url.equals(nodeServer.getUrl()))
- {
- // Server is already in the list of added servers, so now connect it.
- // Set the server node as selected and then connect it.
- _treeViewer.setSelection(new StructuredSelection(node));
- reconnect(user, pwd);
+ // Server is already in the list of added servers, so now connect it.
+ // Set the server node as selected and then connect it.
+ _treeViewer.setSelection(new StructuredSelection(node));
+ reconnect(user, pwd);
- return;
- }
+ return;
}
-
- // The server is not in the list of already added servers, so now connect and add it.
- managedServer.setName(serverAddress);
- createRMIServerConnection(managedServer);
- }
- else
- {
- throw new InfoRequiredException(transportProtocol + " transport is not supported");
}
+ // The server is not in the list of already added servers, so now connect and add it.
+ createJMXServerConnection(managedServer);
+
// Server connection is successful. Now add the server in the tree
- TreeObject serverNode = new TreeObject(serverAddress, NODE_TYPE_SERVER);
+ TreeObject serverNode = new TreeObject(server, NODE_TYPE_SERVER);
serverNode.setManagedObject(managedServer);
_serversRootNode.addChild(serverNode);
@@ -276,10 +277,12 @@ public class NavigationView extends ViewPart
// Add the Queue/Exchanges/Connections from config file into the navigation tree
addConfiguredItems(managedServer);
+ expandInitialMBeanView(serverNode);
+
_treeViewer.refresh();
// save server address in file
- addServerInConfigFile(serverAddress);
+ addServerInConfigFile(server);
}
/**
@@ -288,6 +291,16 @@ public class NavigationView extends ViewPart
*/
private void createConfigFile()
{
+ File dir = new File(APP_DIR);
+ if (!dir.exists())
+ {
+ if(!dir.mkdir())
+ {
+ System.out.println("Could not create application data directory " + APP_DIR);
+ System.exit(1);
+ }
+ }
+
File file = new File(INI_FILENAME);
try
{
@@ -405,50 +418,33 @@ public class NavigationView extends ViewPart
}
}
- /**
- * Queries the qpid server for MBeans and populates the navigation view with all MBeans for
- * the given server node.
- * @param serverNode
- */
- private void populateServer(TreeObject serverNode) throws Exception
+ //check if the MBeanInfo can be retrieved.
+ private boolean haveAccessPermission(ManagedBean mbean)
{
- ManagedServer server = (ManagedServer) serverNode.getManagedObject();
- String domain = server.getDomain();
- if (!domain.equals(ALL))
- {
- TreeObject domainNode = new TreeObject(domain, NODE_TYPE_DOMAIN);
- domainNode.setParent(serverNode);
-
- populateDomain(domainNode);
+ try
+ {
+ MBeanUtility.getMBeanInfo(mbean);
}
- else
+ catch(Exception ex)
{
- List<TreeObject> domainList = new ArrayList<TreeObject>();
- List<String> domains = MBeanUtility.getAllDomains(server);
-
- for (String domainName : domains)
- {
- TreeObject domainNode = new TreeObject(domainName, NODE_TYPE_DOMAIN);
- domainNode.setParent(serverNode);
-
- domainList.add(domainNode);
- populateDomain(domainNode);
- }
+ return false;
}
+
+ return true;
}
-
+
/**
- * Queries the Qpid Server and populates the given domain node with all MBeans undser that domain.
- * @param domain
- * @throws IOException
+ * Queries the qpid server for MBeans and populates the navigation view with all MBeans for
+ * the given server node.
+ * @param serverNode
* @throws Exception
*/
- private void populateDomain(TreeObject domain) throws IOException, Exception
+ private void populateServer(TreeObject serverNode) throws Exception
{
- ManagedServer server = (ManagedServer) domain.getParent().getManagedObject();
+ ManagedServer server = (ManagedServer) serverNode.getManagedObject();
+ String domain = server.getDomain();
- // Now populate the mbenas under those types
- List<ManagedBean> mbeans = MBeanUtility.getManagedObjectsForDomain(server, domain.getName());
+ List<ManagedBean> mbeans = MBeanUtility.getManagedObjectsForDomain(server, domain);
for (ManagedBean mbean : mbeans)
{
mbean.setServer(server);
@@ -459,13 +455,17 @@ public class NavigationView extends ViewPart
// manually by selecting from MBeanView
if (!(mbean.isConnection() || mbean.isExchange() || mbean.isQueue()))
{
- addManagedBean(domain, mbean);
+ //if we cant get the MBeanInfo then we cant display the mbean, so dont add it to the tree
+ if (haveAccessPermission(mbean))
+ {
+ addManagedBean(serverNode, mbean);
+ }
}
}
// To make it work with the broker without virtual host implementation.
// This will add the default nodes to the domain node
boolean hasVirtualHost = false;
- for (TreeObject child : domain.getChildren())
+ for (TreeObject child : serverNode.getChildren())
{
if (child.getName().startsWith(VIRTUAL_HOST))
{
@@ -475,7 +475,7 @@ public class NavigationView extends ViewPart
}
if (!hasVirtualHost){
- addDefaultNodes(domain);
+ addDefaultNodes(serverNode);
}
}
@@ -540,15 +540,14 @@ public class NavigationView extends ViewPart
}
/**
- * Adds the given MBean to the given domain node. Creates Notification node for the MBean.
+ * Adds the given MBean to the given domain node.
* sample ObjectNames -
* org.apache.qpid:type=VirtualHost.VirtualHostManager,VirtualHost=localhost
* org.apache.qpid:type=VirtualHost.Queue,VirtualHost=test,name=ping_1
- * @param domain
- * @param mbean
- * @throws Exception
+ * @param parent parent tree node to add the mbean to
+ * @param mbean mbean to add
*/
- private void addManagedBean(TreeObject domain, ManagedBean mbean) // throws Exception
+ private void addManagedBean(TreeObject parent, ManagedBean mbean)
{
String name = mbean.getName();
// Split the mbean type into array of Strings, to create hierarchy
@@ -558,7 +557,7 @@ public class NavigationView extends ViewPart
// test->Queue->ping
String[] types = mbean.getType().split("\\.");
TreeObject typeNode = null;
- TreeObject parentNode = domain;
+ TreeObject parentNode = parent;
// Run this loop till all nodes(hierarchy) for this mbean are created. This loop only creates
// all the required parent nodes for the mbean
@@ -638,11 +637,6 @@ public class NavigationView extends ViewPart
{
addItemInConfigFile(mbeanNode);
}
-
- // Add notification node
- // TODO: show this only if the mbean sends any notification
- //TreeObject notificationNode = new TreeObject(NOTIFICATION, NOTIFICATION);
- //notificationNode.setParent(mbeanNode);
}
private TreeObject createTypeNode(TreeObject parent, String name)
@@ -755,7 +749,7 @@ public class NavigationView extends ViewPart
managedServer.setUser(user);
managedServer.setPassword(password);
- createRMIServerConnection(managedServer);
+ createJMXServerConnection(managedServer);
// put the server in the managed server map
_managedServerMap.put(managedServer, selectedNode);
@@ -775,8 +769,31 @@ public class NavigationView extends ViewPart
// Add the Queue/Exchanges/Connections from config file into the navigation tree
addConfiguredItems(managedServer);
+ expandInitialMBeanView(selectedNode);
+
_treeViewer.refresh();
}
+
+ private void expandInitialMBeanView(TreeObject serverNode)
+ {
+ if (serverNode.getChildren().size() == 0 )
+ {
+ return;
+ }
+ else
+ {
+ _treeViewer.setExpandedState(serverNode , true);
+ }
+
+ List<TreeObject> children = serverNode.getChildren();
+ for (TreeObject child : children)
+ {
+ if (child.getChildren().size() > 0)
+ {
+ _treeViewer.setExpandedState(child, true);
+ }
+ }
+ }
/**
* Adds the items(queues/exchanges/connectins) from config file to the server tree
@@ -1157,25 +1174,12 @@ public class NavigationView extends ViewPart
/**
* Adds the mbean to the navigation tree
- * @param mbean
- * @throws Exception
+ * @param mbean mbean to add to the tree
*/
- public void addManagedBean(ManagedBean mbean) // throws Exception
+ public void addManagedBean(ManagedBean mbean)
{
TreeObject treeServerObject = _managedServerMap.get(mbean.getServer());
- List<TreeObject> domains = treeServerObject.getChildren();
- TreeObject domain = null;
- for (TreeObject child : domains)
- {
- if (child.getName().equals(mbean.getDomain()))
- {
- domain = child;
-
- break;
- }
- }
-
- addManagedBean(domain, mbean);
+ addManagedBean(treeServerObject, mbean);
_treeViewer.refresh();
}
@@ -1200,20 +1204,8 @@ public class NavigationView extends ViewPart
for (ManagedBean mbean : removalList)
{
TreeObject treeServerObject = _managedServerMap.get(mbean.getServer());
- List<TreeObject> domains = treeServerObject.getChildren();
- TreeObject domain = null;
- for (TreeObject child : domains)
- {
- if (child.getName().equals(mbean.getDomain()))
- {
- domain = child;
-
- break;
- }
- }
- removeManagedObject(domain, mbean);
- // serverRegistry.removeManagedObject(mbean);
+ removeManagedObject(treeServerObject, mbean);
}
_treeViewer.refresh();
diff --git a/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/OperationTabControl.java b/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/OperationTabControl.java
index 36ad1b4fdc..11df1b6f00 100644
--- a/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/OperationTabControl.java
+++ b/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/OperationTabControl.java
@@ -33,8 +33,6 @@ import static org.apache.qpid.management.ui.Constants.*;
import org.apache.qpid.management.ui.ApplicationRegistry;
import org.apache.qpid.management.ui.ManagedBean;
-import org.apache.qpid.management.ui.ServerRegistry;
-import org.apache.qpid.management.ui.jmx.JMXServerRegistry;
import org.apache.qpid.management.ui.jmx.MBeanUtility;
import org.apache.qpid.management.ui.model.OperationData;
import org.apache.qpid.management.ui.model.ParameterData;
@@ -69,8 +67,6 @@ import org.eclipse.ui.forms.widgets.FormToolkit;
/**
* Control class for the MBean operations tab. It creates the required widgets
* for the selected MBean.
- * @author Bhupendra Bhardwaj
- * @author Robert Gemmell
*/
public class OperationTabControl extends TabControl
{
@@ -521,7 +517,7 @@ public class OperationTabControl extends TabControl
private void populateResults(Object result)
{
Display display = Display.getCurrent();
- int width = 600;
+ int width = 610;
int height = 400;
Shell shell = ViewUtility.createPopupShell(RESULT, width, height);
shell.setImage(ApplicationRegistry.getImage(CONSOLE_IMAGE));
@@ -605,23 +601,37 @@ public class OperationTabControl extends TabControl
return;
}
- // customized for passwords
- if (PASSWORD.equalsIgnoreCase(param.getName()))
+ //Custom handling for the PASSWORD field
+ if (param.getName().equalsIgnoreCase(PASSWORD))
{
+ //Convert the String value to a character array if that is what is required.
if (param.getType().equals("[C"))
{
- try
+ // Retreive the mBean type and version.
+ // If we have a version 1 UserManagement class mbean then it expects the password
+ // to be sent as the hashed version.
+ if (_mbean.getType().equals("UserManagement") && _mbean.getVersion() == 1)
{
- param.setValue(ViewUtility.getHash((String)param.getValue()));
+ try
+ {
+ param.setValue(ViewUtility.getHash((String) param.getValue()));
+ }
+ catch (Exception hashException)
+ {
+ ViewUtility.popupErrorMessage(_form.getText(),
+ "Unable to calculate hash for Password:"
+ + hashException.getMessage());
+ return;
+ }
}
- catch (Exception ex)
+ else
{
- MBeanUtility.handleException(_mbean, ex);
- return;
+ param.setValue(((String) param.getValue()).toCharArray());
}
}
}
// end of customization
+
}
}
@@ -725,7 +735,14 @@ public class OperationTabControl extends TabControl
{
boolean success = Boolean.parseBoolean(result.toString());
String message = success ? OPERATION_SUCCESSFUL : OPERATION_UNSUCCESSFUL;
- ViewUtility.popupInfoMessage(title, message);
+ if(success)
+ {
+ ViewUtility.popupInfoMessage(title, message);
+ }
+ else
+ {
+ ViewUtility.popupErrorMessage(title, message);
+ }
}
else if (_opData.getParameters() != null && !_opData.getParameters().isEmpty())
{
diff --git a/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/QueueTypeTabControl.java b/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/QueueTypeTabControl.java
index 9fcf32abdd..6e37e96695 100644
--- a/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/QueueTypeTabControl.java
+++ b/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/QueueTypeTabControl.java
@@ -271,12 +271,50 @@ public class QueueTypeTabControl extends MBeanTypeTabControl
for (AttributeData data : list)
{
ManagedBean mbean = _queueDepthMap.get(data);
- String value = data.getValue().toString();
- items[i++] = mbean.getName() + " (" + value + " KB)";
+ items[i++] = mbean.getName() + " (" + getQueueDepthString(mbean, data) + ")";
}
getListWidget().setItems(items);
}
+ private String getQueueDepthString(ManagedBean mbean, AttributeData data)
+ {
+ if (mbean.getVersion() == 1) //mbean returns KB
+ {
+ Long value = (Long)data.getValue();
+
+ Double mb = 1024.0;
+
+ if(value > mb) //MB
+ {
+ return String.format("%.3f", (Double)(value / mb)) + " MB";
+ }
+ else //KB
+ {
+ return data.getValue().toString() + " KB";
+ }
+ }
+ else //mbean returns Bytes
+ {
+ Long value = (Long)data.getValue();
+
+ double mb = 1024.0 * 1024.0;
+ double kb = 1024.0;
+
+ if(value >= mb) //MB
+ {
+ return String.format("%.3f", (Double)(value / mb)) + " MB";
+ }
+ else if (value >= kb) //KB
+ {
+ return String.format("%.3f", (Double)(value / kb)) + " KB";
+ }
+ else //Bytes
+ {
+ return data.getValue().toString() + " Bytes";
+ }
+ }
+ }
+
private void sortQueuesByConsumerCount()
{
java.util.List<AttributeData> list = new ArrayList<AttributeData>(_queueConsumerCountMap.keySet());
diff --git a/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/ViewUtility.java b/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/ViewUtility.java
index 5d6a03b238..16bae07e48 100644
--- a/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/ViewUtility.java
+++ b/qpid/java/management/eclipse-plugin/src/main/java/org/apache/qpid/management/ui/views/ViewUtility.java
@@ -39,14 +39,15 @@ import javax.management.openmbean.OpenType;
import javax.management.openmbean.TabularDataSupport;
import javax.management.openmbean.TabularType;
-import org.apache.qpid.management.ui.ApplicationWorkbenchAdvisor;
-import org.eclipse.core.runtime.IStatus;
-import org.eclipse.core.runtime.Status;
-import org.eclipse.jface.dialogs.ErrorDialog;
+import org.apache.commons.codec.binary.Hex;
+
import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.ControlAdapter;
+import org.eclipse.swt.events.ControlEvent;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
+import org.eclipse.swt.graphics.Font;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
@@ -56,12 +57,12 @@ import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.MessageBox;
import org.eclipse.swt.widgets.Shell;
+import org.eclipse.swt.widgets.ScrollBar;
import org.eclipse.swt.widgets.Text;
import org.eclipse.ui.forms.widgets.FormToolkit;
/**
* Utility Class for displaying OpenMbean data types by creating required SWT widgets
- * @author Bhupendra Bhardwaj
*/
public class ViewUtility
{
@@ -89,6 +90,10 @@ public class ViewUtility
SUPPORTED_ARRAY_DATATYPES.add("java.util.Date");
}
+ private static final int DEFAULT_CONTENT_SIZE = 198;
+ static Button _firstButton, _nextButton, _previousButton, _lastButton;
+ static Text _hexNumTextToEnd, _hexNumTextToStart;
+
/**
* Populates the composite with given openmbean data type (TabularType or CompositeType)
* @param toolkit
@@ -190,15 +195,15 @@ public class ViewUtility
layoutData.widthHint = 80;
firstRecordButton.setLayoutData(layoutData);
- final Button nextRecordButton = toolkit.createButton(dataHolder, NEXT, SWT.PUSH);
+ final Button previousRecordButton = toolkit.createButton(dataHolder, PREV, SWT.PUSH);
layoutData = new GridData (GridData.HORIZONTAL_ALIGN_END);
layoutData.widthHint = 80;
- nextRecordButton.setLayoutData(layoutData);
+ previousRecordButton.setLayoutData(layoutData);
- final Button previousRecordButton = toolkit.createButton(dataHolder, PREV, SWT.PUSH);
+ final Button nextRecordButton = toolkit.createButton(dataHolder, NEXT, SWT.PUSH);
layoutData = new GridData (GridData.HORIZONTAL_ALIGN_BEGINNING);
layoutData.widthHint = 80;
- previousRecordButton.setLayoutData(layoutData);
+ nextRecordButton.setLayoutData(layoutData);
final Button lastRecordButton = toolkit.createButton(dataHolder, LAST, SWT.PUSH);
layoutData = new GridData (GridData.HORIZONTAL_ALIGN_BEGINNING);
@@ -352,7 +357,7 @@ public class ViewUtility
}
else
{
- setNotSupportedDataType(toolkit, compositeHolder);
+ handleBinaryMessageContent(toolkit, compositeHolder, data, itemName, encoding);
}
}
// If array of any other supported type, show as a list of String array
@@ -436,6 +441,321 @@ public class ViewUtility
return messageBox.open();
}
+ /**
+ * Creates widgets for object messages and populates the content in hexadecimal format.
+ * @param toolkit
+ * @param compositeHolder
+ * @param data
+ * @param itemName
+ * @param encoding
+ */
+ private static void handleBinaryMessageContent(FormToolkit toolkit, Composite compositeHolder, CompositeData data, String itemName, String encoding)
+ {
+ final String thisEncoding = encoding;
+ final Byte[] arrayItems = (Byte[]) data.get(itemName);
+ final byte[] byteArray = new byte[arrayItems.length];
+
+ for (int i = 0; i < arrayItems.length; i++)
+ {
+ byteArray[i] = arrayItems[i];
+ }
+
+ try
+ {
+ //create a new composite to contain the widgets required to display object messages.
+ final Composite localComposite = toolkit.createComposite(compositeHolder, SWT.NONE);
+ localComposite.setData("currentBytePos", 0);
+ localComposite.setData("startingBytePos", 0);
+ GridLayout layout = new GridLayout(2, true);
+ layout.marginWidth = 0;
+ layout.marginHeight = 0;
+ localComposite.setLayout(layout);
+ localComposite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 3, 1));
+
+ int startContentSize = DEFAULT_CONTENT_SIZE;
+
+ if (byteArray.length < DEFAULT_CONTENT_SIZE)
+ {
+ startContentSize = byteArray.length;
+ }
+
+ //create a text to display the hexadecimal views of object messages, it takes more space than ascii view as
+ //a hex uses 2 chars and 1 space, while ascii only uses 1 char and 1 space.
+ final Text hexText = toolkit.createText(localComposite,
+ new String(displayByteFormat(localComposite, byteArray, startContentSize * 2, thisEncoding, "<<", true)),
+ SWT.READ_ONLY | SWT.MULTI | SWT.WRAP | SWT.V_SCROLL | SWT.BORDER);
+ GridData gridData = new GridData(SWT.FILL, SWT.FILL, true, true, 1, 1);
+ gridData.widthHint = 144; //set to 222 if not using any fonts
+ gridData.heightHint = 200;
+ hexText.setLayoutData(gridData);
+
+ final Text asciiText = toolkit.createText(localComposite,
+ new String(displayByteFormat(localComposite, byteArray, startContentSize * 2, thisEncoding, "<<", false)),
+ SWT.READ_ONLY | SWT.MULTI | SWT.WRAP | SWT.V_SCROLL | SWT.BORDER);
+
+
+ gridData = new GridData(SWT.FILL, SWT.FILL, true, true, 1, 1);
+ gridData.widthHint = 52;//set to 98 if not using any fonts
+ gridData.heightHint = 200;
+ asciiText.setLayoutData(gridData);
+
+ //use a monospaced font for a better layout
+ Font font = new Font(compositeHolder.getDisplay(), "Courier", 10, SWT.NORMAL);
+ hexText.setFont(font);
+ asciiText.setFont(font);
+
+ final ScrollBar hexScrollBar = hexText.getVerticalBar();
+ final ScrollBar asciiScrollBar = asciiText.getVerticalBar();
+
+ //create a sub composite to contain all the buttons
+ final Composite buttonComposite = toolkit.createComposite(localComposite, SWT.NONE);
+ layout = new GridLayout(7, false);
+ layout.marginWidth = 0;
+ buttonComposite.setLayout(layout);
+ buttonComposite.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false, 2, 1));
+
+ _firstButton = toolkit.createButton(buttonComposite, "<<", SWT.PUSH);
+ GridData layoutData = new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING);
+ layoutData.widthHint = 40;
+ _firstButton.setLayoutData(layoutData);
+ _firstButton.setToolTipText("See the first n bytes");
+
+ _previousButton = toolkit.createButton(buttonComposite, "<", SWT.PUSH);
+ layoutData = new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING);
+ layoutData.widthHint = 40;
+ _previousButton.setLayoutData(layoutData);
+ _previousButton.setToolTipText("See the previous n bytes");
+ _previousButton.setEnabled(false);
+
+ _hexNumTextToStart = toolkit.createText(buttonComposite, "0");
+ layoutData = new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING);
+ layoutData.widthHint = 40;
+ _hexNumTextToStart.setLayoutData(layoutData);
+ _hexNumTextToStart.setEditable(false);
+
+ final Text hexNumText = toolkit.createText(buttonComposite, "" + startContentSize);
+ layoutData = new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING);
+ layoutData.widthHint = 40;
+ hexNumText.setLayoutData(layoutData);
+
+ _hexNumTextToEnd = toolkit.createText(buttonComposite, "" + (byteArray.length - startContentSize));
+ layoutData = new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING);
+ layoutData.widthHint = 40;
+ _hexNumTextToEnd.setLayoutData(layoutData);
+ _hexNumTextToEnd.setEditable(false);
+
+ _nextButton = toolkit.createButton(buttonComposite, ">", SWT.PUSH);
+ layoutData = new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING);
+ layoutData.widthHint = 40;
+ _nextButton.setLayoutData(layoutData);
+ _nextButton.setToolTipText("See the next n bytes");
+ _nextButton.setEnabled(true);
+
+ _lastButton = toolkit.createButton(buttonComposite, ">>", SWT.PUSH);
+ layoutData = new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING);
+ layoutData.widthHint = 40;
+ _lastButton.setToolTipText("See the last n bytes");
+ _lastButton.setLayoutData(layoutData);
+
+ SelectionListener listener = new SelectionAdapter()
+ {
+ public void widgetSelected(SelectionEvent e)
+ {
+ if (e.widget instanceof Button)
+ {
+ String numOfBytes = hexNumText.getText();
+ try
+ {
+ int n = Integer.parseInt(numOfBytes);
+
+ //Reset range display if user requests a large value
+ if (n > byteArray.length)
+ {
+ n = (byteArray.length > DEFAULT_CONTENT_SIZE) ? DEFAULT_CONTENT_SIZE : byteArray.length;
+ hexNumText.setText("" + n);
+ }
+
+ //rest if the user requests 0
+ if (n < 1)
+ {
+ n = DEFAULT_CONTENT_SIZE;
+ hexNumText.setText("" + n);
+ }
+
+ Button button = (Button) e.widget;
+ hexText.setText(displayByteFormat(localComposite, byteArray, n * 2, thisEncoding,
+ button.getText(), true));
+ asciiText.setText(displayByteFormat(localComposite, byteArray, n * 2, thisEncoding,
+ button.getText(), false));
+ }
+ catch (NumberFormatException exp)
+ {
+ popupErrorMessage("Error", "Please input the number of bytes you wish to look at");
+ }
+ }
+ if (e.widget instanceof ScrollBar)
+ {
+ //synchronize the movements of the two scrollbars
+ ScrollBar sb = (ScrollBar) e.widget;
+ if (sb.getParent().equals(hexText))
+ {
+ asciiScrollBar.setIncrement(sb.getIncrement());
+ asciiScrollBar.setSelection(sb.getSelection());
+ }
+ else if (sb.getParent().equals(asciiText))
+ {
+ hexScrollBar.setSelection(sb.getSelection());
+ hexScrollBar.setIncrement(sb.getIncrement());
+ }
+ }
+ }
+ };
+ localComposite.addControlListener(new ControlAdapter()
+ {
+ public void controlResized(ControlEvent e)
+ {
+ //if the control is resized, set different parameters to make a single line displays the same contents.
+ if (((GridLayout) localComposite.getLayout()).makeColumnsEqualWidth)
+ {
+ ((GridLayout) localComposite.getLayout()).makeColumnsEqualWidth = false;
+ ((GridLayout) localComposite.getLayout()).numColumns = 2;
+ ((GridData) hexText.getLayoutData()).horizontalSpan = 1;
+ ((GridData) hexText.getLayoutData()).widthHint = 144;
+ ((GridData) asciiText.getLayoutData()).horizontalSpan = 1;
+ ((GridData) asciiText.getLayoutData()).widthHint = 52;
+ ((GridData) buttonComposite.getLayoutData()).horizontalSpan = 2;
+ }
+ else
+ {
+ ((GridLayout) localComposite.getLayout()).makeColumnsEqualWidth = true;
+ ((GridLayout) localComposite.getLayout()).numColumns = 42; //set to 47 if not using any fonts
+ ((GridData) hexText.getLayoutData()).horizontalSpan = 25; // set to 30 if not using any fonts
+ ((GridData) asciiText.getLayoutData()).horizontalSpan = 17; // set to 17 if not using any fonts
+ ((GridData) buttonComposite.getLayoutData()).horizontalSpan = 42;
+ }
+ }
+ });
+
+ _firstButton.addSelectionListener(listener);
+ _previousButton.addSelectionListener(listener);
+ _nextButton.addSelectionListener(listener);
+ _lastButton.addSelectionListener(listener);
+ hexScrollBar.addSelectionListener(listener);
+ asciiScrollBar.addSelectionListener(listener);
+ //f.dispose();
+ }
+ catch (Exception ex)
+ {
+ ex.printStackTrace();
+ }
+ }
+
+ /**
+ * Format object messages to have a hexadecimal view and a ascii view.
+ * @param numOfBytes
+ * @param encoding
+ * @return
+ */
+ private static String displayByteFormat(Composite localComposite, byte[] byteArray, int numOfBytes,
+ String encoding, String direction, boolean isHex)
+ {
+ final Hex hexeconder = new Hex();
+ final byte[] encoded = hexeconder.encode(byteArray);
+
+ int hexLength = byteArray.length * 2;
+ StringBuilder sb = new StringBuilder();
+ int currentBytePos = (Integer) localComposite.getData("currentBytePos");
+ int startingBytePos = (Integer) localComposite.getData("startingBytePos");
+
+ int strLength = 0;
+ int offset = 0;
+ String encStr;
+ if (isHex)
+ {
+ if (direction.equals("<<"))
+ {
+ strLength = (numOfBytes > hexLength) ? hexLength : numOfBytes;
+ offset = 0;
+ }
+ else if (direction.equals("<"))
+ {
+ strLength = (startingBytePos - numOfBytes < 0) ? startingBytePos : numOfBytes;
+ offset = (startingBytePos - numOfBytes < 0) ? 0 : startingBytePos - numOfBytes;
+ }
+ else if (direction.equals(">"))
+ {
+ strLength = (numOfBytes > (hexLength - currentBytePos)) ? hexLength - currentBytePos : numOfBytes;
+ offset = currentBytePos;
+ }
+ else if (direction.equals(">>"))
+ {
+ strLength = (numOfBytes > hexLength) ? hexLength : numOfBytes;
+ offset = (hexLength - numOfBytes > 0) ? hexLength - numOfBytes : 0;
+ }
+ else
+ {
+ strLength = hexLength;
+ offset = 0;
+ }
+ localComposite.setData("strLength", strLength);
+ localComposite.setData("currentBytePos", offset + strLength);
+ localComposite.setData("startingBytePos", offset);
+
+ if (_lastButton != null && !_lastButton.isDisposed())
+ {
+ //Set button state
+ _previousButton.setEnabled(offset != 0);
+ _nextButton.setEnabled(offset + strLength != hexLength);
+
+ //set the text fields
+ _hexNumTextToStart.setText("" + offset / 2);
+ _hexNumTextToEnd.setText("" + (hexLength - (offset + strLength)) / 2);
+ }
+ }
+
+ try
+ {
+ if (isHex)
+ {
+ encStr = new String(encoded, offset, strLength, encoding);
+ for (int c = 0; c < strLength; c++)
+ {
+ sb.append(encStr.charAt(c));
+ if (c % 2 == 1)
+ {
+ sb.append(" ");
+ }
+ }
+ return sb.toString().toUpperCase();
+ }
+ else
+ {
+ strLength = (Integer) localComposite.getData("strLength");
+ sb = new StringBuilder();
+ encStr = new String(byteArray, startingBytePos / 2, strLength / 2, encoding);
+ for (int c = 0; c < encStr.length(); c++)
+ {
+ char ch = encStr.charAt(c);
+ if (ch > 31 && ch < 127)
+ {
+ sb.append(ch);
+ }
+ else
+ {
+ sb.append("?");
+ }
+
+ sb.append(" ");
+ }
+ }
+ }
+ catch (UnsupportedEncodingException e)
+ {
+ e.printStackTrace();
+ }
+ return sb.toString();
+ }
+
public static int popupInfoMessage(String title, String message)
{
return showBox(title, message, SWT.ICON_INFORMATION | SWT.OK);
@@ -448,7 +768,7 @@ public class ViewUtility
public static int popupConfirmationMessage(String title, String message)
{
- return showBox(title, message,SWT.ICON_QUESTION | SWT.YES | SWT.NO | SWT.CANCEL);
+ return showBox(title, message,SWT.ICON_QUESTION | SWT.YES | SWT.NO);
}
diff --git a/qpid/java/management/eclipse-plugin/src/main/resources/linux-gtk-x86/Configuration/config.ini b/qpid/java/management/eclipse-plugin/src/main/resources/linux-gtk-x86/Configuration/config.ini
index be058e2ae5..dc15366740 100644
--- a/qpid/java/management/eclipse-plugin/src/main/resources/linux-gtk-x86/Configuration/config.ini
+++ b/qpid/java/management/eclipse-plugin/src/main/resources/linux-gtk-x86/Configuration/config.ini
@@ -45,4 +45,5 @@ org.eclipse.ui, \
org.eclipse.ui.forms, \
org.eclipse.ui.workbench, \
org.eclipse.equinox.launcher, \
-org.eclipse.equinox.launcher.gtk.linux.x86
+org.eclipse.equinox.launcher.gtk.linux.x86, \
+org.apache.commons.codec
diff --git a/qpid/java/management/eclipse-plugin/src/main/resources/linux-gtk-x86_64/Configuration/config.ini b/qpid/java/management/eclipse-plugin/src/main/resources/linux-gtk-x86_64/Configuration/config.ini
new file mode 100644
index 0000000000..f437e830b5
--- /dev/null
+++ b/qpid/java/management/eclipse-plugin/src/main/resources/linux-gtk-x86_64/Configuration/config.ini
@@ -0,0 +1,49 @@
+###############################################################################
+# 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.
+###############################################################################
+
+#Product Runtime Configuration File
+
+osgi.splashPath=platform:/base/plugins/org.apache.qpid.management.ui
+eclipse.product=org.apache.qpid.management.ui.product
+osgi.bundles.defaultStartLevel=4
+osgi.bundles=jmxremote.sasl, \
+qpid-management-common, \
+org.apache.qpid.management.ui, \
+com.ibm.icu, \
+org.eclipse.core.commands, \
+org.eclipse.core.contenttype, \
+org.eclipse.core.databinding, \
+org.eclipse.core.expressions, \
+org.eclipse.core.jobs, \
+org.eclipse.core.runtime@start, \
+org.eclipse.core.runtime.compatibility.registry, \
+org.eclipse.equinox.app,org.eclipse.equinox.common, \
+org.eclipse.equinox.preferences, \
+org.eclipse.equinox.registry, \
+org.eclipse.help, \
+org.eclipse.jface, \
+org.eclipse.jface.databinding, \
+org.eclipse.swt, \
+org.eclipse.swt.gtk.linux.x86_64, \
+org.eclipse.ui, \
+org.eclipse.ui.forms, \
+org.eclipse.ui.workbench, \
+org.eclipse.equinox.launcher, \
+org.eclipse.equinox.launcher.gtk.linux.x86_64, \
+org.apache.commons.codec
diff --git a/qpid/java/management/eclipse-plugin/src/main/resources/linux-gtk-x86_64/libcairo-swt.so b/qpid/java/management/eclipse-plugin/src/main/resources/linux-gtk-x86_64/libcairo-swt.so
new file mode 100644
index 0000000000..5734427fb8
--- /dev/null
+++ b/qpid/java/management/eclipse-plugin/src/main/resources/linux-gtk-x86_64/libcairo-swt.so
Binary files differ
diff --git a/qpid/java/management/eclipse-plugin/src/main/resources/linux-gtk-x86_64/qpidmc b/qpid/java/management/eclipse-plugin/src/main/resources/linux-gtk-x86_64/qpidmc
new file mode 100644
index 0000000000..ff1f3a7507
--- /dev/null
+++ b/qpid/java/management/eclipse-plugin/src/main/resources/linux-gtk-x86_64/qpidmc
Binary files differ
diff --git a/qpid/java/management/eclipse-plugin/src/main/resources/linux-gtk-x86_64/qpidmc.ini b/qpid/java/management/eclipse-plugin/src/main/resources/linux-gtk-x86_64/qpidmc.ini
new file mode 100644
index 0000000000..19ceb6f717
--- /dev/null
+++ b/qpid/java/management/eclipse-plugin/src/main/resources/linux-gtk-x86_64/qpidmc.ini
@@ -0,0 +1,37 @@
+###############################################################################
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+###############################################################################
+
+-vmargs
+-Xms40m
+-Xmx256m
+-XX:MaxPermSize=256m
+-Dosgi.requiredJavaVersion=1.5
+-Declipse.consoleLog=true
+
+#===============================================
+# SSL trust store configuration options.
+#===============================================
+
+# Uncomment lines below to specify custom truststore for server SSL
+# certificate verification, eg when using self-signed server certs.
+#
+#-Djavax.net.ssl.trustStore=<path.to.truststore>
+#-Djavax.net.ssl.trustStorePassword=<truststore.password>
+
+
diff --git a/qpid/java/management/eclipse-plugin/src/main/resources/macosx/Configuration/config.ini b/qpid/java/management/eclipse-plugin/src/main/resources/macosx/Configuration/config.ini
index a7c671ce2d..3ac3aa20f3 100644
--- a/qpid/java/management/eclipse-plugin/src/main/resources/macosx/Configuration/config.ini
+++ b/qpid/java/management/eclipse-plugin/src/main/resources/macosx/Configuration/config.ini
@@ -45,4 +45,5 @@ org.eclipse.ui, \
org.eclipse.ui.forms, \
org.eclipse.ui.workbench, \
org.eclipse.equinox.launcher, \
-org.eclipse.equinox.launcher.carbon.macosx
+org.eclipse.equinox.launcher.carbon.macosx, \
+org.apache.commons.codec
diff --git a/qpid/java/management/eclipse-plugin/src/main/resources/qpid-management-common-plugin/MANIFEST.MF b/qpid/java/management/eclipse-plugin/src/main/resources/qpid-management-common-plugin/MANIFEST.MF
index 5ef0c78606..818daef003 100644
--- a/qpid/java/management/eclipse-plugin/src/main/resources/qpid-management-common-plugin/MANIFEST.MF
+++ b/qpid/java/management/eclipse-plugin/src/main/resources/qpid-management-common-plugin/MANIFEST.MF
@@ -8,4 +8,4 @@ Export-Package: org.apache.qpid.management.common,
org.apache.qpid.management.common.sasl
Bundle-Vendor:
Bundle-Localization: plugin
-Require-Bundle: jmxremote.sasl
+Require-Bundle: jmxremote.sasl;resolution:=optional
diff --git a/qpid/java/management/eclipse-plugin/src/main/resources/solaris-gtk-sparc/Configuration/config.ini b/qpid/java/management/eclipse-plugin/src/main/resources/solaris-gtk-sparc/Configuration/config.ini
new file mode 100644
index 0000000000..a99a8b3f7d
--- /dev/null
+++ b/qpid/java/management/eclipse-plugin/src/main/resources/solaris-gtk-sparc/Configuration/config.ini
@@ -0,0 +1,49 @@
+###############################################################################
+# 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.
+###############################################################################
+
+#Product Runtime Configuration File
+
+osgi.splashPath=platform:/base/plugins/org.apache.qpid.management.ui
+eclipse.product=org.apache.qpid.management.ui.product
+osgi.bundles.defaultStartLevel=4
+osgi.bundles=jmxremote.sasl, \
+qpid-management-common, \
+org.apache.qpid.management.ui, \
+com.ibm.icu, \
+org.eclipse.core.commands, \
+org.eclipse.core.contenttype, \
+org.eclipse.core.databinding, \
+org.eclipse.core.expressions, \
+org.eclipse.core.jobs, \
+org.eclipse.core.runtime@start, \
+org.eclipse.core.runtime.compatibility.registry, \
+org.eclipse.equinox.app,org.eclipse.equinox.common, \
+org.eclipse.equinox.preferences, \
+org.eclipse.equinox.registry, \
+org.eclipse.help, \
+org.eclipse.jface, \
+org.eclipse.jface.databinding, \
+org.eclipse.swt, \
+org.eclipse.swt.gtk.solaris.sparc, \
+org.eclipse.ui, \
+org.eclipse.ui.forms, \
+org.eclipse.ui.workbench, \
+org.eclipse.equinox.launcher, \
+org.eclipse.equinox.launcher.gtk.solaris.sparc, \
+org.apache.commons.codec
diff --git a/qpid/java/management/eclipse-plugin/src/main/resources/solaris-gtk-sparc/Qpidmc.l.pm b/qpid/java/management/eclipse-plugin/src/main/resources/solaris-gtk-sparc/Qpidmc.l.pm
new file mode 100644
index 0000000000..995d7c9bb0
--- /dev/null
+++ b/qpid/java/management/eclipse-plugin/src/main/resources/solaris-gtk-sparc/Qpidmc.l.pm
@@ -0,0 +1,311 @@
+/* XPM */
+static char *ProductIcon48[] = {
+/* columns rows colors chars-per-pixel */
+"48 48 257 2",
+" c black",
+". c gray100",
+"X c #69695A5AE8E8",
+"o c #494949499191",
+"O c #CECE9292BFBF",
+"+ c #E7E7CACAE0E0",
+"@ c #C8C88C8CBBBB",
+"# c #C2C28A8ABABA",
+"$ c #EAEAD7D7E8E8",
+"% c #CFCFA9A9CCCC",
+"& c #D9D9BCBCD8D8",
+"* c #B6B68787B9B9",
+"= c #C3C39999C7C7",
+"- c #A7A77D7DB5B5",
+"; c #BDBDA3A3CDCD",
+": c #D8D8CACAE3E3",
+"> c #A8A88D8DC4C4",
+", c #92927575B2B2",
+"< c #87876C6CAAAA",
+"1 c #9A9A8383BABA",
+"2 c #7B7B6363A3A3",
+"3 c #666654549595",
+"4 c #73735F5FADAD",
+"5 c #626251519292",
+"6 c #7F7F7272A7A7",
+"7 c #6D6D5E5E9E9E",
+"8 c #64645454A9A9",
+"9 c #77776969B1B1",
+"0 c #49493E3E8282",
+"q c #7D7D7373B6B6",
+"w c #5B5B4E4EADAD",
+"e c #55554949BABA",
+"r c #56564949BABA",
+"t c #56564A4ABABA",
+"y c #56564949B9B9",
+"u c #55554949B8B8",
+"i c #4F4F4444ACAC",
+"p c #53534848B4B4",
+"a c #53534848B3B3",
+"s c #54544949B5B5",
+"d c #52524747B0B0",
+"f c #52524747AFAF",
+"g c #54544949B3B3",
+"h c #DEDEDCDCEEEE",
+"j c #3E3E36369898",
+"k c #43433B3B9F9F",
+"l c #33332C2C7777",
+"z c #42423A3A9C9C",
+"x c #4A4A4040A8A8",
+"c c #55554A4ABABA",
+"v c #55554A4AB9B9",
+"b c #54544949B7B7",
+"n c #52524848B1B1",
+"m c #51514747AEAE",
+"M c #4E4E4545A9A9",
+"N c #49494141A0A0",
+"B c #52524848AFAF",
+"V c #51514848AEAE",
+"C c #50504747ACAC",
+"Z c #4F4F4646AAAA",
+"A c #51514848ADAD",
+"S c #50504747ABAB",
+"D c #50504848ACAC",
+"F c #50504747A9A9",
+"G c #4E4E4646A7A7",
+"H c #4E4E4545A4A4",
+"J c #4D4D4545A4A4",
+"K c #4F4F4747A8A8",
+"L c #4E4E4646A5A5",
+"P c #4D4D4545A3A3",
+"I c #3B3B35357D7D",
+"U c #4E4E4646A3A3",
+"Y c #55554D4D9F9F",
+"T c #4A4A43438989",
+"R c #51514B4B9090",
+"E c #67676060A5A5",
+"W c #1D1D18186A6A",
+"Q c #272722227D7D",
+"! c #282823237D7D",
+"~ c #2B2B26268181",
+"^ c #33332C2C8989",
+"/ c #3B3B36368E8E",
+"( c #454540409797",
+") c #4D4D4646A4A4",
+"_ c #4C4C4545A1A1",
+"` c #4D4D4646A2A2",
+"' c #4B4B4545A0A0",
+"] c #4D4D4646A1A1",
+"[ c #4C4C45459F9F",
+"{ c #4B4B45459E9E",
+"} c #4A4A44449C9C",
+"| c #494944449898",
+" . c #484843439696",
+".. c #4A4A45459999",
+"X. c #4F4F4A4AA0A0",
+"o. c #68686363AAAA",
+"O. c #21211D1D7676",
+"+. c #242420207575",
+"@. c #2D2D2A2A7F7F",
+"#. c #2D2D2A2A7B7B",
+"$. c #3D3D39398F8F",
+"%. c #484844449696",
+"&. c #474743439393",
+"*. c #464643439191",
+"=. c #454542428E8E",
+"-. c #4D4D4A4A9C9C",
+";. c #57575454A3A3",
+":. c #5A5A58589797",
+">. c #5F5F5D5D9999",
+",. c #85858282C1C1",
+"<. c #95959292C9C9",
+"1. c #B8B8B6B6DCDC",
+"2. c #070705055353",
+"3. c #080807075555",
+"4. c #0A0A09095757",
+"5. c #0C0C0B0B5858",
+"6. c #0F0F0D0D5C5C",
+"7. c #10100F0F5C5C",
+"8. c #131311116464",
+"9. c #141413136060",
+"0. c #141413135F5F",
+"q. c #171715156767",
+"w. c #161615156262",
+"e. c #161615156161",
+"r. c #181817176464",
+"t. c #1A1A19196666",
+"y. c #1C1C1A1A6464",
+"u. c #1D1D1C1C6868",
+"i. c #1F1F1E1E6A6A",
+"p. c #222221216C6C",
+"a. c #242423236F6F",
+"s. c #272725257171",
+"d. c #272726267272",
+"f. c #272726267171",
+"g. c #292928287474",
+"h. c #2A2A29297474",
+"j. c #2C2C2B2B7777",
+"k. c #2F2F2E2E7C7C",
+"l. c #2E2E2D2D7979",
+"z. c #343433337E7E",
+"x. c #393937378686",
+"c. c #373736368181",
+"v. c #3A3A39398484",
+"b. c #3A3A39398383",
+"n. c #3D3D3B3B8686",
+"m. c #424241418C8C",
+"M. c #424241418B8B",
+"N. c #444442428B8B",
+"B. c #434341418989",
+"V. c #454544448E8E",
+"C. c #454544448D8D",
+"Z. c #424241418787",
+"A. c #434342428888",
+"S. c #444442428787",
+"D. c #424241418585",
+"F. c #414140408383",
+"G. c #484847479090",
+"H. c #434342428686",
+"J. c #4A4A49499393",
+"K. c #464645458A8A",
+"L. c #4D4D4C4C9595",
+"P. c #54545252A0A0",
+"I. c #50504F4F9898",
+"U. c #58585757A0A0",
+"Y. c #525250509393",
+"T. c #5B5B5959A2A2",
+"R. c #585857579F9F",
+"E. c #62626161A9A9",
+"W. c #64646363ACAC",
+"Q. c #6B6B6A6AB2B2",
+"!. c #6B6B6A6AB1B1",
+"~. c #75757474B8B8",
+"^. c #7F7F7D7DBDBD",
+"/. c #9C9C9B9BCFCF",
+"(. c #0B0B0B0B5858",
+"). c #0D0D0D0D5A5A",
+"_. c #111111115E5E",
+"`. c #131313136060",
+"'. c #212121216D6D",
+"]. c #242424246F6F",
+"[. c #2B2B2C2C7777",
+"{. c #2B2B2B2B7777",
+"}. c #2C2C2C2C7777",
+"|. c #2E2E2E2E7979",
+" X c #313131317C7C",
+".X c #313131317B7B",
+"XX c #343434347E7E",
+"oX c #3C3C3C3C8686",
+"OX c #3F3F3F3F8989",
+"+X c #414142428B8B",
+"@X c #424242428B8B",
+"#X c #474747479090",
+"$X c #414141418484",
+"%X c #404040408181",
+"&X c #4A4A4A4A9494",
+"*X c #4A4A4A4A9393",
+"=X c #4D4D4D4D9696",
+"-X c #4F4F4F4F9898",
+";X c #505050509898",
+":X c #525252529B9B",
+">X c #555555559E9E",
+",X c #555555559D9D",
+"<X c #57575858A0A0",
+"1X c #58585858A0A0",
+"2X c #575758589F9F",
+"3X c #575757579F9F",
+"4X c #5A5A5A5AA2A2",
+"5X c #5D5D5D5DA5A5",
+"6X c #5F5F5F5FA7A7",
+"7X c #61616262AAAA",
+"8X c #61616161A9A9",
+"9X c #61616262A9A9",
+"0X c #62626262AAAA",
+"qX c #64646464ACAC",
+"wX c #62626262A9A9",
+"eX c #64646464ABAB",
+"rX c #66666666AEAE",
+"tX c #66666666ADAD",
+"yX c #68686868B0B0",
+"uX c #69696969AFAF",
+"iX c #6D6D6D6DB4B4",
+"pX c #6F6F6F6FB5B5",
+"aX c #73737373BABA",
+"sX c #71717171B7B7",
+"dX c #76767676BCBC",
+"fX c #79797979BFBF",
+"gX c #77777777B9B9",
+"hX c #80808080C1C1",
+"jX c #8C8C8C8CC5C5",
+"kX c #90909090C9C9",
+"lX c #98989898CBCB",
+"zX c #A0A0A0A0CFCF",
+"xX c #A5A5A5A5D3D3",
+"cX c #ABABABABD6D6",
+"vX c #C4C4C4C4E3E3",
+"bX c #D1D1D1D1E9E9",
+"nX c #E5E5E5E5F3F3",
+"mX c #9F9FA0A0D1D1",
+"MX c #B6B6C5C5E5E5",
+"NX c #8E8EA6A6D6D6",
+"BX c #9090A7A7D7D7",
+"VX c #9191A9A9D7D7",
+"CX c #9595ABABD8D8",
+"ZX c #9999AFAFDADA",
+"AX c #9D9DB2B2DCDC",
+"SX c #A1A1B5B5DDDD",
+"DX c #A5A5B8B8DEDE",
+"FX c #A9A9BBBBE0E0",
+"GX c #ACACBDBDE1E1",
+"HX c #B0B0C1C1E3E3",
+"JX c #B4B4C4C4E4E4",
+"KX c #B8B8C7C7E5E5",
+"LX c #BBBBC9C9E6E6",
+"PX c #AEAEC0C0E2E2",
+"IX c #B2B2C3C3E3E3",
+"UX c gray100",
+"YX c None",
+/* pixels */
+"YXX X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X YX",
+"X %X%X%XF.F.F.F.$XD.Z.Z.Z.B.B.B.N.N.=.=.=.*.*.*.&.&. . .| ....} } { { _ _ P P H G G G K S S C o ",
+"X %X%X%X%XF.F.$XD.D.Z.Z.B.A.B.N.N.N.=.=.=.*.*.&.&.%.%.%.| | ..} { { [ _ _ ` U J L G K F Z S C o ",
+"X %X%X%X%XF.F.F.D.D.H.Z.Z.A.B.N.N.N.C.=.=.*.*.&.&. . .%.| | ..} } { [ [ _ P P H G G K F S S C o ",
+"X %XF.%XF.F.$XF.$XZ.Z.Z.B.A.K.Y.7 , - - 1 1 ^.^.~.aX~.q 9 6XY { } { ' _ ] P P H L G K F Z S C o ",
+"X %XF.F.F.F.F.D.D.Z.Z.Z.K.:.1 ; % ; <.hXfXfXdXaXaXsXpXiX!.yXrXo.;.X.[ _ _ ` H H G K K F S S C o ",
+"X F.F.F.F.F.D.D.D.Z.H.Y.1 & & 1.cXmX/.kXfXdXaXaXsXpXiXQ.yXtXeXE.6X5XP.X._ ` J L G G K F Z S C o ",
+"X D.$XF.$XD.D.Z.Z.S.>.% + : vX1.1.cXmX/.dXaXaXsXpXiXQ.uXrXqX8X6X5XT.R.P.X.P ) H G K K S S S m o ",
+"X D.$XD.D.D.D.D.S.6 & $ h bXvXvX1.xX/.kXfXaXsXpXiXQ.yXrXW.E.6X5X4XU.,X:XI.-.` L G G K F Z C C o ",
+"X D.D.D.D.D.Z.H.6 & $ h h h bXvX1.cXmXkX,.dXpXiXQ.yXtXqXwX6X5XT.U.,X:XI.=X*X..` G K K Z S S m o ",
+"X Z.D.Z.H.Z.Z.7 & $ h h nXh bXvX1.cXmXkX,.gXiXQ.uXrXW.E.6X5X4XU.,X:X-XL.J.#XV. .P G F S S C m o ",
+"X Z.Z.Z.H.Z.R % + : bXh h h bXvX1.cX/.kXhX~.Q.yXrXqX9X6X5X4X2X,X:X;X=X*X#XV.M.OX( K Z S S C m o ",
+"X Z.Z.Z.A.A.* & & vXvXbXbXbXvXvX1.xXlXjX^.pXuXrXeXwX6X5X4XU.,X:X-XL.*XG.V.@XOXoXb.( Z S C C V o ",
+"X B.B.B.A.2 % % 1.1.vXvXvXvXvX1.cXzX<.,.gXiXrXW.E.6X5X4XU.,X:XI.=X*X#XV.@XOXn.b.c.x.N S S C m o ",
+"X B.B.B.S.* % ; xX1.1.1.1.1.cXcXzXlXjX^.pXrXeX7X6X5X4XR.,X:X-XL.J.#XV.@XOXn.b.c.XX X$.S C C m o ",
+"X N.N.N.2 O = /.mXxXcXcXcXcXxXzXlXjXhX~.uXeXE.6X5X4XU.,X:X-XL.J.#XV.M.OXn.v.c.z. X|.k.N D V f o ",
+"X N.N.N.- @ > kX<././.mXzXzXlX<.jXhXgXuXeXE.6X5X4X1X,X:XI.L.*X#XV.m.OXn.b.c.z. Xl.j.g./ C m V o ",
+"X N.N.R @ # ,.,.jXkXkX<.kXkXjX,.^.~.uXwXE.6X5X4X1X,X:XI.=XJ.#XC.M.OXn.v.c.z..X|.j.g.d.#.M m B o ",
+"X =.M.< @ * fXfXhXhX,.,.,.hX^.gXpXuXqX9X6X5X4XU.,X:XI.L.*XG.V.+XOXn.b.c.z..X|.[.g.d.a.p.z V B o ",
+"X =.N.- @ NXNXBXBXBXVXCXCXCXCXZXZXZXZXAXAXSXSXSXDXDXDXFXFXFXGXPXPXHXHXIXJXMXMXMXKXKXLXLXLXB d o ",
+"X =.=.* @ 1 dXdXaXaXsXpXiX!.yXrXeXwX6X5X4X<X,X:XI.=X*XG.V.M.OXn.v.c.XX.X|.j.g.d.a.p.i.u.@.f d o ",
+"X *.=.# @ ^.dXaXaXsXpXiXQ.yXrXeXwX6X5XT.U.,X:X-XL.&XG.C.m.OXoXv.c.z..X|.j.g.f.a.p.i.u.t.+.d d o ",
+"X *.*.@ @ NXNXNXBXVXVXCXCXCXCXZXZXZXZXAXAXAXSXSXDXDXDXFXFXGXGXPXPXHXHXJXJXJXMXKXKXKXLXLXLXd n o ",
+"X &.*.@ @ dXaXsXpXiXQ.yXtXeXE.6X5X4XU.>X:XI.L.*XG.V.m.OXoXv.c.z. X|.j.g.d.a.'.i.u.t.r.w.9.d n o ",
+"X &.&.@ @ ~.sXpXiXQ.yXtXW.E.6X5X4X1X,X:XI.=X*X#XC.m.OXn.b.c.z. X|.[.g.f.a.p.i.u.t.r.w.9.0.n a o ",
+"X &.&.@ @ NXNXBXBXVXVXVXCXCXCXZXZXZXZXAXAXSXSXSXDXDXDXFXFXGXGXPXPXHXIXIXJXMXMXKXKXKXLXLXLXn n o ",
+"X %. .# @ q iXQ.yXrXW.0X6X5X4XU.>X:XI.L.*X#XV.@XOXn.b.c.XX.X|.{.g.f.].'.i.u.t.r.w.0._.7.W n a o ",
+"X %. .* # , Q.yXtXeX7X6X5X4XU.,X:X-XL.*X#XV.@XOXn.b.c.XX Xl.{.g.d.a.p.i.u.t.r.e.0._.7.).+.a a o ",
+"X | | - # NXNXNXBXVXVXCXCXCXCXZXZXZXAXAXAXAXSXSXDXDXDXFXFXGXGXPXPXHXHXIXJXMXMXMXKXKXLXLXLXa a o ",
+"X | | < # - rXeX9X6X5X4XU.,X:X-XL.*X#XC.@XOXoXb.c.z. X|.j.h.s.a.'.i.u.t.r.w.9._.7.).5.4.j a p o ",
+"X | } Y # * 9 8X6X5X4X3X,X:XI.=X*XG.V.@XOXn.v.c.XX X|.j.g.f.a.p.i.u.t.r.e.0._.7.).5.4.q.i g p o ",
+"X } } | - # , 6X5X4XR.,X:XI.=X*XG.V.m.OXoXb.c.XX X|.j.g.f.a.p.i.u.t.r.e.9._.7.).5.4.3.~ a s s o ",
+"X } } } 4 # - E 4XU.>X:X-X=XJ.#XV.M.OXoXb.c.XX X|.{.h.d.a.'.i.u.t.r.e.9._.7.).5.4.3.6.z p s s o ",
+"X { { } } - # < U.,X:XI.=X*XG.V.+XOXoXb.c.z. X|.}.g.d.a.'.i.u.t.r.w.0._.7.).5.4.3.2.! g p s s o ",
+"X [ { ' [ 4 * - E :X;XL.J.#XV.m.OXoXb.c.z..X|.j.h.f.a.'.i.u.t.r.w.9._.6.).(.4.3.2.8.k p s s s o ",
+"X [ [ ' _ [ , * , ;XL.J.#XV.@XOXoXv.c.z..X|.{.g.f.a.p.i.u.t.r.w.`._.7.).(.4.3.2.2.^ s p s s s o ",
+"X _ _ _ _ P ] - * 2 *X#XV.m.OXn.v.c.XX X|.j.h.f.a.p.i.u.t.r.w.`._.7.).(.4.3.2.2.Q p s s s b u o ",
+"X ` ` ` ` ` ` 8 - - 7 V.@XOXoXv.c.XX.X|.j.g.d.a.'.i.u.t.r.w.0._.7.).5.4.3.2.2.O.x p s s s u u o ",
+"X P P ) P U U ) 8 - - 7 OXn.v.c.XX X|.j.h.f.a.p.i.u.t.r.w.0._.7.).5.4.3.2.2.O.x s s s s b u u o ",
+"X L L ) H ) L L L 8 1 - 7 b.c.z. X|.j.h.f.a.'.i.u.t.r.w.0._.7.).5.4.3.2.2.Q x p s s s b b u e o ",
+"X L G L G G G G G G G , * 2 T .Xl.j.h.f.a.p.i.u.t.r.e.0._.7.).5.4.3.2.8.^ p p s s s s u u e e o ",
+"X G G G G G G G K K M M 4 , , 3 I g.d.a.p.i.u.t.r.e.`._.7.).5.4.3.7.! k p s p s s s u u u e v o ",
+"X K G K K K K K K Z Z M F F 4 , < 3 I p.i.u.t.r.w.9._.7.).5.4.W ~ z a p p s s b s u u u e e e o ",
+"X F Z F F F F Z Z F F S S S S S w 9 < 2 5 0 l p.e.9.y.a.l ^ j i a p p p s s b b b u e v y r e o ",
+"X S Z Z S Z S Z S S S S S C C C A m d V f m B m B d d n d a a a p s p s s b u u u u e v e r t o ",
+"X S S S S S S S S S S C C C m m A V V B B B d d d n n a a a p p s p s s b u u u e e e c t r t o ",
+"X C C C C C C C C m C A m A m f V f f B d d d n n n a a a a s s s s s u b u u u u v t t r t t o ",
+"YXo o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o YX"
+};
diff --git a/qpid/java/management/eclipse-plugin/src/main/resources/solaris-gtk-sparc/Qpidmc.m.pm b/qpid/java/management/eclipse-plugin/src/main/resources/solaris-gtk-sparc/Qpidmc.m.pm
new file mode 100644
index 0000000000..e64aa0cc06
--- /dev/null
+++ b/qpid/java/management/eclipse-plugin/src/main/resources/solaris-gtk-sparc/Qpidmc.m.pm
@@ -0,0 +1,295 @@
+/* XPM */
+static char *ProductIcon32[] = {
+/* columns rows colors chars-per-pixel */
+"32 32 257 2",
+" c black",
+". c gray100",
+"X c #69695A5AE8E8",
+"o c #494949499191",
+"O c #E8E8CBCBE0E0",
+"+ c #DDDDB3B3D2D2",
+"@ c #F0F0DDDDEBEB",
+"# c #CDCD9191BEBE",
+"$ c #C8C88B8BBBBB",
+"% c #CACA9898C2C2",
+"& c #C3C38A8ABBBB",
+"* c #BABA8787B9B9",
+"= c #DCDCC4C4DEDE",
+"- c #C5C5A3A3CACA",
+"; c #ADAD8181B8B8",
+": c #A3A37A7AB5B5",
+"> c #E2E2D6D6E9E9",
+", c #B3B39A9AC4C4",
+"< c #EBEBE3E3F0F0",
+"1 c #C9C9B6B6D6D6",
+"2 c #96967676B8B8",
+"3 c #8C8C7171ABAB",
+"4 c #A4A49292BEBE",
+"5 c #7D7D6565A6A6",
+"6 c #83836D6DABAB",
+"7 c #9A9A8787C2C2",
+"8 c #7B7B6464B7B7",
+"9 c #5E5E50509191",
+"0 c #646457579A9A",
+"q c #85857B7BBEBE",
+"w c #7C7C7373B6B6",
+"e c #62625353D5D5",
+"r c #61615353D4D4",
+"t c #60605252D1D1",
+"y c #5F5F5252D0D0",
+"u c #5F5F5151CFCF",
+"i c #60605353D2D2",
+"p c #5F5F5252CFCF",
+"a c #5E5E5151CDCD",
+"s c #5C5C4F4FC7C7",
+"d c #5F5F5252CDCD",
+"f c #5E5E5151CBCB",
+"g c #5B5B4F4FC4C4",
+"h c #5A5A4E4EC1C1",
+"j c #71716969B0B0",
+"k c #48483E3EADAD",
+"l c #5D5D5151CDCD",
+"z c #5C5C5050C9C9",
+"x c #5D5D5151CBCB",
+"c c #5C5C5050C7C7",
+"v c #5B5B4F4FC6C6",
+"b c #5B5B5050C6C6",
+"n c #59594E4EC1C1",
+"m c #58584D4DBFBF",
+"M c #59594F4FC2C2",
+"N c #5A5A4F4FC2C2",
+"B c #58584D4DBCBC",
+"V c #57574D4DBCBC",
+"C c #59594E4EBEBE",
+"Z c #58584E4EBDBD",
+"A c #58584D4DBBBB",
+"S c #57574D4DBABA",
+"D c #56564D4DB9B9",
+"F c #56564C4CB6B6",
+"G c #55554C4CB6B6",
+"H c #54544B4BB4B4",
+"J c #54544B4BB1B1",
+"K c #53534B4BB1B1",
+"L c #52524A4AAEAE",
+"P c #51514949ACAC",
+"I c #51514949ABAB",
+"U c #474741418787",
+"Y c #32322C2C8F8F",
+"T c #2B2B25257777",
+"R c #36362F2F9696",
+"E c #2B2B26266E6E",
+"W c #4D4D4545ACAC",
+"Q c #55554D4DB8B8",
+"! c #54544C4CB4B4",
+"~ c #54544C4CB3B3",
+"^ c #51514A4AACAC",
+"/ c #51514A4AABAB",
+"( c #50504949A9A9",
+") c #4F4F4949A6A6",
+"_ c #4C4C4747A1A1",
+"` c #4E4E4848A3A3",
+"' c #4D4D4848A1A1",
+"] c #4B4B46469C9C",
+"[ c #4C4C47479E9E",
+"{ c #51514C4CA6A6",
+"} c #A9A9A6A6D5D5",
+"| c #1E1E1A1A6666",
+" . c #292925258181",
+".. c #3D3D39399292",
+"X. c #4A4A46469B9B",
+"o. c #53534E4EABAB",
+"O. c #494945459797",
+"+. c #4A4A46469999",
+"@. c #474744449494",
+"#. c #484845459494",
+"$. c #474744449292",
+"%. c #464643439090",
+"&. c #464642428D8D",
+"*. c #54545050A9A9",
+"=. c #474744448F8F",
+"-. c #4C4C49499999",
+";. c #57575454A6A6",
+":. c #5B5B5757AAAA",
+">. c #545451519B9B",
+",. c #5A5A57579C9C",
+"<. c #65656262A7A7",
+"1. c #68686666A2A2",
+"2. c #CACAC9C9E5E5",
+"3. c #050504045151",
+"4. c #080807075454",
+"5. c #0A0A09095858",
+"6. c #0C0C0A0A5858",
+"7. c #10100E0E6262",
+"8. c #0E0E0D0D5A5A",
+"9. c #121211115D5D",
+"0. c #131312125D5D",
+"q. c #161615156161",
+"w. c #171716166161",
+"e. c #1A1A19196565",
+"r. c #20201E1E7070",
+"t. c #1E1E1D1D6969",
+"y. c #2A2A29297676",
+"u. c #2F2F2D2D7676",
+"i. c #3A3A39398787",
+"p. c #3A3A39398383",
+"a. c #3F3F3E3E8888",
+"s. c #414140408989",
+"d. c #454543438D8D",
+"f. c #444442428B8B",
+"g. c #444443438C8C",
+"h. c #434342428A8A",
+"j. c #434341418888",
+"k. c #434342428989",
+"l. c #424241418787",
+"z. c #434342428787",
+"x. c #424241418585",
+"c. c #41413F3F8181",
+"v. c #414140408282",
+"b. c #484846468D8D",
+"n. c #494948489090",
+"m. c #4B4B4A4A9191",
+"M. c #4B4B49498E8E",
+"N. c #525251519A9A",
+"B. c #525251519999",
+"V. c #565654549A9A",
+"C. c #545453539494",
+"Z. c #60605F5FA7A7",
+"A. c #64646363ABAB",
+"S. c #5A5A59599797",
+"D. c #68686767ADAD",
+"F. c #6C6C6B6BB2B2",
+"G. c #5E5E5D5D9A9A",
+"H. c #76767575BABA",
+"J. c #78787777BBBB",
+"K. c #76767474B5B5",
+"L. c #7E7E7D7DBABA",
+"P. c #A5A5A4A4D2D2",
+"I. c #040404045252",
+"U. c #070707075454",
+"Y. c #070708085353",
+"T. c #080808085454",
+"R. c #0A0A0B0B5757",
+"E. c #0E0E0E0E5A5A",
+"W. c #111112125E5E",
+"Q. c #111111115E5E",
+"!. c #111111115D5D",
+"~. c #111112125D5D",
+"^. c #161616166868",
+"/. c #151516166161",
+"(. c #151515156161",
+"). c #19191A1A6565",
+"_. c #191919196565",
+"`. c #1A1A1A1A6464",
+"'. c #1D1D1E1E6969",
+"]. c #1E1E1E1E6969",
+"[. c #222222226D6D",
+"{. c #272727277171",
+"}. c #2B2B2C2C7676",
+"|. c #2B2B2B2B7676",
+" X c #2B2B2B2B7575",
+".X c #303030307A7A",
+"XX c #303030307979",
+"oX c #353535357F7F",
+"OX c #393939398383",
+"+X c #3A3A3A3A8383",
+"@X c #3F3F3F3F8787",
+"#X c #434343438C8C",
+"$X c #434344448C8C",
+"%X c #424242428686",
+"&X c #414141418484",
+"*X c #484848489191",
+"=X c #484849499090",
+"-X c #4D4D4D4D9696",
+";X c #515151519D9D",
+":X c #4D4D4D4D9595",
+">X c #515152529A9A",
+",X c #515152529999",
+"<X c #525252529A9A",
+"1X c #525252529999",
+"2X c #565657579E9E",
+"3X c #575757579D9D",
+"4X c #5B5B5B5BA2A2",
+"5X c #5F5F6060A6A6",
+"6X c #5F5F5F5FA6A6",
+"7X c #63636464AAAA",
+"8X c #64646464AAAA",
+"9X c #67676767AEAE",
+"0X c #67676868AEAE",
+"qX c #68686868AEAE",
+"wX c #6F6F6F6FB5B5",
+"eX c #6C6C6C6CB1B1",
+"rX c #73737373B8B8",
+"tX c #82828282BEBE",
+"yX c #86868686C2C2",
+"uX c #89898989C4C4",
+"iX c #98989898CBCB",
+"pX c #A0A0A0A0CFCF",
+"aX c #A9A9A9A9D5D5",
+"sX c #B0B0B0B0D8D8",
+"dX c #B8B8B8B8DDDD",
+"fX c #BDBDBDBDE0E0",
+"gX c #D9D9D9D9EDED",
+"hX c #90909191C6C6",
+"jX c #71718989BCBC",
+"kX c #73738B8BBFBF",
+"lX c #72728989BCBC",
+"zX c #79799090C3C3",
+"xX c #7E7E9595C7C7",
+"cX c #81819898CACA",
+"vX c #84849B9BCCCC",
+"bX c #8C8CA3A3D4D4",
+"nX c #71718A8ABCBC",
+"mX c #73738B8BBDBD",
+"MX c #75758D8DBFBF",
+"NX c #74748C8CBEBE",
+"BX c #76768E8EC0C0",
+"VX c #7C7C9494C6C6",
+"CX c #7B7B9393C4C4",
+"ZX c #7F7F9797C9C9",
+"AX c #82829A9ACBCB",
+"SX c #85859E9ECECE",
+"DX c #8888A0A0D1D1",
+"FX c #87879F9FD0D0",
+"GX c #8B8BA4A4D4D4",
+"HX c #8B8BA3A3D4D4",
+"JX c #8989A1A1D2D2",
+"KX c #8D8DA5A5D6D6",
+"LX c #8B8BA3A3D3D3",
+"PX c #8E8EA6A6D6D6",
+"IX c #8D8DA5A5D5D5",
+"UX c gray100",
+"YX c None",
+/* pixels */
+"YXX X X X X X X X X X X X X X X X X X X X X X X X X X X X X X YX",
+"X v.v.v.v.&Xl.z.k.&.d.%.$.@.O.+.] [ _ ` ) ( ^ L K ! G D V m m o ",
+"X c.c.c.v.&Xx.z.f.f.d.%.$.#.O.+.X.[ _ ` ) ( / L K H F D V C n o ",
+"X v.c.v.v.x.x.z.k.f.n.V.,.>.-.+.] [ _ ` ) ( ^ L K H G D V C h o ",
+"X &Xv.&Xx.x.l.j.M.1.4 - - , 7 q J.H.K.j :.*.P L K H F S B C n o ",
+"X x.&Xx.x.z.j.S., = = 1 } iXuXH.rXwXF.qX7XZ.;.o.J ! F S B m n o ",
+"X x.l.z.%Xz.G.1 @ > 2.dXaXiXuXrXwXF.qX8X5X4X2X;X{ H F S V C n o ",
+"X z.j.j.j.C.1 @ < gX2.fXaXpXuXwXeX9X7X5X4X2XN.:X*X_ D S Z m h o ",
+"X k.k.h.b., O > gXgX2.dXaXiXyXF.D.A.Z.4X3X1X:Xn.g.a._ V B m N o ",
+"X f.f.f.3 + = 2.2.2.fXsXpXhXtXD.8XZ.4X2X1X:X*X$X@Xp.i.W C n N o ",
+"X d.&.%.% + 1 dXdXdXsXP.iXyXK.8X5X4X2X>X:X*Xg.a.+XoX.X..m n N o ",
+"X %.=.5 % - P.} aXP.pXiXyXK.D.Z.4X3X1X-Xn.$X@X+XoX.X Xy.W h g o ",
+"X $.$.: # PXIXGXGXLXJXFXFXSXvXAXcXZXxXVXCXzXzXBXMXkXmXnXjXh g o ",
+"X #.@.* $ 7 yXuXyXtXL.K.D.6X4X2X1X:Xo g.a.OXoX.X|.{.[.t. .g v o ",
+"X O.#.$ $ q H.rXwXF.0XA.6X4X2X1X:Xo $Xa.p.oX.X|.{.[.'.`.r.g b o ",
+"X X.+.$ $ PXKXbXbXLXJXDXFXSXvXAXcXZXxXCXCXzXBXBXMXNXmXlXjXb c o ",
+"X ] ] $ $ H.wXF.0X7X6X4X2X<X:Xo #Xa.+XoX.X|.{.[.].)./.~.Q.c z o ",
+"X [ [ & & w F.qX7XZ.4X2X,X:Xo #Xa.+XoX.X}.{.[.'.e./.9.E.^.c z o ",
+"X ' _ * & PXKXbXHXLXJXDXSXSXvXAXcXZXxXVXCXzXzXBXMXNXkXjXjXz x o ",
+"X ` ` : & 2 8XZ.4X2XB.:X*Xg.@Xp.oX.X|.{.[.].).q.!.E.R.U.Y z f o ",
+"X ) ) 5 & ; <.4X2X>X:Xo #Xa.+XoXXX|.{.[.t._.q.~.E.R.4.5.k x a o ",
+"X ( ( I ; * 6 2X>X:X=X$X@X+XoX.X|.{.[.t.e./.W.E.R.Y.3. .z a a o ",
+"X I ^ / 8 * : 0 :X*X#X@X+XoX.X|.{.[.'._.(.~.E.R.T.3.7.k x a p o ",
+"X L L L ^ 2 * 3 m.$Xa.p.oX.X}.{.[.t.).(.~.E.6.T.3.I.R x a a y o ",
+"X J K K K K 2 * 5 s.OXoX.X}.{.[.'._.(.9.8.R.4.3.I.Y x l a p t o ",
+"X ~ H H ! ! ! 2 ; 5 U XX}.{.[.].e.(.W.E.R.U.3.7.R x l u u y t o ",
+"X G F G G G Q Q 8 : 3 9 u.[.]._./.Q.E.R.T.6. .k x a a u t t t o ",
+"X D S D S D S S S V 8 2 6 9 c.E w.0.| T Y k z z a a p t t i r o ",
+"X A V B V V V B B m m n n h h g g g c z z z l l d p y t i r r o ",
+"X m C C C C C C C n n n M N g g b c z z x a a a u y t t r r e o ",
+"X n n n n n h h h N N g g v b s z z z x a p p u t t r r r e e o ",
+"YXo o o o o o o o o o o o o o o o o o o o o o o o o o o o o o YX"
+};
diff --git a/qpid/java/management/eclipse-plugin/src/main/resources/solaris-gtk-sparc/Qpidmc.s.pm b/qpid/java/management/eclipse-plugin/src/main/resources/solaris-gtk-sparc/Qpidmc.s.pm
new file mode 100644
index 0000000000..e2b9379f3a
--- /dev/null
+++ b/qpid/java/management/eclipse-plugin/src/main/resources/solaris-gtk-sparc/Qpidmc.s.pm
@@ -0,0 +1,287 @@
+/* XPM */
+static char *ProductIcon24[] = {
+/* columns rows colors chars-per-pixel */
+"24 24 257 2",
+" c black",
+". c gray100",
+"X c #69695A5AE8E8",
+"o c #494949499191",
+"O c #F1F1DFDFECEC",
+"+ c #D7D7ACACCDCD",
+"@ c #DFDFBBBBD6D6",
+"# c #E2E2C4C4DBDB",
+"$ c #CECE9C9CC4C4",
+"% c #C4C48B8BBABA",
+"& c #C2C28A8ABABA",
+"* c #C4C48E8EBCBC",
+"= c #BFBF8A8AB9B9",
+"- c #EBEBD9D9E9E9",
+"; c #BFBF8888B9B9",
+": c #D8D8B9B9D6D6",
+"> c #B9B98686B9B9",
+", c #B8B88989B9B9",
+"< c #BBBB9393BFBF",
+"1 c #A9A97B7BB2B2",
+"2 c #E4E4D4D4E7E7",
+"3 c #C6C6AFAFCECE",
+"4 c #A6A68080B6B6",
+"5 c #A2A27E7EB4B4",
+"6 c #9E9E7E7EB1B1",
+"7 c #ABAB9090BBBB",
+"8 c #B7B7A0A0C5C5",
+"9 c #9D9D7C7CB2B2",
+"0 c #AAAA8B8BBEBE",
+"q c #AAAA9090BCBC",
+"w c #8C8C6B6BABAB",
+"e c #90907070B1B1",
+"r c #C4C4B3B3D7D7",
+"t c #CDCDBFBFDDDD",
+"y c #EAEAE4E4F1F1",
+"u c #88886A6AADAD",
+"i c #9E9E8585C1C1",
+"p c #84846A6AAFAF",
+"a c #81816B6BAAAA",
+"s c #D7D7CFCFE6E6",
+"d c #81816969B1B1",
+"f c #78786363A5A5",
+"g c #6E6E5D5D9C9C",
+"h c #717160609D9D",
+"j c #83837474AAAA",
+"k c #6A6A5757A3A3",
+"l c #6E6E5E5EA0A0",
+"z c #5E5E50509292",
+"x c #88887B7BBCBC",
+"c c #68685858ABAB",
+"v c #5A5A4D4DA2A2",
+"b c #7D7D7373B4B4",
+"n c #5A5A4E4EA6A6",
+"m c #5F5F56569595",
+"M c #56564A4ABBBB",
+"N c #56564949B9B9",
+"B c #55554949B8B8",
+"V c #53534848B3B3",
+"C c #54544949B4B4",
+"Z c #52524747B0B0",
+"A c #52524747AFAF",
+"S c #5B5B53539393",
+"D c #3E3E36369797",
+"F c #49494040A6A6",
+"G c #48484040A5A5",
+"H c #55554A4ABABA",
+"J c #54544949B7B7",
+"K c #53534949B4B4",
+"L c #51514747AFAF",
+"P c #52524848B1B1",
+"I c #51514848B0B0",
+"U c #51514848AEAE",
+"Y c #51514747ADAD",
+"T c #51514848ADAD",
+"R c #4F4F4747ABAB",
+"E c #50504747ABAB",
+"W c #50504646A9A9",
+"Q c #4F4F4646A8A8",
+"! c #4E4E4646A7A7",
+"~ c #4E4E4545A4A4",
+"^ c #4D4D4545A4A4",
+"/ c #4E4E4646A5A5",
+"( c #4D4D4545A1A1",
+") c #3D3D36367E7E",
+"_ c #4B4B44449C9C",
+"` c #2A2A25257F7F",
+"' c #3E3E37379898",
+"] c #474740409C9C",
+"[ c #4D4D4646A4A4",
+"{ c #4C4C4545A2A2",
+"} c #4D4D4646A2A2",
+"| c #4D4D4646A1A1",
+" . c #4B4B45459F9F",
+".. c #4C4C45459F9F",
+"X. c #4C4C46469F9F",
+"o. c #4B4B45459D9D",
+"O. c #494943439898",
+"+. c #494944449A9A",
+"@. c #4A4A45459A9A",
+"#. c #494944449898",
+"$. c #484843439696",
+"%. c #494944449797",
+"&. c #484843439595",
+"*. c #51514C4CA1A1",
+"=. c #6B6B6767AEAE",
+"-. c #95959191C9C9",
+";. c #23231F1F7676",
+":. c #21211E1E7070",
+">. c #292925257F7F",
+",. c #252521217070",
+"<. c #242421216D6D",
+"1. c #2B2B27278080",
+"2. c #393935358C8C",
+"3. c #444440409494",
+"4. c #3B3B38388282",
+"5. c #474743439494",
+"6. c #484844449595",
+"7. c #474743439393",
+"8. c #474744449393",
+"9. c #464643439191",
+"0. c #454542428F8F",
+"q. c #4A4A47479898",
+"w. c #464643438F8F",
+"e. c #454542428D8D",
+"r. c #444441418B8B",
+"t. c #484844449191",
+"y. c #444441418989",
+"u. c #494946469090",
+"i. c #4C4C48489393",
+"p. c #51514E4E9E9E",
+"a. c #73737070B6B6",
+"s. c #77777474BBBB",
+"d. c #A0A09E9ED1D1",
+"f. c #D6D6D5D5EBEB",
+"g. c #0E0E0D0D5A5A",
+"h. c #11110F0F5E5E",
+"j. c #121211115E5E",
+"k. c #131312125F5F",
+"l. c #171716166363",
+"z. c #1D1D1B1B6868",
+"x. c #1D1D1C1C6868",
+"c. c #222221216E6E",
+"v. c #222221216D6D",
+"b. c #282827277474",
+"n. c #282827277373",
+"m. c #292928287373",
+"M. c #2F2F2E2E7979",
+"N. c #353534347F7F",
+"B. c #363635358181",
+"V. c #3C3C3B3B8585",
+"C. c #424241418C8C",
+"Z. c #424241418B8B",
+"A. c #444442428B8B",
+"S. c #434341418989",
+"D. c #434342428989",
+"F. c #424241418787",
+"G. c #414140408484",
+"H. c #474745458D8D",
+"J. c #434342428787",
+"K. c #424241418585",
+"L. c #414140408282",
+"P. c #494948489191",
+"I. c #4F4F4E4E9797",
+"U. c #59595757A6A6",
+"Y. c #5F5F5D5DA4A4",
+"T. c #6C6C6B6BB3B3",
+"R. c #7C7C7B7BB9B9",
+"E. c #A8A8A7A7D3D3",
+"W. c #0D0D0D0D5A5A",
+"Q. c #1F1F1F1F6C6C",
+"!. c #222222226E6E",
+"~. c #3B3B3B3B8585",
+"^. c #414141418C8C",
+"/. c #414141418B8B",
+"(. c #424242428B8B",
+"). c #484848489292",
+"_. c #404040408181",
+"`. c #4E4E4E4E9898",
+"'. c #555555559E9E",
+"]. c #555555559D9D",
+"[. c #5B5B5B5BA3A3",
+"{. c #5C5C5C5CA3A3",
+"}. c #61616161A9A9",
+"|. c #66666666AEAE",
+" X c #66666666ADAD",
+".X c #6B6B6B6BB2B2",
+"XX c #70707070B7B7",
+"oX c #6A6A6A6AADAD",
+"OX c #74747474BBBB",
+"+X c #89898989C2C2",
+"@X c #90909090C8C8",
+"#X c #8F8F8F8FC6C6",
+"$X c #92929292C6C6",
+"%X c #9F9F9F9FCFCF",
+"&X c #A5A5A5A5D2D2",
+"*X c #B5B5B5B5DBDB",
+"=X c #B8B8B8B8DEDE",
+"-X c #B7B7B7B7DCDC",
+";X c #BBBBBBBBDEDE",
+":X c #BDBDBDBDDFDF",
+">X c #C9C9C9C9E5E5",
+",X c #D1D1D1D1EAEA",
+"<X c #7C7C7D7DBABA",
+"1X c #89898A8AC7C7",
+"2X c #8F8F9090C7C7",
+"3X c #A3A3A4A4D3D3",
+"4X c #A2A2B5B5DEDE",
+"5X c #ADADBDBDE1E1",
+"6X c #B9B9C7C7E5E5",
+"7X c #BABAC8C8E6E6",
+"8X c #8E8EA6A6D6D6",
+"9X c #9090A7A7D7D7",
+"0X c #9191A9A9D7D7",
+"qX c #9292A9A9D8D8",
+"wX c #9494ABABD8D8",
+"eX c #9898AEAED9D9",
+"rX c #9B9BB0B0DADA",
+"tX c #9E9EB3B3DCDC",
+"yX c #A1A1B5B5DDDD",
+"uX c #A5A5B8B8DEDE",
+"iX c #A8A8BBBBE0E0",
+"pX c #ACACBEBEE1E1",
+"aX c #AFAFC0C0E3E3",
+"sX c #B3B3C3C3E4E4",
+"dX c #B2B2C2C2E3E3",
+"fX c #B5B5C5C5E5E5",
+"gX c #B8B8C7C7E6E6",
+"hX c #B6B6C5C5E4E4",
+"jX c #9797AEAED9D9",
+"kX c #A1A1B6B6DDDD",
+"lX c #A8A8BBBBDFDF",
+"zX c gray100",
+"xX c black",
+"cX c black",
+"vX c black",
+"bX c black",
+"nX c black",
+"mX c black",
+"MX c black",
+"NX c black",
+"BX c black",
+"VX c black",
+"CX c black",
+"ZX c black",
+"AX c black",
+"SX c black",
+"DX c black",
+"FX c black",
+"GX c black",
+"HX c black",
+"JX c black",
+"KX c black",
+"LX c black",
+"PX c black",
+"IX c black",
+"UX c black",
+"YX c None",
+/* pixels */
+"YXX X X X X X X X X X X X X X X X X X X X X X YX",
+"X _._.L.G.K.F.D.A.e.0.9.&.$.%.+._ ..{ ^ ! W E o ",
+"X L.L.L.G.F.F.D.r.e.0.9.7.&.O.@.o. .{ ~ ! Q E o ",
+"X L.G.G.K.F.S.y.r.e.w.9.5.$.+.@.o...( ~ ! W E o ",
+"X G.K.K.F.J.D.h 6 0 i x s.a.=.U.*...} ~ ! W E o ",
+"X K.F.F.F.S 7 : r d.1XOXXX.X|.}.[.p.| / ! W E o ",
+"X F.F.F.m 3 - s =X3X@XXXT. X}.[.].I.q.{ Q E T o ",
+"X S.D.H.8 O y ,X;X&X2X.X|.}.[.].I.P.C.3.Q E Y o ",
+"X A.r.j # 2 f.>X*X%X+X|.}.[.].I.P.^.~.B.] E Y o ",
+"X e.u.q @ t :X-XE.$X<X}.[.].`.P.Z.V.N.M.2.Y L o ",
+"X 0.i.< + 8X8XqXwXeXrXtX4XuXlXpXaXsXfXgX7XY A o ",
+"X 9.t.* $ -.#X+XR.oX{.'.`.P.(.~.N.M.m.c.Q.T Z o ",
+"X 8.7.; % 8X9X0XwXeXrXtXyXuXiXpXaXdXfXgX7XL Z o ",
+"X 6.&.1 & b X}.[.'.I.P./.~.N.M.n.!.x.l.:.I P o ",
+"X #.#.w = 8X9XqXwXjXrXtXkXuXiX5XaXsXhX6X7XP V o ",
+"X +.+.k > 5 Y.].I.)./.~.N.M.b.v.x.l.k.h.' V C o ",
+"X o.o.o.u , a I.).Z.V.N.M.n.c.z.l.j.W.` P V C o ",
+"X .. .X.v e 4 l ^.V.N.M.m.!.x.l.j.g.;.F V C J o ",
+"X ( | ( ( n p 9 g 4.M.n.c.x.l.j.h.>.G V K C J o ",
+"X ~ [ [ ^ / / c d f z ) <.z.,.1.D P V C C B B o ",
+"X ! Q ! Q Q Q Q W E E Y T A Z P V V K C J B B o ",
+"X Q W Q W R W E E T T T L Z P V V K J J J B N o ",
+"X R E E E E E Y Y U L Z P P P C V J J B B H M o ",
+"YXo o o o o o o o o o o o o o o o o o o o o o YX"
+};
diff --git a/qpid/java/management/eclipse-plugin/src/main/resources/solaris-gtk-sparc/Qpidmc.t.pm b/qpid/java/management/eclipse-plugin/src/main/resources/solaris-gtk-sparc/Qpidmc.t.pm
new file mode 100644
index 0000000000..3f6b21f428
--- /dev/null
+++ b/qpid/java/management/eclipse-plugin/src/main/resources/solaris-gtk-sparc/Qpidmc.t.pm
@@ -0,0 +1,279 @@
+/* XPM */
+static char *ProductIcon16[] = {
+/* columns rows colors chars-per-pixel */
+"16 16 257 2",
+" c black",
+". c gray100",
+"X c #E2E2C0C0D9D9",
+"o c #EDEDD9D9E8E8",
+"O c #D5D5ABABCDCD",
+"+ c #E2E2C3C3DCDC",
+"@ c #C5C58E8EBCBC",
+"# c #D4D4ABABCDCD",
+"$ c #CACA9F9FC6C6",
+"% c #D6D6B4B4D3D3",
+"& c #CACAA0A0C8C8",
+"* c #C6C69D9DC6C6",
+"= c #C5C59F9FC8C8",
+"- c #CCCCACACCECE",
+"; c #CCCCB0B0D3D3",
+": c #A6A68383B3B3",
+"> c #BABA9A9AC6C6",
+", c #B7B79A9AC2C2",
+"< c #E3E3D5D5E9E9",
+"1 c #B0B08E8EC0C0",
+"2 c #9F9F8080B8B8",
+"3 c #AFAF9898C1C1",
+"4 c #DBDBCFCFE5E5",
+"5 c #96967878B2B2",
+"6 c #9A9A7E7EBABA",
+"7 c #8E8E7878AFAF",
+"8 c #91917F7FBDBD",
+"9 c #D3D3CCCCE4E4",
+"0 c #535348488B8B",
+"q c #69695A5AE8E8",
+"w c #55554949B9B9",
+"e c #55554949B8B8",
+"r c #54544848B6B6",
+"t c #53534848B4B4",
+"y c #54544848B4B4",
+"u c #53534848B3B3",
+"i c #53534848B2B2",
+"p c #52524747AFAF",
+"a c #53534848B1B1",
+"s c #54544949B8B8",
+"d c #54544949B6B6",
+"f c #52524848B3B3",
+"g c #52524848B2B2",
+"h c #53534949B3B3",
+"j c #52524848B1B1",
+"k c #52524848B0B0",
+"l c #51514747AEAE",
+"z c #52524848AFAF",
+"x c #51514848AEAE",
+"c c #51514747ADAD",
+"v c #51514747ACAC",
+"b c #4F4F4646AAAA",
+"n c #51514848ADAD",
+"m c #50504747ABAB",
+"M c #50504747AAAA",
+"N c #4F4F4646A8A8",
+"B c #50504747A9A9",
+"V c #4E4E4646A7A7",
+"C c #4E4E4646A6A6",
+"Z c #4F4F4646A6A6",
+"A c #4F4F4747A7A7",
+"S c #4D4D4545A3A3",
+"D c #4D4D4545A2A2",
+"F c #4C4C45459E9E",
+"G c #74746E6EB3B3",
+"H c #2E2E29298383",
+"J c #383832329090",
+"K c #464640409999",
+"L c #4D4D4646A2A2",
+"P c #4E4E4747A3A3",
+"I c #4B4B45459F9F",
+"U c #4B4B45459E9E",
+"Y c #4C4C46469F9F",
+"T c #4A4A44449B9B",
+"R c #4A4A44449A9A",
+"E c #494943439797",
+"W c #494944449797",
+"Q c #484843439494",
+"! c #78787474B8B8",
+"~ c #272724247878",
+"^ c #2D2D2A2A7575",
+"/ c #484844449797",
+"( c #474743439393",
+") c #454542429090",
+"_ c #4B4B48489A9A",
+"` c #464643438F8F",
+"' c #464643438E8E",
+"] c #454542428C8C",
+"[ c #51514D4DA0A0",
+"{ c #5C5C5959A5A5",
+"} c #535350509090",
+"| c #C8C8C7C7E3E3",
+" . c #121211115D5D",
+".. c #1A1A19196565",
+"X. c #242422226D6D",
+"o. c #3F3F3E3E8888",
+"O. c #444442428D8D",
+"+. c #444442428989",
+"@. c #424241418787",
+"#. c #454543438A8A",
+"$. c #434342428888",
+"%. c #424241418686",
+"&. c #414140408484",
+"*. c #414140408383",
+"=. c #424240408383",
+"-. c #414140408282",
+";. c #474746468D8D",
+":. c #464644448989",
+">. c #525251519999",
+",. c #64646363AAAA",
+"<. c #61615F5FA2A2",
+"1. c #6E6E6C6CB2B2",
+"2. c #A5A5A4A4D3D3",
+"3. c #B0B0AFAFD6D6",
+"4. c #111112125D5D",
+"5. c #19191A1A6565",
+"6. c #1E1E1E1E6C6C",
+"7. c #222222226D6D",
+"8. c #2B2B2B2B7676",
+"9. c #2B2B2B2B7575",
+"0. c #2B2B2C2C7575",
+"q. c #343435357F7F",
+"w. c #343435357E7E",
+"e. c #353535357F7F",
+"r. c #3E3E3E3E8888",
+"t. c #3E3E3E3E8787",
+"y. c #414141418484",
+"u. c #404040408282",
+"i. c #484849499191",
+"p. c #494949499191",
+"a. c #484848489090",
+"s. c #484849499090",
+"d. c #404040408080",
+"f. c #525252529A9A",
+"g. c #525252529999",
+"h. c #5B5B5B5BA3A3",
+"j. c #5B5B5B5BA2A2",
+"k. c #64646464ABAB",
+"l. c #63636464AAAA",
+"z. c #6B6B6C6CB2B2",
+"x. c #72727373B9B9",
+"c. c #71717171A4A4",
+"v. c #78787878ABAB",
+"b. c #7F7F7F7FB1B1",
+"n. c #8C8C8C8CBEBE",
+"m. c #A5A5A5A5D2D2",
+"M. c #C9C9C9C9E5E5",
+"N. c #85858686B7B7",
+"B. c #91919292C4C4",
+"V. c #71718989BCBC",
+"C. c #73738B8BBEBE",
+"Z. c #75758D8DC0C0",
+"A. c #78789090C3C3",
+"S. c #7A7A9292C5C5",
+"D. c #71718A8ABDBD",
+"F. c #76768E8EC0C0",
+"G. c #78789090C2C2",
+"H. c #7B7B9393C5C5",
+"J. c #7D7D9595C7C7",
+"K. c #80809999CACA",
+"L. c #7E7E9696C7C7",
+"P. c #83839B9BCDCD",
+"I. c #83839B9BCCCC",
+"U. c #86869E9ECFCF",
+"Y. c #8888A1A1D1D1",
+"T. c #8A8AA2A2D3D3",
+"R. c #8989A1A1D1D1",
+"E. c #8B8BA3A3D3D3",
+"W. c gray100",
+"Q. c black",
+"!. c black",
+"~. c black",
+"^. c black",
+"/. c black",
+"(. c black",
+"). c black",
+"_. c black",
+"`. c black",
+"'. c black",
+"]. c black",
+"[. c black",
+"{. c black",
+"}. c black",
+"|. c black",
+" X c black",
+".X c black",
+"XX c black",
+"oX c black",
+"OX c black",
+"+X c black",
+"@X c black",
+"#X c black",
+"$X c black",
+"%X c black",
+"&X c black",
+"*X c black",
+"=X c black",
+"-X c black",
+";X c black",
+":X c black",
+">X c black",
+",X c black",
+"<X c black",
+"1X c black",
+"2X c black",
+"3X c black",
+"4X c black",
+"5X c black",
+"6X c black",
+"7X c black",
+"8X c black",
+"9X c black",
+"0X c black",
+"qX c black",
+"wX c black",
+"eX c black",
+"rX c black",
+"tX c black",
+"yX c black",
+"uX c black",
+"iX c black",
+"pX c black",
+"aX c black",
+"sX c black",
+"dX c black",
+"fX c black",
+"gX c black",
+"hX c black",
+"jX c black",
+"kX c black",
+"lX c black",
+"zX c black",
+"xX c black",
+"cX c black",
+"vX c black",
+"bX c black",
+"nX c black",
+"mX c black",
+"MX c black",
+"NX c black",
+"BX c black",
+"VX c black",
+"CX c black",
+"ZX c black",
+"AX c black",
+"SX c black",
+"DX c black",
+"FX c black",
+"GX c black",
+"HX c black",
+"JX c black",
+"KX c black",
+"LX c black",
+"PX c black",
+"IX c black",
+"UX c black",
+"YX c None",
+/* pixels */
+"YXq q q q q q q q q q q q q q YX",
+"q d.-.y.%.+.O.` ( E R U D C B p.",
+"q u.*.&.$.#.] ) Q W T F L V M p.",
+"q =.y.} , % ; 8 ! 1.{ [ S Z b p.",
+"q @.:.- o 4 2.x.z.,.j.>._ A m p.",
+"q +.: X < M.m.z.l.j.g.s.r.K v p.",
+"q ' $ + 9 | 3.B.n.N.b.v.c.<.n p.",
+"q ` O T.Y.U.P.K.L.S.G.F.C.D.l p.",
+"q ( # @ G k.h.g.i.t.e.9.7.6.z p.",
+"q / * E.R.U.I.K.J.H.A.Z.C.V.a p.",
+"q T 2 & 5 f.a.o.q.8.7...4.J u p.",
+"q I Y 1 = 7 ;.w.0.7.5. .H f y p.",
+"q L D P 6 > 3 0 ^ X.~ J i t d p.",
+"q C C V A N M m n p k g y r e p.",
+"q M b M m m c x p j h y d s w p.",
+"YXp.p.p.p.p.p.p.p.p.p.p.p.p.p.YX"
+};
diff --git a/qpid/java/management/eclipse-plugin/src/main/resources/solaris-gtk-sparc/qpidmc b/qpid/java/management/eclipse-plugin/src/main/resources/solaris-gtk-sparc/qpidmc
new file mode 100755
index 0000000000..b88ff49e8e
--- /dev/null
+++ b/qpid/java/management/eclipse-plugin/src/main/resources/solaris-gtk-sparc/qpidmc
Binary files differ
diff --git a/qpid/java/management/eclipse-plugin/src/main/resources/solaris-gtk-sparc/qpidmc.ini b/qpid/java/management/eclipse-plugin/src/main/resources/solaris-gtk-sparc/qpidmc.ini
new file mode 100644
index 0000000000..cfa715e5a8
--- /dev/null
+++ b/qpid/java/management/eclipse-plugin/src/main/resources/solaris-gtk-sparc/qpidmc.ini
@@ -0,0 +1,40 @@
+###############################################################################
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+###############################################################################
+-startup
+plugins/org.eclipse.equinox.launcher_1.0.101.R34x_v20080819.jar
+--launcher.library
+plugins/org.eclipse.equinox.launcher.gtk.solaris.sparc_1.0.101.R34x_v20080731
+-vmargs
+-Xms40m
+-Xmx256m
+-XX:MaxPermSize=256m
+-Dosgi.requiredJavaVersion=1.5
+-Declipse.consoleLog=true
+
+#===============================================
+# SSL trust store configuration options.
+#===============================================
+
+# Uncomment lines below to specify custom truststore for server SSL
+# certificate verification, eg when using self-signed server certs.
+#
+#-Djavax.net.ssl.trustStore=<path.to.truststore>
+#-Djavax.net.ssl.trustStorePassword=<truststore.password>
+
+
diff --git a/qpid/java/management/eclipse-plugin/src/main/resources/win32-win32-x86/Configuration/config.ini b/qpid/java/management/eclipse-plugin/src/main/resources/win32-win32-x86/Configuration/config.ini
index d00d756706..a61bea2fa8 100644
--- a/qpid/java/management/eclipse-plugin/src/main/resources/win32-win32-x86/Configuration/config.ini
+++ b/qpid/java/management/eclipse-plugin/src/main/resources/win32-win32-x86/Configuration/config.ini
@@ -45,4 +45,5 @@ org.eclipse.ui, \
org.eclipse.ui.forms, \
org.eclipse.ui.workbench, \
org.eclipse.equinox.launcher, \
-org.eclipse.equinox.launcher.win32.win32.x86
+org.eclipse.equinox.launcher.win32.win32.x86, \
+org.apache.commons.codec
diff --git a/qpid/java/systests/build.xml b/qpid/java/systests/build.xml
index 4eb7275e73..11af9c21bf 100644
--- a/qpid/java/systests/build.xml
+++ b/qpid/java/systests/build.xml
@@ -20,7 +20,7 @@ nn - or more contributor license agreements. See the NOTICE file
-->
<project name="System Tests" default="build">
- <property name="module.depends" value="client broker common junit-toolkit"/>
+ <property name="module.depends" value="client broker broker/test common junit-toolkit"/>
<property name="module.test.src" location="src/main/java"/>
<property name="module.test.excludes"
value="**/TTLTest.java,**/DropInTest.java,**/TestClientControlledTest.java"/>
diff --git a/qpid/java/systests/src/main/java/org/apache/qpid/client/MessageListenerTest.java b/qpid/java/systests/src/main/java/org/apache/qpid/client/MessageListenerTest.java
index 4c1d5ee9c1..ffec6c7a29 100644
--- a/qpid/java/systests/src/main/java/org/apache/qpid/client/MessageListenerTest.java
+++ b/qpid/java/systests/src/main/java/org/apache/qpid/client/MessageListenerTest.java
@@ -106,6 +106,14 @@ public class MessageListenerTest extends QpidTestCase implements MessageListener
}
}
+ public void testSynchronousRecieveNoWait() throws Exception
+ {
+ for (int msg = 0; msg < MSG_COUNT; msg++)
+ {
+ assertTrue(_consumer.receiveNoWait() != null);
+ }
+ }
+
public void testAsynchronousRecieve() throws Exception
{
_consumer.setMessageListener(this);
diff --git a/qpid/java/systests/src/main/java/org/apache/qpid/client/MultipleJCAProviderRegistrationTest.java b/qpid/java/systests/src/main/java/org/apache/qpid/client/MultipleJCAProviderRegistrationTest.java
index ea0bae7a56..ba7a4bb19c 100644
--- a/qpid/java/systests/src/main/java/org/apache/qpid/client/MultipleJCAProviderRegistrationTest.java
+++ b/qpid/java/systests/src/main/java/org/apache/qpid/client/MultipleJCAProviderRegistrationTest.java
@@ -59,10 +59,6 @@ public class MultipleJCAProviderRegistrationTest extends QpidTestCase
}
ConfigurationFileApplicationRegistry config = new ConfigurationFileApplicationRegistry(defaultaclConfigFile);
-
- // This is a bit evil it should be updated with QPID-1103
- config.getConfiguration().setProperty("management.enabled", "false");
-
startBroker();
}
diff --git a/qpid/java/systests/src/main/java/org/apache/qpid/server/queue/QueueCreateTest.java b/qpid/java/systests/src/main/java/org/apache/qpid/server/queue/QueueCreateTest.java
new file mode 100644
index 0000000000..dd9b35c475
--- /dev/null
+++ b/qpid/java/systests/src/main/java/org/apache/qpid/server/queue/QueueCreateTest.java
@@ -0,0 +1,179 @@
+/*
+ *
+ * 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.AMQSession;
+import org.apache.qpid.client.failover.FailoverException;
+import org.apache.qpid.framing.AMQShortString;
+import org.apache.qpid.test.utils.QpidTestCase;
+
+import javax.jms.Connection;
+import javax.jms.JMSException;
+import javax.jms.Session;
+import javax.naming.NamingException;
+import java.util.HashMap;
+import java.util.Map;
+
+/** The purpose of this set of tests is to ensure */
+public class QueueCreateTest extends QpidTestCase
+{
+ private Connection _connection;
+ private AMQSession _session;
+ private int _queueCount = 0;
+
+ public void setUp() throws Exception
+ {
+ _connection = getConnection();
+
+ _session = (AMQSession) _connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
+
+ }
+
+ private void testQueueWithArguments(Map<String, Object> arguments) throws AMQException
+ {
+ _session.createQueue(new AMQShortString(this.getName() + (_queueCount++)), false, false, false, arguments);
+ }
+
+ public void testCreateNoArguments() throws AMQException, FailoverException
+ {
+ Map<String, Object> arguments = null;
+ testQueueWithArguments(arguments);
+ }
+
+ public void testCreatePriorityInt() throws AMQException, FailoverException
+ {
+ Map<String, Object> arguments = new HashMap<String, Object>();
+
+ //Ensure we can call createQueue with a priority int value
+ arguments.put(AMQQueueFactory.X_QPID_PRIORITIES.toString(), 7);
+ testQueueWithArguments(arguments);
+ }
+
+ /**
+ * @link https://issues.apache.org/jira/browse/QPID-1715, QPID-1716
+ *
+ * @throws AMQException
+ * @throws FailoverException
+ */
+ public void testCreatePriorityString() throws AMQException, FailoverException
+ {
+ Map<String, Object> arguments = new HashMap<String, Object>();
+
+ //Ensure we can call createQueue with a priority value that is not an int
+ arguments.put(AMQQueueFactory.X_QPID_PRIORITIES.toString(), "seven");
+ try
+ {
+
+ testQueueWithArguments(arguments);
+ fail("Invalid Property value still succeeds.");
+ }
+ catch (Exception e)
+ {
+ assertTrue("Incorrect error message thrown:" + e.getMessage(),
+ e.getMessage().startsWith("Queue create request with non integer value for :x-qpid-priorities=seven"));
+ }
+ }
+
+ public void testCreateFlowToDiskValid() throws AMQException, FailoverException
+ {
+ Map<String, Object> arguments = new HashMap<String, Object>();
+
+ //Ensure we can call createQueue with a priority int value
+ arguments.put(AMQQueueFactory.QPID_POLICY_TYPE.toString(), AMQQueueFactory.QPID_FLOW_TO_DISK);
+ arguments.put(AMQQueueFactory.QPID_MAX_SIZE.toString(), 100);
+ testQueueWithArguments(arguments);
+ }
+
+ /**
+ * @link https://issues.apache.org/jira/browse/QPID-1715, QPID-1716
+ * @throws AMQException
+ * @throws FailoverException
+ */
+ public void testCreateFlowToDiskValidNoSize() throws AMQException, FailoverException
+ {
+ Map<String, Object> arguments = new HashMap<String, Object>();
+
+ //Ensure we can call createQueue with a priority int value
+ arguments.put(AMQQueueFactory.QPID_POLICY_TYPE.toString(), AMQQueueFactory.QPID_FLOW_TO_DISK);
+ try
+ {
+ testQueueWithArguments(arguments);
+ }
+ catch (AMQException e)
+ {
+ assertTrue("Incorrect Error throw:" + e.getMessage() +
+ ":expecting:Queue create request with no qpid.max_size value",
+ e.getMessage().contains("Queue create request with no qpid.max_size value"));
+ }
+ }
+
+ /**
+ * @link https://issues.apache.org/jira/browse/QPID-1715, QPID-1716
+ * @throws AMQException
+ * @throws FailoverException
+ */
+ public void testCreateFlowToDiskInvalid() throws AMQException, FailoverException
+ {
+ Map<String, Object> arguments = new HashMap<String, Object>();
+
+ arguments.put(AMQQueueFactory.QPID_POLICY_TYPE.toString(), "infinite");
+ try
+ {
+ testQueueWithArguments(arguments);
+ fail("Invalid Property value still succeeds.");
+ }
+ catch (Exception e)
+ {
+ //Check error is correct
+ assertTrue("Incorrect error message thrown:" + e.getMessage(),
+ e.getMessage().startsWith("Queue create request with unknown Policy Type:infinite"));
+ }
+
+ }
+
+ /**
+ * @link https://issues.apache.org/jira/browse/QPID-1715, QPID-1716
+ * @throws AMQException
+ * @throws FailoverException
+ */
+ public void testCreateFlowToDiskInvalidSize() throws AMQException, FailoverException
+ {
+ Map<String, Object> arguments = new HashMap<String, Object>();
+
+ arguments.put(AMQQueueFactory.QPID_POLICY_TYPE.toString(), AMQQueueFactory.QPID_FLOW_TO_DISK);
+ arguments.put(AMQQueueFactory.QPID_MAX_SIZE.toString(), -1);
+ try
+ {
+ testQueueWithArguments(arguments);
+ fail("Invalid Property value still succeeds.");
+ }
+ catch (Exception e)
+ {
+ //Check error is correct
+ assertTrue("Incorrect error message thrown:" + e.getMessage(),
+ e.getMessage().startsWith("Queue create request with negative size:-1"));
+ }
+
+ }
+
+
+}
diff --git a/qpid/java/systests/src/main/java/org/apache/qpid/server/queue/TimeToLiveTest.java b/qpid/java/systests/src/main/java/org/apache/qpid/server/queue/TimeToLiveTest.java
index 289ca0b1b0..5970d105eb 100644
--- a/qpid/java/systests/src/main/java/org/apache/qpid/server/queue/TimeToLiveTest.java
+++ b/qpid/java/systests/src/main/java/org/apache/qpid/server/queue/TimeToLiveTest.java
@@ -70,7 +70,9 @@ public class TimeToLiveTest extends QpidTestCase
producerConnection.start();
- Session producerSession = producerConnection.createSession(false, Session.AUTO_ACKNOWLEDGE);
+ // Move to a Transacted session to ensure that all messages have been delivered to broker before
+ // we start waiting for TTL
+ Session producerSession = producerConnection.createSession(true, Session.SESSION_TRANSACTED);
MessageProducer producer = producerSession.createProducer(queue);
@@ -89,12 +91,15 @@ public class TimeToLiveTest extends QpidTestCase
producer.setTimeToLive(0L);
producer.send(nextMessage(String.valueOf(msg), false, producerSession, producer));
+ producerSession.commit();
+
consumer = clientSession.createConsumer(queue);
// Ensure we sleep the required amount of time.
ReentrantLock waitLock = new ReentrantLock();
Condition wait = waitLock.newCondition();
final long MILLIS = 1000000L;
+
long waitTime = TIME_TO_LIVE * MILLIS;
while (waitTime > 0)
{
diff --git a/qpid/java/systests/src/main/java/org/apache/qpid/server/security/acl/SimpleACLTest.java b/qpid/java/systests/src/main/java/org/apache/qpid/server/security/acl/SimpleACLTest.java
index e6c9f43ffb..5d0e7f9186 100644
--- a/qpid/java/systests/src/main/java/org/apache/qpid/server/security/acl/SimpleACLTest.java
+++ b/qpid/java/systests/src/main/java/org/apache/qpid/server/security/acl/SimpleACLTest.java
@@ -61,12 +61,7 @@ public class SimpleACLTest extends QpidTestCase implements ConnectionListener
}
ConfigurationFileApplicationRegistry config = new ConfigurationFileApplicationRegistry(defaultaclConfigFile);
-
- // This is a bit evil it should be updated with QPID-1103
- config.getConfiguration().setProperty("management.enabled", "false");
-
ApplicationRegistry.initialise(config, 1);
-
TransportConnection.createVMBroker(1);
}
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 256491194d..c7c2c8b292 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
@@ -27,6 +27,7 @@ import org.apache.qpid.framing.AMQShortString;
import org.apache.qpid.framing.FieldTable;
import org.apache.qpid.framing.abstraction.ContentChunk;
import org.apache.qpid.server.virtualhost.VirtualHost;
+import org.apache.qpid.server.configuration.VirtualHostConfiguration;
import org.apache.qpid.server.exchange.Exchange;
import org.apache.qpid.server.queue.AMQQueue;
import org.apache.qpid.server.queue.MessageMetaData;
@@ -49,38 +50,38 @@ public class SlowMessageStore implements TransactionLog, RoutingTable
private static final String POST = "post";
private String DEFAULT_DELAY = "default";
- public void configure(VirtualHost virtualHost, String base, Configuration config) throws Exception
+ public void configure(VirtualHost virtualHost, String base, VirtualHostConfiguration config) throws Exception
{
- _logger.info("Starting SlowMessageStore on Virtualhost:" + virtualHost.getName());
- Configuration delays = config.subset(base + "." + DELAYS);
+ _logger.warn("Starting SlowMessageStore on Virtualhost:" + virtualHost.getName());
+ Configuration delays = config.getStoreConfiguration().subset(DELAYS);
configureDelays(delays);
- String transactionLogClass = config.getString(base + ".store.class");
+ String transactionLogClass = config.getTransactionLogClass();
if (delays.containsKey(DEFAULT_DELAY))
{
_defaultDelay = delays.getLong(DEFAULT_DELAY);
+ _logger.warn("Delay is:" + _defaultDelay);
}
if (transactionLogClass != null)
{
Class clazz = Class.forName(transactionLogClass);
+ if (clazz != this.getClass())
+ {
- Object o = clazz.newInstance();
+ Object o = clazz.newInstance();
- if (!(o instanceof TransactionLog))
- {
- throw new ClassCastException("TransactionLog class must implement " + TransactionLog.class + ". Class " + clazz +
- " does not.");
+ if (!(o instanceof TransactionLog))
+ {
+ throw new ClassCastException("TransactionLog class must implement " + TransactionLog.class + ". Class " + clazz +
+ " does not.");
+ }
+ _realTransactionLog = (TransactionLog) o;
}
- _realTransactionLog = (TransactionLog) o;
- _realTransactionLog.configure(virtualHost, base , config);
- }
- else
- {
- _realTransactionLog.configure(virtualHost, base , config);
}
+ _realTransactionLog.configure(virtualHost, base , config);
}
private void configureDelays(Configuration config)
@@ -157,13 +158,6 @@ public class SlowMessageStore implements TransactionLog, RoutingTable
doPostDelay("close");
}
- public void removeMessage(StoreContext storeContext, Long messageId) throws AMQException
- {
- doPreDelay("removeMessage");
- _realTransactionLog.removeMessage(storeContext, messageId);
- doPostDelay("removeMessage");
- }
-
public void createExchange(Exchange exchange) throws AMQException
{
doPreDelay("createExchange");
diff --git a/qpid/java/systests/src/main/java/org/apache/qpid/test/client/QueueBrowsingFlowToDiskTest.java b/qpid/java/systests/src/main/java/org/apache/qpid/test/client/QueueBrowsingFlowToDiskTest.java
new file mode 100644
index 0000000000..02965b5ab7
--- /dev/null
+++ b/qpid/java/systests/src/main/java/org/apache/qpid/test/client/QueueBrowsingFlowToDiskTest.java
@@ -0,0 +1,69 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.qpid.test.client;
+
+import org.apache.qpid.AMQException;
+import org.apache.qpid.framing.AMQShortString;
+import org.apache.qpid.client.AMQSession;
+import org.apache.qpid.server.queue.AMQQueueFactory;
+
+import javax.jms.JMSException;
+import javax.jms.Connection;
+import javax.jms.Session;
+import java.util.Map;
+import java.util.HashMap;
+
+public class QueueBrowsingFlowToDiskTest extends QueueBrowserAutoAckTest
+{
+ @Override
+ protected void sendMessages(Connection producerConnection, int messageSendCount) throws JMSException
+ {
+ try
+ {
+ setupFlowToDisk(producerConnection, messageSendCount , this.getName());
+ }
+ catch (AMQException e)
+ {
+ fail("Unable to setup Flow to disk:"+e.getMessage());
+ }
+
+ super.sendMessages(producerConnection,messageSendCount);
+ }
+
+ private void setupFlowToDisk(Connection producerConnection, int messages, String name)
+ throws AMQException, JMSException
+ {
+ Map<String, Object> arguments = new HashMap<String, Object>();
+
+ //Ensure we can call createQueue with a priority int value
+ arguments.put(AMQQueueFactory.QPID_POLICY_TYPE.toString(), AMQQueueFactory.QPID_FLOW_TO_DISK);
+ // each message in the QBAAT is around 9-10 bytes each so only give space for half
+ arguments.put(AMQQueueFactory.QPID_MAX_SIZE.toString(), 5 * messages);
+
+ //Create the FlowToDisk Queue
+ ((AMQSession) producerConnection.createSession(false, Session.AUTO_ACKNOWLEDGE)).
+ createQueue(new AMQShortString(name), false, false, false, arguments);
+
+ // Get a JMS reference to the new queue
+ _queue = _clientSession.createQueue(name);
+ }
+
+}
diff --git a/qpid/java/systests/src/main/java/org/apache/qpid/test/client/failover/FailoverTest.java b/qpid/java/systests/src/main/java/org/apache/qpid/test/client/failover/FailoverTest.java
index 3a1fb50725..b7ae911a49 100644
--- a/qpid/java/systests/src/main/java/org/apache/qpid/test/client/failover/FailoverTest.java
+++ b/qpid/java/systests/src/main/java/org/apache/qpid/test/client/failover/FailoverTest.java
@@ -21,36 +21,37 @@
package org.apache.qpid.test.client.failover;
-import org.apache.qpid.client.AMQConnection;
-import org.apache.qpid.client.AMQConnectionFactory;
-import org.apache.qpid.client.AMQConnectionURL;
-import org.apache.qpid.client.transport.TransportConnection;
-import org.apache.qpid.jms.ConnectionListener;
-import org.apache.qpid.jms.ConnectionURL;
-import org.apache.qpid.jms.BrokerDetails;
-import org.apache.qpid.server.registry.ApplicationRegistry;
-import org.apache.qpid.test.utils.FailoverBaseCase;
-import org.apache.log4j.Logger;
+import java.util.Random;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
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 javax.jms.TextMessage;
-import javax.jms.Queue;
import javax.naming.NamingException;
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.TimeUnit;
+
+import org.apache.log4j.Logger;
+import org.apache.qpid.client.AMQConnection;
+import org.apache.qpid.client.AMQSession_0_10;
+import org.apache.qpid.jms.BrokerDetails;
+import org.apache.qpid.jms.ConnectionListener;
+import org.apache.qpid.jms.ConnectionURL;
+import org.apache.qpid.test.utils.FailoverBaseCase;
public class FailoverTest extends FailoverBaseCase implements ConnectionListener
{
private static final Logger _logger = Logger.getLogger(FailoverTest.class);
private static final String QUEUE = "queue";
- private static final int NUM_MESSAGES = 10;
- private Connection connnection;
+ private static final int DEFAULT_NUM_MESSAGES = 10;
+ private static final int DEFAULT_SEED = 20080921;
+ protected int numMessages = 0;
+ protected Connection connection;
private Session producerSession;
private Queue queue;
private MessageProducer producer;
@@ -61,26 +62,32 @@ public class FailoverTest extends FailoverBaseCase implements ConnectionListener
private CountDownLatch failoverComplete;
private static final long DEFAULT_FAILOVER_TIME = 10000L;
private boolean CLUSTERED = Boolean.getBoolean("profile.clustered");
-
+ private int seed;
+ private Random rand;
+
@Override
protected void setUp() throws Exception
{
super.setUp();
-
- connnection = getConnection();
- ((AMQConnection) connnection).setConnectionListener(this);
- connnection.start();
+
+ numMessages = Integer.getInteger("profile.failoverMsgCount",DEFAULT_NUM_MESSAGES);
+ seed = Integer.getInteger("profile.failoverRandomSeed",DEFAULT_SEED);
+ rand = new Random(seed);
+
+ connection = getConnection();
+ ((AMQConnection) connection).setConnectionListener(this);
+ connection.start();
failoverComplete = new CountDownLatch(1);
}
- private void init(boolean transacted, int mode) throws JMSException, NamingException
+ protected void init(boolean transacted, int mode) throws JMSException, NamingException
{
queue = (Queue) getInitialContext().lookup(QUEUE);
- consumerSession = connnection.createSession(transacted, mode);
+ consumerSession = connection.createSession(transacted, mode);
consumer = consumerSession.createConsumer(queue);
- producerSession = connnection.createSession(transacted, mode);
+ producerSession = connection.createSession(transacted, mode);
producer = producerSession.createProducer(queue);
}
@@ -89,7 +96,7 @@ public class FailoverTest extends FailoverBaseCase implements ConnectionListener
{
try
{
- connnection.close();
+ connection.close();
}
catch (Exception e)
{
@@ -99,26 +106,46 @@ public class FailoverTest extends FailoverBaseCase implements ConnectionListener
super.tearDown();
}
- private void consumeMessages(int toConsume, boolean transacted) throws JMSException
+ private void consumeMessages(int startIndex,int endIndex, boolean transacted) throws JMSException
{
Message msg;
- for (int i = 0; i < toConsume; i++)
+ _logger.debug("**************** Receive (Start: " + startIndex + ", End:" + endIndex + ")***********************");
+
+ for (int i = startIndex; i < endIndex; i++)
{
- msg = consumer.receive(1000);
+ msg = consumer.receive(1000);
assertNotNull("Message " + i + " was null!", msg);
- assertEquals("message " + i, ((TextMessage) msg).getText());
+
+ _logger.debug("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@");
+ _logger.debug("Received : " + ((TextMessage) msg).getText());
+ _logger.debug("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@");
+
+ assertEquals("Invalid message order","message " + i, ((TextMessage) msg).getText());
+
}
- if (transacted) {
+ _logger.debug("***********************************************************");
+
+ if (transacted)
+ {
consumerSession.commit();
}
}
- private void sendMessages(int totalMessages, boolean transacted) throws JMSException
+ private void sendMessages(int startIndex,int endIndex, boolean transacted) throws JMSException
{
- for (int i = 0; i < totalMessages; i++)
- {
+ _logger.debug("**************** Send (Start: " + startIndex + ", End:" + endIndex + ")***********************");
+
+ for (int i = startIndex; i < endIndex; i++)
+ {
producer.send(producerSession.createTextMessage("message " + i));
+
+ _logger.debug("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@");
+ _logger.debug("Sending message"+i);
+ _logger.debug("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@");
}
+
+ _logger.debug("***********************************************************");
+
if (transacted)
{
producerSession.commit();
@@ -127,47 +154,93 @@ public class FailoverTest extends FailoverBaseCase implements ConnectionListener
public void testP2PFailover() throws Exception
{
- testP2PFailover(NUM_MESSAGES, true, false);
+ testP2PFailover(numMessages, true,true, false);
}
- public void testP2PFailoverWithMessagesLeft() throws Exception
+ public void testP2PFailoverWithMessagesLeftToConsumeAndProduce() throws Exception
{
- testP2PFailover(NUM_MESSAGES, false, false);
+ if (CLUSTERED)
+ {
+ testP2PFailover(numMessages, false,false, false);
+ }
}
-
+
+ public void testP2PFailoverWithMessagesLeftToConsume() throws Exception
+ {
+ if (CLUSTERED)
+ {
+ testP2PFailover(numMessages, false,true, false);
+ }
+ }
+
public void testP2PFailoverTransacted() throws Exception
{
- testP2PFailover(NUM_MESSAGES, true, false);
+ testP2PFailover(numMessages, true,true, false);
}
- private void testP2PFailover(int totalMessages, boolean consumeAll, boolean transacted) throws JMSException, NamingException
+ public void testP2PFailoverTransactedWithMessagesLeftToConsumeAndProduce() throws Exception
{
- Message msg = null;
+ // Currently the cluster does not support transactions that span a failover
+ if (CLUSTERED)
+ {
+ testP2PFailover(numMessages, false,false, false);
+ }
+ }
+
+ private void testP2PFailover(int totalMessages, boolean consumeAll, boolean produceAll , boolean transacted) throws JMSException, NamingException
+ {
init(transacted, Session.AUTO_ACKNOWLEDGE);
- sendMessages(totalMessages, transacted);
+ runP2PFailover(totalMessages,consumeAll, produceAll , transacted);
+ }
+
+ protected void runP2PFailover(int totalMessages, boolean consumeAll, boolean produceAll , boolean transacted) throws JMSException, NamingException
+ {
+ Message msg = null;
+ int toProduce = totalMessages;
+
+ _logger.debug("===================================================================");
+ _logger.debug("Total messages used for the test " + totalMessages + " messages");
+ _logger.debug("===================================================================");
+
+ if (!produceAll)
+ {
+ toProduce = totalMessages - rand.nextInt(totalMessages);
+ }
+
+ _logger.debug("==================");
+ _logger.debug("Sending " + toProduce + " messages");
+ _logger.debug("==================");
+
+ sendMessages(0,toProduce, transacted);
// Consume some messages
- int toConsume = totalMessages;
+ int toConsume = toProduce;
if (!consumeAll)
{
- toConsume = totalMessages / 2;
+ toConsume = toProduce - rand.nextInt(toProduce);
}
+
+ consumeMessages(0,toConsume, transacted);
- consumeMessages(toConsume, transacted);
-
+ _logger.debug("==================");
+ _logger.debug("Consuming " + toConsume + " messages");
+ _logger.debug("==================");
+
_logger.info("Failing over");
causeFailure(DEFAULT_FAILOVER_TIME);
- if (!CLUSTERED)
- {
- msg = consumer.receive(500);
- assertNull("Should not have received message from new broker!", msg);
- }
-
- // Check that messages still sent / received
- sendMessages(totalMessages, transacted);
- consumeMessages(totalMessages, transacted);
+ // Check that you produce and consume the rest of messages.
+ _logger.debug("==================");
+ _logger.debug("Sending " + (totalMessages-toProduce) + " messages");
+ _logger.debug("==================");
+
+ sendMessages(toProduce,totalMessages, transacted);
+ consumeMessages(toConsume,totalMessages, transacted);
+
+ _logger.debug("==================");
+ _logger.debug("Consuming " + (totalMessages-toConsume) + " messages");
+ _logger.debug("==================");
}
private void causeFailure(long delay)
@@ -188,11 +261,11 @@ public class FailoverTest extends FailoverBaseCase implements ConnectionListener
//evil ignore IE.
}
}
-
+
public void testClientAckFailover() throws Exception
{
init(false, Session.CLIENT_ACKNOWLEDGE);
- sendMessages(1, false);
+ sendMessages(0,1, false);
Message msg = consumer.receive();
assertNotNull("Expected msgs not received", msg);
@@ -208,7 +281,7 @@ public class FailoverTest extends FailoverBaseCase implements ConnectionListener
failure = e;
}
assertNotNull("Exception should be thrown", failure);
- }
+ }
/**
* The client used to have a fixed timeout of 4 minutes after which failover would no longer work.
@@ -216,6 +289,7 @@ public class FailoverTest extends FailoverBaseCase implements ConnectionListener
*
* @throws Exception if something unexpected occurs in the test.
*/
+
public void test4MinuteFailover() throws Exception
{
ConnectionURL connectionURL = getConnectionFactory().getConnectionURL();
@@ -228,12 +302,12 @@ public class FailoverTest extends FailoverBaseCase implements ConnectionListener
details.setProperty(BrokerDetails.OPTIONS_RETRY, String.valueOf(RETRIES));
details.setProperty(BrokerDetails.OPTIONS_CONNECT_DELAY, String.valueOf(DELAY));
- connnection = new AMQConnection(connectionURL, null);
+ connection = new AMQConnection(connectionURL, null);
- ((AMQConnection) connnection).setConnectionListener(this);
+ ((AMQConnection) connection).setConnectionListener(this);
//Start the connection
- connnection.start();
+ connection.start();
long FAILOVER_DELAY = (RETRIES * DELAY);
@@ -247,6 +321,51 @@ public class FailoverTest extends FailoverBaseCase implements ConnectionListener
assertTrue("Failover did not take long enough", System.nanoTime() > failTime);
}
+
+ /**
+ * The idea is to run a failover test in a loop by failing over
+ * to the other broker each time.
+ */
+ public void testFailoverInALoop() throws Exception
+ {
+ if (!CLUSTERED)
+ {
+ return;
+ }
+
+ int iterations = Integer.getInteger("profile.failoverIterations",0);
+ boolean b = true;
+ int failingPort = getFailingPort();
+ init(false, Session.AUTO_ACKNOWLEDGE);
+ for (int i=0; i < iterations; i++)
+ {
+ _logger.debug("===================================================================");
+ _logger.debug("Failover In a loop : iteration number " + i);
+ _logger.debug("===================================================================");
+
+ runP2PFailover(numMessages, false,false, false);
+ startBroker(failingPort);
+ if (b)
+ {
+ failingPort = getFailingPort()-1;
+ b = false;
+ }
+ else
+ {
+ failingPort = getFailingPort()+1;
+ b = true;
+ }
+ setFailingPort(failingPort);
+ }
+ //To prevent any failover logic being initiaed when we shutdown the brokers.
+ connection.close();
+
+ // Shutdown the brokers
+ stopBroker(getFailingPort());
+ stopBroker(b?getFailingPort()+1 : getFailingPort()-1);
+
+ }
+
public void bytesSent(long count)
{
}
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
new file mode 100644
index 0000000000..001a40988b
--- /dev/null
+++ b/qpid/java/systests/src/main/java/org/apache/qpid/test/client/message/ObjectMessageTest.java
@@ -0,0 +1,136 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.qpid.test.client.message;
+
+import org.apache.qpid.client.AMQQueue;
+import org.apache.qpid.test.utils.QpidTestCase;
+
+import javax.jms.Connection;
+import javax.jms.JMSException;
+import javax.jms.MessageConsumer;
+import javax.jms.MessageProducer;
+import javax.jms.ObjectMessage;
+import javax.jms.Queue;
+import javax.jms.Session;
+import java.util.UUID;
+
+public class ObjectMessageTest extends QpidTestCase
+{
+ private Connection _connection;
+ private Session _session;
+ MessageConsumer _consumer;
+ MessageProducer _producer;
+
+ public void setUp() throws Exception
+ {
+ super.setUp();
+
+ //Create Connection
+ _connection = getConnection();
+
+ //Create Queue
+ Queue queue = new AMQQueue("amq.direct", "queue");
+
+ //Create Session
+ _session = _connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
+
+ //Create Consumer
+ _consumer = _session.createConsumer(queue);
+
+ //Create Producer
+ _producer = _session.createProducer(queue);
+
+ _connection.start();
+ }
+
+ public void tearDown() throws Exception
+ {
+ //clean up
+ _connection.close();
+
+ super.tearDown();
+ }
+
+ public void testGetAndSend() throws JMSException
+ {
+ //Create Sample Message using UUIDs
+ UUID test = UUID.randomUUID();
+
+ ObjectMessage testMessage = _session.createObjectMessage(test);
+
+ Object o = testMessage.getObject();
+
+ assertNotNull("Object was null", o);
+
+ sendAndTest(testMessage, test);
+ }
+
+ public void testSend() throws JMSException
+ {
+ //Create Sample Message using UUIDs
+ UUID test = UUID.randomUUID();
+
+ ObjectMessage testMessage = _session.createObjectMessage(test);
+
+ sendAndTest(testMessage, test);
+ }
+
+ public void testTostringAndSend() throws JMSException
+ {
+ //Create Sample Message using UUIDs
+ UUID test = UUID.randomUUID();
+
+ ObjectMessage testMessage = _session.createObjectMessage(test);
+
+ assertNotNull("Object was null", testMessage.toString());
+
+ sendAndTest(testMessage, test);
+ }
+
+ public void testSendNull() throws JMSException
+ {
+
+ ObjectMessage testMessage = _session.createObjectMessage(null);
+
+ assertNotNull("Object was null", testMessage.toString());
+
+ sendAndTest(testMessage, null);
+ }
+
+ //***************** Helpers
+
+ private void sendAndTest(ObjectMessage message, Object sent) throws JMSException
+ {
+ _producer.send(message);
+
+ ObjectMessage receivedMessage = (ObjectMessage) _consumer.receive(1000);
+
+ assertNotNull("Message was not received.", receivedMessage);
+
+ UUID result = (UUID) receivedMessage.getObject();
+
+ assertEquals("First read: UUIDs were not equal", sent, result);
+
+ result = (UUID) receivedMessage.getObject();
+
+ assertEquals("Second read: UUIDs were not equal", sent, result);
+ }
+}
diff --git a/qpid/java/systests/src/main/java/org/apache/qpid/test/client/timeouts/SyncWaitDelayTest.java b/qpid/java/systests/src/main/java/org/apache/qpid/test/client/timeouts/SyncWaitDelayTest.java
index f2c8a5e1f5..59ee4ad511 100644
--- a/qpid/java/systests/src/main/java/org/apache/qpid/test/client/timeouts/SyncWaitDelayTest.java
+++ b/qpid/java/systests/src/main/java/org/apache/qpid/test/client/timeouts/SyncWaitDelayTest.java
@@ -20,13 +20,7 @@
*/
package org.apache.qpid.test.client.timeouts;
-import org.apache.commons.configuration.Configuration;
-import org.apache.qpid.server.registry.ConfigurationFileApplicationRegistry;
-import org.apache.qpid.server.registry.ApplicationRegistry;
-import org.apache.qpid.test.utils.QpidTestCase;
-import org.apache.qpid.client.transport.TransportConnection;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
+import java.io.File;
import javax.jms.Connection;
import javax.jms.JMSException;
@@ -35,7 +29,13 @@ import javax.jms.MessageConsumer;
import javax.jms.MessageProducer;
import javax.jms.Queue;
import javax.jms.Session;
-import java.io.File;
+
+import org.apache.commons.configuration.XMLConfiguration;
+import org.apache.qpid.server.registry.ApplicationRegistry;
+import org.apache.qpid.server.registry.ConfigurationFileApplicationRegistry;
+import org.apache.qpid.test.utils.QpidTestCase;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
/**
* This tests that when the commit takes a long time(due to POST_COMMIT_DELAY) that the commit does not timeout
@@ -67,16 +67,19 @@ public class SyncWaitDelayTest extends QpidTestCase
fail("Unable to test without config file:" + _configFile);
}
- ConfigurationFileApplicationRegistry config = new ConfigurationFileApplicationRegistry(_configFile);
-
- //Disable management on broker.
- config.getConfiguration().setProperty("management.enabled", "false");
-
- Configuration testVirtualhost = config.getConfiguration().subset("virtualhosts.virtualhost." + VIRTUALHOST);
- testVirtualhost.setProperty("store.class", "org.apache.qpid.server.store.SlowMessageStore");
- testVirtualhost.setProperty("store.delays.commitTran.post", POST_COMMIT_DELAY);
-
- startBroker(1, config);
+ XMLConfiguration configuration = new XMLConfiguration(_configFile);
+ configuration.setProperty("virtualhosts.virtualhost." + VIRTUALHOST+".store.class", "org.apache.qpid.server.store.SlowMessageStore");
+ configuration.setProperty("virtualhosts.virtualhost." + VIRTUALHOST+".store.delays.commitTran.post", POST_COMMIT_DELAY);
+ configuration.setProperty("management.enabled", "false");
+
+
+ File tmpFile = File.createTempFile("configFile", "test");
+ tmpFile.deleteOnExit();
+ configuration.save(tmpFile);
+
+ ApplicationRegistry reg = new ConfigurationFileApplicationRegistry(tmpFile);
+
+ startBroker(1, reg);
//Set the syncWrite timeout to be just larger than the delay on the commitTran.
setSystemProperty("amqj.default_syncwrite_timeout", String.valueOf(SYNC_WRITE_TIMEOUT));
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 b932b1d784..5d8ee785ec 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
@@ -77,7 +77,7 @@ public class ConnectionCloseTest extends QpidTestCase
// This should leave the finalizer enough time to notify those threads
synchronized (this)
{
- this.wait(1000);
+ this.wait(10000);
}
Map<Thread,StackTraceElement[]> after = Thread.getAllStackTraces();
diff --git a/qpid/java/systests/src/main/java/org/apache/qpid/test/utils/FailoverBaseCase.java b/qpid/java/systests/src/main/java/org/apache/qpid/test/utils/FailoverBaseCase.java
index 2a44c444e0..b185ec60a2 100644
--- a/qpid/java/systests/src/main/java/org/apache/qpid/test/utils/FailoverBaseCase.java
+++ b/qpid/java/systests/src/main/java/org/apache/qpid/test/utils/FailoverBaseCase.java
@@ -20,30 +20,34 @@
*/
package org.apache.qpid.test.utils;
-import org.apache.qpid.client.transport.TransportConnection;
-import org.apache.qpid.server.registry.ApplicationRegistry;
-
import javax.jms.Connection;
public class FailoverBaseCase extends QpidTestCase
{
- protected int FAILING_VM_PORT = 2;
- protected int FAILING_PORT = 5673;
+ public static int FAILING_VM_PORT = 2;
+ public static int FAILING_PORT = 5673;
+ protected int failingPort;
+
private boolean failedOver = false;
- private int getFailingPort()
+ public FailoverBaseCase()
{
if (_broker.equals(VM))
{
- return FAILING_VM_PORT;
+ failingPort = FAILING_VM_PORT;
}
else
{
- return FAILING_PORT;
+ failingPort = FAILING_PORT;
}
}
+
+ protected int getFailingPort()
+ {
+ return failingPort;
+ }
protected void setUp() throws java.lang.Exception
{
@@ -67,10 +71,16 @@ public class FailoverBaseCase extends QpidTestCase
public void tearDown() throws Exception
{
- if (!failedOver)
+ int port;
+ if (_broker.equals(VM))
{
- stopBroker(getFailingPort());
+ port = FAILING_VM_PORT;
}
+ else
+ {
+ port = FAILING_PORT;
+ }
+ stopBroker(port);
super.tearDown();
}
@@ -90,4 +100,9 @@ public class FailoverBaseCase extends QpidTestCase
throw new RuntimeException(e);
}
}
+
+ protected void setFailingPort(int p)
+ {
+ failingPort = p;
+ }
}
diff --git a/qpid/java/systests/src/main/java/org/apache/qpid/test/utils/QpidTestCase.java b/qpid/java/systests/src/main/java/org/apache/qpid/test/utils/QpidTestCase.java
index d0bb265a0c..00c1da69e9 100644
--- a/qpid/java/systests/src/main/java/org/apache/qpid/test/utils/QpidTestCase.java
+++ b/qpid/java/systests/src/main/java/org/apache/qpid/test/utils/QpidTestCase.java
@@ -229,11 +229,13 @@ public class QpidTestCase extends TestCase
private LineNumberReader in;
private String ready;
private CountDownLatch latch;
+ private boolean seenReady;
public Piper(InputStream in, String ready)
{
this.in = new LineNumberReader(new InputStreamReader(in));
this.ready = ready;
+ this.seenReady = false;
if (this.ready != null && !this.ready.equals(""))
{
this.latch = new CountDownLatch(1);
@@ -257,7 +259,8 @@ public class QpidTestCase extends TestCase
}
else
{
- return latch.await(timeout, unit);
+ latch.await(timeout, unit);
+ return seenReady;
}
}
@@ -271,6 +274,7 @@ public class QpidTestCase extends TestCase
System.out.println(line);
if (latch != null && line.contains(ready))
{
+ seenReady = true;
latch.countDown();
}
}
@@ -290,7 +294,7 @@ public class QpidTestCase extends TestCase
}
}
- public void startBroker(int port, ConfigurationFileApplicationRegistry config) throws Exception
+ public void startBroker(int port, ApplicationRegistry config) throws Exception
{
ApplicationRegistry.initialise(config, port);
startBroker(port);
diff --git a/qpid/java/test-provider.properties b/qpid/java/test-provider.properties
index 8066256f4f..5e2ab9c9cf 100644
--- a/qpid/java/test-provider.properties
+++ b/qpid/java/test-provider.properties
@@ -23,7 +23,7 @@ connectionfactory.default = amqp://username:password@clientid/test?brokerlist='t
connectionfactory.default.vm = amqp://username:password@clientid/test?brokerlist='vm://:1'
connectionfactory.ssl = amqp://username:password@clientid/test?brokerlist='tcp://localhost:5671?ssl='true''
-connectionfactory.failover = amqp://username:password@clientid/test?brokerlist='tcp://localhost:5673;tcp://localhost:5672'
+connectionfactory.failover = amqp://username:password@clientid/test?brokerlist='tcp://localhost:5673;tcp://localhost:5672'&sync_ack='true'&sync_publish='all'&failover='roundrobin?cyclecount='20''
connectionfactory.failover.vm = amqp://username:password@clientid/test?brokerlist='vm://:2;vm://:1'
connectionfactory.connection1 = amqp://username:password@clientid/test?brokerlist='tcp://localhost:5672'
connectionfactory.connection2 = amqp://username:password@clientid/test?brokerlist='tcp://localhost:5673'
diff --git a/qpid/java/tools/src/main/java/org/apache/qpid/tools/QpidBench.java b/qpid/java/tools/src/main/java/org/apache/qpid/tools/QpidBench.java
index 4bba7b113d..9770adceb0 100644
--- a/qpid/java/tools/src/main/java/org/apache/qpid/tools/QpidBench.java
+++ b/qpid/java/tools/src/main/java/org/apache/qpid/tools/QpidBench.java
@@ -696,6 +696,8 @@ public class QpidBench
public void opened(org.apache.qpid.transport.Session ssn) {}
+ public void resumed(org.apache.qpid.transport.Session ssn) {}
+
public void exception(org.apache.qpid.transport.Session ssn,
SessionException exc)
{
diff --git a/qpid/python/commands/qpid-cluster b/qpid/python/commands/qpid-cluster
index f2028d944b..07fa666041 100755
--- a/qpid/python/commands/qpid-cluster
+++ b/qpid/python/commands/qpid-cluster
@@ -23,12 +23,17 @@ import os
import getopt
import sys
import locale
+import socket
+import re
from qmf.console import Session
_host = "localhost"
_stopId = None
_stopAll = False
_force = False
+_numeric = False
+_showConn = False
+_delConn = None
def Usage ():
print "Usage: qpid-cluster [OPTIONS] [broker-addr]"
@@ -37,12 +42,43 @@ def Usage ():
print " ex: localhost, 10.1.1.7:10000, broker-host:10000, guest/guest@localhost"
print
print "Options:"
- print " -s [--stop] ID Stop one member of the cluster by its ID"
- print " -k [--all-stop] Shut down the whole cluster"
- print " -f [--force] Suppress the 'are-you-sure?' prompt"
+ print " -C [--all-connections] View client connections to all cluster members"
+ print " -c [--connections] ID View client connections to specified member"
+ print " -d [--del-connection] HOST:PORT"
+ print " Disconnect a client connection"
+ print " -s [--stop] ID Stop one member of the cluster by its ID"
+ print " -k [--all-stop] Shut down the whole cluster"
+ print " -f [--force] Suppress the 'are-you-sure?' prompt"
+ print " -n [--numeric] Don't resolve names"
print
sys.exit (1)
+
+class IpAddr:
+ def __init__(self, text):
+ if text.find("@") != -1:
+ tokens = text.split("@")
+ text = tokens[1]
+ if text.find(":") != -1:
+ tokens = text.split(":")
+ text = tokens[0]
+ self.port = int(tokens[1])
+ else:
+ self.port = 5672
+ self.dottedQuad = socket.gethostbyname(text)
+ nums = self.dottedQuad.split(".")
+ self.addr = (int(nums[0]) << 24) + (int(nums[1]) << 16) + (int(nums[2]) << 8) + int(nums[3])
+
+ def bestAddr(self, addrPortList):
+ bestDiff = 0xFFFFFFFFL
+ bestAddr = None
+ for addrPort in addrPortList:
+ diff = IpAddr(addrPort[0]).addr ^ self.addr
+ if diff < bestDiff:
+ bestDiff = diff
+ bestAddr = addrPort
+ return bestAddr
+
class BrokerManager:
def __init__(self):
self.brokerName = None
@@ -62,7 +98,7 @@ class BrokerManager:
if self.broker:
self.qmf.delBroker(self.broker)
- def overview(self):
+ def _getClusters(self):
packages = self.qmf.getPackages()
if "org.apache.qpid.cluster" not in packages:
print "Clustering is not installed on the broker."
@@ -73,8 +109,35 @@ class BrokerManager:
print "Clustering is installed but not enabled on the broker."
sys.exit(0)
+ return clusters
+
+ def _getHostList(self, urlList):
+ hosts = []
+ hostAddr = IpAddr(_host)
+ for url in urlList:
+ if url.find("amqp:") != 0:
+ raise Exception("Invalid URL 1")
+ url = url[5:]
+ addrs = str(url).split(",")
+ addrList = []
+ for addr in addrs:
+ tokens = addr.split(":")
+ if len(tokens) != 3:
+ raise Exception("Invalid URL 2")
+ addrList.append((tokens[1], tokens[2]))
+
+ # Find the address in the list that is most likely to be in the same subnet as the address
+ # with which we made the original QMF connection. This increases the probability that we will
+ # be able to reach the cluster member.
+
+ best = hostAddr.bestAddr(addrList)
+ bestUrl = best[0] + ":" + best[1]
+ hosts.append(bestUrl)
+ return hosts
+
+ def overview(self):
+ clusters = self._getClusters()
cluster = clusters[0]
- myUrl = cluster.publishedURL
memberList = cluster.members.split(";")
idList = cluster.memberIDs.split(";")
@@ -86,11 +149,7 @@ class BrokerManager:
print " : ID=%s URL=%s" % (idList[idx], memberList[idx])
def stopMember(self, id):
- clusters = self.qmf.getObjects(_class="cluster", _agent=self.brokerAgent)
- if len(clusters) == 0:
- print "Clustering is installed but not enabled on the broker."
- sys.exit(0)
-
+ clusters = self._getClusters()
cluster = clusters[0]
idList = cluster.memberIDs.split(";")
if id not in idList:
@@ -113,11 +172,7 @@ class BrokerManager:
cluster.stopClusterNode(id)
def stopAll(self):
- clusters = self.qmf.getObjects(_class="cluster", _agent=self.brokerAgent)
- if len(clusters) == 0:
- print "Clustering is installed but not enabled on the broker."
- sys.exit(0)
-
+ clusters = self._getClusters()
if not _force:
prompt = "Warning: This command will shut down the entire cluster."
prompt += " Are you sure? [N]: "
@@ -130,15 +185,72 @@ class BrokerManager:
cluster = clusters[0]
cluster.stopFullCluster()
+ def showConnections(self):
+ clusters = self._getClusters()
+ cluster = clusters[0]
+ memberList = cluster.members.split(";")
+ idList = cluster.memberIDs.split(";")
+ displayList = []
+ hostList = self._getHostList(memberList)
+ self.qmf.delBroker(self.broker)
+ self.broker = None
+ self.brokers = []
+ pattern = re.compile("^\\d+\\.\\d+\\.\\d+\\.\\d+:\\d+$")
+
+ idx = 0
+ for host in hostList:
+ if _showConn == "all" or _showConn == idList[idx] or _delConn:
+ self.brokers.append(self.qmf.addBroker(host))
+ displayList.append(idList[idx])
+ idx += 1
+
+ idx = 0
+ found = False
+ for broker in self.brokers:
+ if not _delConn:
+ print "Clients on Member: ID=%s:" % displayList[idx]
+ connList = self.qmf.getObjects(_class="connection", _package="org.apache.qpid.broker", _broker=broker)
+ for conn in connList:
+ if pattern.match(conn.address):
+ if _numeric or _delConn:
+ a = conn.address
+ else:
+ tokens = conn.address.split(":")
+ try:
+ hostList = socket.gethostbyaddr(tokens[0])
+ host = hostList[0]
+ except:
+ host = tokens[0]
+ a = host + ":" + tokens[1]
+ if _delConn:
+ tokens = _delConn.split(":")
+ ip = socket.gethostbyname(tokens[0])
+ toDelete = ip + ":" + tokens[1]
+ if a == toDelete:
+ print "Closing connection from client: %s" % a
+ conn.close()
+ found = True
+ else:
+ print " %s" % a
+ idx += 1
+ if not _delConn:
+ print
+ if _delConn and not found:
+ print "Client connection '%s' not found" % _delConn
+
+ for broker in self.brokers:
+ self.qmf.delBroker(broker)
+
+
##
## Main Program
##
try:
- longOpts = ("stop=", "all-stop", "force")
- (optlist, encArgs) = getopt.gnu_getopt (sys.argv[1:], "s:kf", longOpts)
+ longOpts = ("stop=", "all-stop", "force", "connections=", "all-connections" "del-connection=", "numeric")
+ (optlist, encArgs) = getopt.gnu_getopt(sys.argv[1:], "s:kfCc:d:n", longOpts)
except:
- Usage ()
+ Usage()
try:
encoding = locale.getpreferredencoding()
@@ -146,13 +258,41 @@ try:
except:
cargs = encArgs
+count = 0
for opt in optlist:
if opt[0] == "-s" or opt[0] == "--stop":
_stopId = opt[1]
+ if len(_stopId.split(":")) != 2:
+ print "Member ID must be of form: <host or ip>:<number>"
+ sys.exit(1)
+ count += 1
if opt[0] == "-k" or opt[0] == "--all-stop":
_stopAll = True
+ count += 1
if opt[0] == "-f" or opt[0] == "--force":
_force = True
+ if opt[0] == "-n" or opt[0] == "--numeric":
+ _numeric = True
+ if opt[0] == "-C" or opt[0] == "--all-connections":
+ _showConn = "all"
+ count += 1
+ if opt[0] == "-c" or opt[0] == "--connections":
+ _showConn = opt[1]
+ if len(_showConn.split(":")) != 2:
+ print "Member ID must be of form: <host or ip>:<number>"
+ sys.exit(1)
+ count += 1
+ if opt[0] == "-d" or opt[0] == "--del-connection":
+ _delConn = opt[1]
+ if len(_delConn.split(":")) != 2:
+ print "Connection must be of form: <host or ip>:<port>"
+ sys.exit(1)
+ count += 1
+
+if count > 1:
+ print "Only one command option may be supplied"
+ print
+ Usage()
nargs = len(cargs)
bm = BrokerManager()
@@ -166,6 +306,8 @@ try:
bm.stopMember(_stopId)
elif _stopAll:
bm.stopAll()
+ elif _showConn or _delConn:
+ bm.showConnections()
else:
bm.overview()
except KeyboardInterrupt:
diff --git a/qpid/python/commands/qpid-config b/qpid/python/commands/qpid-config
index a7d537edb5..144fe36953 100755
--- a/qpid/python/commands/qpid-config
+++ b/qpid/python/commands/qpid-config
@@ -27,8 +27,12 @@ from qmf.console import Session
_recursive = False
_host = "localhost"
+_altern_ex = None
+_passive = False
_durable = False
_clusterDurable = False
+_if_empty = True
+_if_unused = True
_fileCount = 8
_fileSize = 24
_maxQueueSize = None
@@ -58,7 +62,7 @@ def Usage ():
print " qpid-config [OPTIONS] add exchange <type> <name> [AddExchangeOptions]"
print " qpid-config [OPTIONS] del exchange <name>"
print " qpid-config [OPTIONS] add queue <name> [AddQueueOptions]"
- print " qpid-config [OPTIONS] del queue <name>"
+ print " qpid-config [OPTIONS] del queue <name> [DelQueueOptions]"
print " qpid-config [OPTIONS] bind <exchange-name> <queue-name> [binding-key]"
print " qpid-config [OPTIONS] unbind <exchange-name> <queue-name> [binding-key]"
print
@@ -69,6 +73,13 @@ def Usage ():
print " ex: localhost, 10.1.1.7:10000, broker-host:10000, guest/guest@localhost"
print
print "Add Queue Options:"
+ print " --altern-ex [name of the alternate exchange]"
+ print " The alternate-exchange field specifies how messages on this queue should"
+ print " be treated when they are rejected by a subscriber, or when they are"
+ print " orphaned by queue deletion. When present, rejected or orphaned messages"
+ print " MUST be routed to the alternate-exchange. In all cases the messages MUST"
+ print " be removed from the queue."
+ print " --passive Do not actually change the broker state (queue will not be created)"
print " --durable Queue is durable"
print " --cluster-durable Queue becomes durable if there is only one functioning cluster node"
print " --file-count N (8) Number of files in queue's persistence journal"
@@ -92,7 +103,20 @@ def Usage ():
print " registered listeners (e.g. for replication). If set to 2, events will be"
print " generated for enqueues and dequeues"
print
+ print "Del Queue Options:"
+ print " --force Force delete of queue even if it's currently used or it's not empty"
+ print " --force-if-not-empty Force delete of queue even if it's not empty"
+ print " --force-if-used Force delete of queue even if it's currently used"
+ print
print "Add Exchange Options:"
+ print " --altern-ex [name of the alternate exchange]"
+ print " In the event that a message cannot be routed, this is the name of the exchange to"
+ print " which the message will be sent. Messages transferred using message.transfer will"
+ print " be routed to the alternate-exchange only if they are sent with the \"none\""
+ print " accept-mode, and the discard-unroutable delivery property is set to false, and"
+ print " there is no queue to route to for the given message according to the bindings"
+ print " on this exchange."
+ print " --passive Do not actually change teh broker state (exchange will not be created)"
print " --durable Exchange is durable"
print " --sequence Exchange will insert a 'qpid.msg_sequence' field in the message header"
print " with a value that increments for each message forwarded."
@@ -211,7 +235,7 @@ class BrokerManager:
if POLICY_TYPE in args: print "--limit-policy=%s" % args[POLICY_TYPE].replace("_", "-"),
if LVQ in args and args[LVQ] == 1: print "--order lvq",
if LVQNB in args and args[LVQNB] == 1: print "--order lvq-no-browse",
- if QUEUE_EVENT_GENERATION in args: print "--generate-queue-events=%d" % args[GENERATE_QUEUE_EVENTS],
+ if QUEUE_EVENT_GENERATION in args: print "--generate-queue-events=%d" % args[QUEUE_EVENT_GENERATION],
print
def QueueListRecurse (self, filter):
@@ -241,7 +265,10 @@ class BrokerManager:
declArgs[MSG_SEQUENCE] = 1
if _ive:
declArgs[IVE] = 1
- self.broker.getAmqpSession().exchange_declare (exchange=ename, type=etype, durable=_durable, arguments=declArgs)
+ if _altern_ex != None:
+ self.broker.getAmqpSession().exchange_declare (exchange=ename, type=etype, alternate_exchange=_altern_ex, passive=_passive, durable=_durable, arguments=declArgs)
+ else:
+ self.broker.getAmqpSession().exchange_declare (exchange=ename, type=etype, passive=_passive, durable=_durable, arguments=declArgs)
def DelExchange (self, args):
if len (args) < 1:
@@ -286,13 +313,16 @@ class BrokerManager:
if _eventGeneration:
declArgs[QUEUE_EVENT_GENERATION] = _eventGeneration
- self.broker.getAmqpSession().queue_declare (queue=qname, durable=_durable, arguments=declArgs)
+ if _altern_ex != None:
+ self.broker.getAmqpSession().queue_declare (queue=qname, alternate_exchange=_altern_ex, passive=_passive, durable=_durable, arguments=declArgs)
+ else:
+ self.broker.getAmqpSession().queue_declare (queue=qname, passive=_passive, durable=_durable, arguments=declArgs)
def DelQueue (self, args):
if len (args) < 1:
Usage ()
qname = args[0]
- self.broker.getAmqpSession().queue_delete (queue=qname)
+ self.broker.getAmqpSession().queue_delete (queue=qname, if_empty=_if_empty, if_unused=_if_unused)
def Bind (self, args):
if len (args) < 2:
@@ -340,7 +370,8 @@ def YN (bool):
try:
longOpts = ("durable", "cluster-durable", "bindings", "broker-addr=", "file-count=",
"file-size=", "max-queue-size=", "max-queue-count=", "limit-policy=",
- "order=", "sequence", "ive", "generate-queue-events=")
+ "order=", "sequence", "ive", "generate-queue-events=", "force", "force-if-not-empty",
+ "force_if_used", "altern_ex=", "passive")
(optlist, encArgs) = getopt.gnu_getopt (sys.argv[1:], "a:b", longOpts)
except:
Usage ()
@@ -356,6 +387,10 @@ for opt in optlist:
_recursive = True
if opt[0] == "-a" or opt[0] == "--broker-addr":
_host = opt[1]
+ if opt[0] == "--altern-ex":
+ _altern_ex = opt[1]
+ if opt[0] == "--passive":
+ _passive = True
if opt[0] == "--durable":
_durable = True
if opt[0] == "--cluster-durable":
@@ -384,6 +419,14 @@ for opt in optlist:
_ive = True
if opt[0] == "--generate-queue-events":
_eventGeneration = int (opt[1])
+ if opt[0] == "--force":
+ _if_empty = False
+ _if_unused = False
+ if opt[0] == "--force-if-not-empty":
+ _if_empty = False
+ if opt[0] == "--force-if-used":
+ _if_unused = False
+
nargs = len (cargs)
bm = BrokerManager ()
diff --git a/qpid/python/commands/qpid-stat b/qpid/python/commands/qpid-stat
new file mode 100755
index 0000000000..1f1d247bb1
--- /dev/null
+++ b/qpid/python/commands/qpid-stat
@@ -0,0 +1,449 @@
+#!/usr/bin/env python
+
+#
+# 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 os
+import getopt
+import sys
+import locale
+import socket
+import re
+from qmf.console import Session, Console
+from qpid.disp import Display, Header, Sorter
+
+_host = "localhost"
+_top = False
+_types = ""
+_limit = 50
+_increasing = False
+_sortcol = None
+pattern = re.compile("^\\d+\\.\\d+\\.\\d+\\.\\d+:\\d+$")
+
+def Usage ():
+ print "Usage: qpid-stat [OPTIONS] [broker-addr]"
+ print
+ print " broker-addr is in the form: [username/password@] hostname | ip-address [:<port>]"
+ print " ex: localhost, 10.1.1.7:10000, broker-host:10000, guest/guest@localhost"
+ print
+# print "General Options:"
+# print " -n [--numeric] Don't resolve names"
+# print " -t [--top] Repeatedly display top items"
+# print
+ print "Display Options:"
+ print
+ print " -b Show Brokers"
+ print " -c Show Connections"
+# print " -s Show Sessions"
+ print " -e Show Exchanges"
+ print " -q Show Queues"
+ print
+ print " -S [--sort-by] COLNAME Sort by column name"
+ print " -I [--increasing] Sort by increasing value (default = decreasing)"
+ print " -L [--limit] NUM Limit output to NUM rows (default = 50)"
+ print
+ sys.exit (1)
+
+class IpAddr:
+ def __init__(self, text):
+ if text.find("@") != -1:
+ tokens = text.split("@")
+ text = tokens[1]
+ if text.find(":") != -1:
+ tokens = text.split(":")
+ text = tokens[0]
+ self.port = int(tokens[1])
+ else:
+ self.port = 5672
+ self.dottedQuad = socket.gethostbyname(text)
+ nums = self.dottedQuad.split(".")
+ self.addr = (int(nums[0]) << 24) + (int(nums[1]) << 16) + (int(nums[2]) << 8) + int(nums[3])
+
+ def bestAddr(self, addrPortList):
+ bestDiff = 0xFFFFFFFFL
+ bestAddr = None
+ for addrPort in addrPortList:
+ diff = IpAddr(addrPort[0]).addr ^ self.addr
+ if diff < bestDiff:
+ bestDiff = diff
+ bestAddr = addrPort
+ return bestAddr
+
+class Broker(object):
+ def __init__(self, qmf, broker):
+ self.broker = broker
+ bobj = qmf.getObjects(_class="broker", _package="org.apache.qpid.broker", _broker=broker)[0]
+ self.currentTime = bobj.getTimestamps()[0]
+ try:
+ self.uptime = bobj.uptime
+ except:
+ self.uptime = 0
+ self.connections = {}
+ self.sessions = {}
+ self.exchanges = {}
+ self.queues = {}
+ package = "org.apache.qpid.broker"
+
+ list = qmf.getObjects(_class="connection", _package=package, _broker=broker)
+ for conn in list:
+ if pattern.match(conn.address):
+ self.connections[conn.getObjectId()] = conn
+
+ list = qmf.getObjects(_class="session", _package=package, _broker=broker)
+ for sess in list:
+ if sess.connectionRef in self.connections:
+ self.sessions[sess.getObjectId()] = sess
+
+ list = qmf.getObjects(_class="exchange", _package=package, _broker=broker)
+ for exchange in list:
+ self.exchanges[exchange.getObjectId()] = exchange
+
+ list = qmf.getObjects(_class="queue", _package=package, _broker=broker)
+ for queue in list:
+ self.queues[queue.getObjectId()] = queue
+
+ def getName(self):
+ return self.broker.getUrl()
+
+ def getCurrentTime(self):
+ return self.currentTime
+
+ def getUptime(self):
+ return self.uptime
+
+class BrokerManager(Console):
+ def __init__(self):
+ self.brokerName = None
+ self.qmf = None
+ self.broker = None
+ self.brokers = []
+ self.cluster = None
+
+ def SetBroker(self, brokerUrl):
+ self.url = brokerUrl
+ self.qmf = Session()
+ self.broker = self.qmf.addBroker(brokerUrl)
+ agents = self.qmf.getAgents()
+ for a in agents:
+ if a.getAgentBank() == 0:
+ self.brokerAgent = a
+
+ def Disconnect(self):
+ if self.broker:
+ self.qmf.delBroker(self.broker)
+
+ def _getCluster(self):
+ packages = self.qmf.getPackages()
+ if "org.apache.qpid.cluster" not in packages:
+ return None
+
+ clusters = self.qmf.getObjects(_class="cluster", _agent=self.brokerAgent)
+ if len(clusters) == 0:
+ print "Clustering is installed but not enabled on the broker."
+ return None
+
+ self.cluster = clusters[0]
+
+ def _getHostList(self, urlList):
+ hosts = []
+ hostAddr = IpAddr(_host)
+ for url in urlList:
+ if url.find("amqp:") != 0:
+ raise Exception("Invalid URL 1")
+ url = url[5:]
+ addrs = str(url).split(",")
+ addrList = []
+ for addr in addrs:
+ tokens = addr.split(":")
+ if len(tokens) != 3:
+ raise Exception("Invalid URL 2")
+ addrList.append((tokens[1], tokens[2]))
+
+ # Find the address in the list that is most likely to be in the same subnet as the address
+ # with which we made the original QMF connection. This increases the probability that we will
+ # be able to reach the cluster member.
+
+ best = hostAddr.bestAddr(addrList)
+ bestUrl = best[0] + ":" + best[1]
+ hosts.append(bestUrl)
+ return hosts
+
+ def displaySubs(self, subs, indent, broker=None, conn=None, sess=None, exchange=None, queue=None):
+ if len(subs) == 0:
+ return
+ this = subs[0]
+ remaining = subs[1:]
+ newindent = indent + " "
+ if this == 'b':
+ pass
+ elif this == 'c':
+ if broker:
+ for oid in broker.connections:
+ iconn = broker.connections[oid]
+ self.printConnSub(indent, broker.getName(), iconn)
+ self.displaySubs(remaining, newindent, broker=broker, conn=iconn,
+ sess=sess, exchange=exchange, queue=queue)
+ elif this == 's':
+ pass
+ elif this == 'e':
+ pass
+ elif this == 'q':
+ pass
+ print
+
+ def displayBroker(self, subs):
+ disp = Display(prefix=" ")
+ heads = []
+ heads.append(Header('broker'))
+ heads.append(Header('cluster'))
+ heads.append(Header('uptime', Header.DURATION))
+ heads.append(Header('conn', Header.KMG))
+ heads.append(Header('sess', Header.KMG))
+ heads.append(Header('exch', Header.KMG))
+ heads.append(Header('queue', Header.KMG))
+ rows = []
+ for broker in self.brokers:
+ if self.cluster:
+ ctext = "%s(%s)" % (self.cluster.clusterName, self.cluster.status)
+ else:
+ ctext = "<standalone>"
+ row = (broker.getName(), ctext, broker.getUptime(),
+ len(broker.connections), len(broker.sessions),
+ len(broker.exchanges), len(broker.queues))
+ rows.append(row)
+ title = "Brokers"
+ if _sortcol:
+ sorter = Sorter(heads, rows, _sortcol, _limit, _increasing)
+ dispRows = sorter.getSorted()
+ else:
+ dispRows = rows
+ disp.formattedTable(title, heads, dispRows)
+
+ def displayConn(self, subs):
+ disp = Display(prefix=" ")
+ heads = []
+ if self.cluster:
+ heads.append(Header('broker'))
+ heads.append(Header('client-addr'))
+ heads.append(Header('cproc'))
+ heads.append(Header('cpid'))
+ heads.append(Header('auth'))
+ heads.append(Header('connected', Header.DURATION))
+ heads.append(Header('idle', Header.DURATION))
+ heads.append(Header('msgIn', Header.KMG))
+ heads.append(Header('msgOut', Header.KMG))
+ rows = []
+ for broker in self.brokers:
+ for oid in broker.connections:
+ conn = broker.connections[oid]
+ row = []
+ if self.cluster:
+ row.append(broker.getName())
+ row.append(conn.address)
+ row.append(conn.remoteProcessName)
+ row.append(conn.remotePid)
+ row.append(conn.authIdentity)
+ row.append(broker.getCurrentTime() - conn.getTimestamps()[1])
+ idle = broker.getCurrentTime() - conn.getTimestamps()[0]
+ row.append(broker.getCurrentTime() - conn.getTimestamps()[0])
+ row.append(conn.framesFromClient)
+ row.append(conn.framesToClient)
+ rows.append(row)
+ title = "Connections"
+ if self.cluster:
+ title += " for cluster '%s'" % self.cluster.clusterName
+ if _sortcol:
+ sorter = Sorter(heads, rows, _sortcol, _limit, _increasing)
+ dispRows = sorter.getSorted()
+ else:
+ dispRows = rows
+ disp.formattedTable(title, heads, dispRows)
+
+ def displaySession(self, subs):
+ disp = Display(prefix=" ")
+
+ def displayExchange(self, subs):
+ disp = Display(prefix=" ")
+ heads = []
+ if self.cluster:
+ heads.append(Header('broker'))
+ heads.append(Header("exchange"))
+ heads.append(Header("type"))
+ heads.append(Header("dur", Header.Y))
+ heads.append(Header("bind", Header.KMG))
+ heads.append(Header("msgIn", Header.KMG))
+ heads.append(Header("msgOut", Header.KMG))
+ heads.append(Header("msgDrop", Header.KMG))
+ heads.append(Header("byteIn", Header.KMG))
+ heads.append(Header("byteOut", Header.KMG))
+ heads.append(Header("byteDrop", Header.KMG))
+ rows = []
+ for broker in self.brokers:
+ for oid in broker.exchanges:
+ ex = broker.exchanges[oid]
+ row = []
+ if self.cluster:
+ row.append(broker.getName())
+ row.append(ex.name)
+ row.append(ex.type)
+ row.append(ex.durable)
+ row.append(ex.bindingCount)
+ row.append(ex.msgReceives)
+ row.append(ex.msgRoutes)
+ row.append(ex.msgDrops)
+ row.append(ex.byteReceives)
+ row.append(ex.byteRoutes)
+ row.append(ex.byteDrops)
+ rows.append(row)
+ title = "Exchanges"
+ if self.cluster:
+ title += " for cluster '%s'" % self.cluster.clusterName
+ if _sortcol:
+ sorter = Sorter(heads, rows, _sortcol, _limit, _increasing)
+ dispRows = sorter.getSorted()
+ else:
+ dispRows = rows
+ disp.formattedTable(title, heads, dispRows)
+
+ def displayQueue(self, subs):
+ disp = Display(prefix=" ")
+ heads = []
+ if self.cluster:
+ heads.append(Header('broker'))
+ heads.append(Header("queue"))
+ heads.append(Header("dur", Header.Y))
+ heads.append(Header("autoDel", Header.Y))
+ heads.append(Header("excl", Header.Y))
+ heads.append(Header("msg", Header.KMG))
+ heads.append(Header("msgIn", Header.KMG))
+ heads.append(Header("msgOut", Header.KMG))
+ heads.append(Header("bytes", Header.KMG))
+ heads.append(Header("bytesIn", Header.KMG))
+ heads.append(Header("bytesOut", Header.KMG))
+ heads.append(Header("cons", Header.KMG))
+ heads.append(Header("bind", Header.KMG))
+ rows = []
+ for broker in self.brokers:
+ for oid in broker.queues:
+ q = broker.queues[oid]
+ row = []
+ if self.cluster:
+ row.append(broker.getName())
+ row.append(q.name)
+ row.append(q.durable)
+ row.append(q.autoDelete)
+ row.append(q.exclusive)
+ row.append(q.msgDepth)
+ row.append(q.msgTotalEnqueues)
+ row.append(q.msgTotalDequeues)
+ row.append(q.byteDepth)
+ row.append(q.byteTotalEnqueues)
+ row.append(q.byteTotalDequeues)
+ row.append(q.consumerCount)
+ row.append(q.bindingCount)
+ rows.append(row)
+ title = "Queues"
+ if self.cluster:
+ title += " for cluster '%s'" % self.cluster.clusterName
+ if _sortcol:
+ sorter = Sorter(heads, rows, _sortcol, _limit, _increasing)
+ dispRows = sorter.getSorted()
+ else:
+ dispRows = rows
+ disp.formattedTable(title, heads, dispRows)
+
+ def displayMain(self, main, subs):
+ if main == 'b': self.displayBroker(subs)
+ elif main == 'c': self.displayConn(subs)
+ elif main == 's': self.displaySession(subs)
+ elif main == 'e': self.displayExchange(subs)
+ elif main == 'q': self.displayQueue(subs)
+
+ def display(self):
+ self._getCluster()
+ if self.cluster:
+ memberList = self.cluster.members.split(";")
+ hostList = self._getHostList(memberList)
+ self.qmf.delBroker(self.broker)
+ self.broker = None
+ for host in hostList:
+ b = self.qmf.addBroker(host)
+ self.brokers.append(Broker(self.qmf, b))
+ else:
+ self.brokers.append(Broker(self.qmf, self.broker))
+
+ self.displayMain(_types[0], _types[1:])
+
+
+##
+## Main Program
+##
+
+try:
+ longOpts = ("top", "numeric", "sort-by=", "limit=", "increasing")
+ (optlist, encArgs) = getopt.gnu_getopt(sys.argv[1:], "bceqS:L:I", longOpts)
+except:
+ Usage()
+
+try:
+ encoding = locale.getpreferredencoding()
+ cargs = [a.decode(encoding) for a in encArgs]
+except:
+ cargs = encArgs
+
+for opt in optlist:
+ if opt[0] == "-t" or opt[0] == "--top":
+ _top = True
+ elif opt[0] == "-n" or opt[0] == "--numeric":
+ _numeric = True
+ elif opt[0] == "-S" or opt[0] == "--sort-by":
+ _sortcol = opt[1]
+ elif opt[0] == "-I" or opt[0] == "--increasing":
+ _increasing = True
+ elif opt[0] == "-L" or opt[0] == "--limit":
+ _limit = int(opt[1])
+ elif len(opt[0]) == 2:
+ char = opt[0][1]
+ if "bcseq".find(char) != -1:
+ _types += char
+ else:
+ Usage()
+ else:
+ Usage()
+
+if len(_types) == 0:
+ Usage()
+
+nargs = len(cargs)
+bm = BrokerManager()
+
+if nargs == 1:
+ _host = cargs[0]
+
+try:
+ bm.SetBroker(_host)
+ bm.display()
+except KeyboardInterrupt:
+ print
+except Exception,e:
+ print "Failed:", e.args
+ #raise # TODO: Remove before flight
+ sys.exit(1)
+
+bm.Disconnect()
diff --git a/qpid/python/examples/datatypes/client.py b/qpid/python/examples/datatypes/client.py
new file mode 100755
index 0000000000..088e529909
--- /dev/null
+++ b/qpid/python/examples/datatypes/client.py
@@ -0,0 +1,122 @@
+#!/usr/bin/env python
+#
+# 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.
+#
+"""
+ client.py
+
+ Client for testing use of Unicode and datatypes.
+
+ Both client and server will be written in C++ and Python.
+ Tests can run clients and servers written in different
+ languages, and they can be run on 32-bit and 64-bit architectures.
+
+"""
+
+import qpid
+import sys
+import os
+from qpid.util import connect
+from qpid.connection import Connection
+from qpid.datatypes import Message, RangedSet, uuid4
+from qpid.queue import Empty
+
+import testdata
+
+#----- Initialization --------------------------------------
+
+
+# Set parameters for login
+
+host="127.0.0.1"
+port=5672
+user="guest"
+password="guest"
+
+# If an alternate host or port has been specified, use that instead
+# (this is used in our unit tests)
+if len(sys.argv) > 1 :
+ host=sys.argv[1]
+if len(sys.argv) > 2 :
+ port=int(sys.argv[2])
+
+# Create a connection.
+socket = connect(host, port)
+connection = Connection (sock=socket, username=user, password=password)
+connection.start()
+session = connection.session(str(uuid4()))
+
+
+#----- Main Body -- ----------------------------------------
+
+# Create a response queue for the server to send responses to. Use the
+# same string as the name of the queue and the name of the routing
+# key.
+
+reply_to = "reply_to:" + session.name
+session.queue_declare(queue=reply_to, exclusive=True)
+session.exchange_bind(exchange="amq.direct", queue=reply_to, binding_key=reply_to)
+
+# Create a local queue and subscribe it to the response queue
+
+local_queue_name = "local_queue"
+queue = session.incoming(local_queue_name)
+
+# Call message_subscribe() to tell the broker to deliver messages from
+# the server's reply_to queue to our local client queue. The server
+# will start delivering messages as soon as message credit is
+# available.
+
+session.message_subscribe(queue=reply_to, destination=local_queue_name)
+queue.start()
+
+# Set up the properties. Perhaps a few application headers?
+
+delivery_properties = session.delivery_properties(routing_key="request")
+
+message_properties = session.message_properties()
+
+message_properties.content_encoding="text/plain; charset='utf-8'"
+
+testdata.set_application_headers(message_properties)
+message_properties.reply_to = session.reply_to("amq.direct", reply_to)
+
+# deliver the message - remember to encode the Unicode string!
+request = Message(message_properties, delivery_properties, testdata.String_Greek.encode("utf8"))
+session.message_transfer(destination="amq.direct", message=request)
+
+# Now see what messages the server sent to our reply_to queue
+
+try:
+ response = queue.get(timeout=10)
+ content = response.body
+ session.message_accept(RangedSet(response.id))
+ testdata.check_message(response)
+ print "Response: " + content
+except Empty:
+ print "No more messages!"
+ exit(1)
+except:
+ print "Unexpected exception!"
+ exit(1)
+
+#----- Cleanup ------------------------------------------------
+
+# Clean up before exiting so there are no open threads.
+
+session.close(timeout=10)
diff --git a/qpid/python/examples/datatypes/server.py b/qpid/python/examples/datatypes/server.py
new file mode 100755
index 0000000000..18e6fa4ad7
--- /dev/null
+++ b/qpid/python/examples/datatypes/server.py
@@ -0,0 +1,124 @@
+#!/usr/bin/env python
+#
+# 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.
+#
+"""
+ server.py
+
+ Server for testing use of Unicode and datatypes.
+
+ Both client and server will be written in C++ and Python.
+ Tests can run clients and servers written in different
+ languages, and they can be run on 32-bit and 64-bit architectures.
+"""
+
+import testdata
+
+import qpid
+import sys
+import os
+from qpid.util import connect
+from qpid.connection import Connection
+from qpid.datatypes import Message, RangedSet, uuid4
+from qpid.queue import Empty
+
+#----- Functions -------------------------------------------
+def respond(session, request):
+
+ # The routing key for the response is the request's reply-to
+ # property. The body for the response is the request's body,
+ # converted to upper case.
+
+ testdata.check_message(request)
+
+ message_properties = request.get("message_properties")
+ reply_to = message_properties.reply_to
+
+ testdata.set_application_headers(message_properties)
+
+ if reply_to == None:
+ raise Exception("This message is missing the 'reply_to' property, which is required")
+
+ delivery_properties = session.delivery_properties(routing_key=reply_to["routing_key"])
+ response = Message(delivery_properties, message_properties, testdata.String_Greek.encode("utf8"))
+ print "Sending response ..."
+ session.message_transfer(destination=reply_to["exchange"], message=response)
+
+#----- Initialization --------------------------------------
+
+
+# Set parameters for login
+
+host="127.0.0.1"
+port=5672
+user="guest"
+password="guest"
+
+# If an alternate host or port has been specified, use that instead
+# (this is used in our unit tests)
+if len(sys.argv) > 1 :
+ host=sys.argv[1]
+if len(sys.argv) > 2 :
+ port=int(sys.argv[2])
+
+socket = connect(host, port)
+connection = Connection (sock=socket, username=user, password=password)
+connection.start()
+session = connection.session(str(uuid4()))
+
+#----- Main Body -- ----------------------------------------
+
+# Create a request queue and subscribe to it
+
+session.queue_declare(queue="request", exclusive=True)
+session.exchange_bind(exchange="amq.direct", queue="request", binding_key="request")
+
+local_queue_name = "local_queue"
+
+session.message_subscribe(queue="request", destination=local_queue_name)
+
+queue = session.incoming(local_queue_name)
+queue.start()
+
+# Remind the user to start the client program
+
+print "Request server running - run your client now."
+print "(Times out after 100 seconds ...)"
+sys.stdout.flush()
+
+# Respond to each request
+
+# If we get a message, send it back to the user (as indicated in the
+# ReplyTo property)
+
+while True:
+ try:
+ request = queue.get(timeout=100)
+ session.message_accept(RangedSet(request.id))
+
+ respond(session, request)
+ except Empty:
+ print "No more messages!"
+ break;
+
+
+#----- Cleanup ------------------------------------------------
+
+# Clean up before exiting so there are no open threads.
+
+session.close(timeout=10)
diff --git a/qpid/python/examples/datatypes/testdata.py b/qpid/python/examples/datatypes/testdata.py
new file mode 100644
index 0000000000..cdf140d400
--- /dev/null
+++ b/qpid/python/examples/datatypes/testdata.py
@@ -0,0 +1,180 @@
+# -*- encoding: utf-8 -*-
+
+from qpid.datatypes import uuid4, timestamp
+
+#----- Some variables to test boundary conditions on various data types
+
+void = None
+boolean_true = True
+boolean_false = False
+Uint8_0 = 0
+Uint8_max = 255
+Uint16_0 = 0
+Uint16_max = 65535
+Uint32_0 = 0
+Uint32_max = 4294967295
+Uint64_0 = 0
+Uint64_max = 18446744073709551615
+Int8_min = -128
+Int8_0 = 0
+Int8_max = 127
+Int16_min = -32768
+Int16_0 = 0
+Int16_max = 32767
+Int32_min = -2147483648
+Int32_0 = 0
+Int32_max = 2147483647
+Int64_min = -9223372036854775808
+Int64_0 = 0
+Int64_max = 9223372036854775807
+
+Float_pi = 3.14159265
+Float_neg = -1E4
+Float_big = 1267.43233E12
+Float_small = 12.78e-12
+Float_neg0 = -0
+Float_pos0 = 0
+Float_INF = float('inf')
+Float_Negative_INF = float('-inf')
+
+Double_pi = 3.1415926535897932384626433832795
+Double_neg = -1E4
+Double_big = 1267.43233E12
+Double_small = 12.78e-2
+Double_neg0 = -0
+Double_pos0 = 0
+Double_INF = float('inf')
+Double_Negative_INF = float('-inf')
+
+char_1byte = u'0024' # $
+char_2byte = u'00A2' # ¢
+char_3byte = u'20AC' # €
+char_4byte = u'10ABCD'
+
+timestamp = timestamp()
+
+UUID = uuid4()
+
+String_Greek = u"ἐξίσταντο δὲ πάντες καὶ διηπόρουν, ἄλλος πρὸς ἄλλον λέγοντες, Τί θέλει τοῦτο εἶναι;"
+
+String_Empty = ""
+
+#----- A few functions ----------------------------------------------------------
+
+def near_enough(float1, float2, delta):
+ return abs(float1-float2) < delta
+
+def set_application_headers(message_properties):
+
+ message_properties.application_headers = {}
+ message_properties.application_headers["void"] = None
+ message_properties.application_headers["boolean_true"] = boolean_true
+ message_properties.application_headers["boolean_false"] = boolean_false
+ message_properties.application_headers["Uint8_0"] = Uint8_0
+ message_properties.application_headers["Uint8_max"] = Uint8_max
+ message_properties.application_headers["Uint16_0"] = Uint16_0
+ message_properties.application_headers["Uint16_max"] = Uint16_max
+ message_properties.application_headers["Uint32_0"] = Uint32_0
+ message_properties.application_headers["Uint32_max"] = Uint32_max
+ message_properties.application_headers["Uint64_0"] = Uint64_0
+# message_properties.application_headers["Uint64_max"] = Uint64_max
+ message_properties.application_headers["Int8_min"] = Int8_min
+ message_properties.application_headers["Int8_0"] = Int8_0
+ message_properties.application_headers["Int8_max"] = Int8_max
+ message_properties.application_headers["Int16_min"] = Int16_min
+ message_properties.application_headers["Int16_0"] = Int16_0
+ message_properties.application_headers["Int16_max"] = Int16_max
+ message_properties.application_headers["Int32_min"] = Int32_min
+ message_properties.application_headers["Int32_0"] = Int32_0
+ message_properties.application_headers["Int32_max"] = Int32_max
+ message_properties.application_headers["Int64_min"] = Int64_min
+ message_properties.application_headers["Int64_0"] = Int64_0
+ message_properties.application_headers["Int64_max"] = Int64_max
+
+ message_properties.application_headers["Float_pi"] = Float_pi
+ message_properties.application_headers["Float_neg"] = Float_neg
+ message_properties.application_headers["Float_big"] = Float_big
+ message_properties.application_headers["Float_small"] = Float_small
+ message_properties.application_headers["Float_neg0"] = Float_neg0
+ message_properties.application_headers["Float_pos0"] = Float_pos0
+ message_properties.application_headers["Float_INF"] = Float_INF
+ message_properties.application_headers["Float_Negative_INF"] = Float_Negative_INF
+
+ message_properties.application_headers["Double_pi"] = Double_pi
+ message_properties.application_headers["Double_neg"] = Double_neg
+ message_properties.application_headers["Double_big"] = Double_big
+ message_properties.application_headers["Double_small"] = Double_small
+ message_properties.application_headers["Double_neg0"] = Double_neg0
+ message_properties.application_headers["Double_pos0"] = Double_pos0
+ message_properties.application_headers["Double_INF"] = Double_INF
+ message_properties.application_headers["Double_Negative_INF"] = Double_Negative_INF
+
+ message_properties.application_headers["char_1byte"] = char_1byte
+ message_properties.application_headers["char_2byte"] = char_2byte
+ message_properties.application_headers["char_3byte"] = char_3byte
+ message_properties.application_headers["char_4byte"] = char_4byte
+
+ message_properties.application_headers["timestamp"] = timestamp
+ message_properties.application_headers["UUID"] = uuid4()
+ message_properties.application_headers["String_Greek"] = String_Greek
+ message_properties.application_headers["String_Empty"] = String_Empty
+
+def check_message(message):
+
+# message_properties = message.message_properties()
+ message_properties = message.get("message_properties")
+ assert message_properties.application_headers["void"] == None
+ assert message_properties.application_headers["boolean_true"] == boolean_true
+ assert message_properties.application_headers["boolean_false"] == boolean_false
+ assert message_properties.application_headers["Uint8_0"] == Uint8_0
+ assert message_properties.application_headers["Uint8_max"] == Uint8_max
+ assert message_properties.application_headers["Uint16_0"] == Uint16_0
+ assert message_properties.application_headers["Uint16_max"] == Uint16_max
+ assert message_properties.application_headers["Uint32_0"] == Uint32_0
+ assert message_properties.application_headers["Uint32_max"] == Uint32_max
+ assert message_properties.application_headers["Uint64_0"] == Uint64_0
+# assert message_properties.application_headers["Uint64_max"] == Uint64_max
+ assert message_properties.application_headers["Int8_min"] == Int8_min
+ assert message_properties.application_headers["Int8_0"] == Int8_0
+ assert message_properties.application_headers["Int8_max"] == Int8_max
+ assert message_properties.application_headers["Int16_min"] == Int16_min
+ assert message_properties.application_headers["Int16_0"] == Int16_0
+ assert message_properties.application_headers["Int16_max"] == Int16_max
+ assert message_properties.application_headers["Int32_min"] == Int32_min
+ assert message_properties.application_headers["Int32_0"] == Int32_0
+ assert message_properties.application_headers["Int32_max"] == Int32_max
+ assert message_properties.application_headers["Int64_min"] == Int64_min
+ assert message_properties.application_headers["Int64_0"] == Int64_0
+ assert message_properties.application_headers["Int64_max"] == Int64_max
+
+# Change floating point comparisons to allow inexactness
+
+ assert near_enough(message_properties.application_headers["Float_pi"], Float_pi, 0.00001)
+ assert near_enough(message_properties.application_headers["Float_neg"], Float_neg, 0.00001)
+ assert near_enough(message_properties.application_headers["Float_big"], Float_big, Float_big/1000000)
+ assert near_enough(message_properties.application_headers["Float_small"], Float_small, 0.00001)
+ assert message_properties.application_headers["Float_neg0"] == Float_neg0
+ assert message_properties.application_headers["Float_pos0"] == Float_pos0
+ assert message_properties.application_headers["Float_INF"] == Float_INF
+ assert message_properties.application_headers["Float_Negative_INF"] == Float_Negative_INF
+
+ assert near_enough(message_properties.application_headers["Double_pi"], Double_pi, 0.00001)
+ assert near_enough(message_properties.application_headers["Double_neg"], Double_neg, 0.00001)
+ assert near_enough(message_properties.application_headers["Double_big"], Double_big, Double_big/1000000)
+ assert near_enough(message_properties.application_headers["Double_small"], Double_small, 0.00001)
+ assert message_properties.application_headers["Double_neg0"] == Double_neg0
+ assert message_properties.application_headers["Double_pos0"] == Double_pos0
+ assert message_properties.application_headers["Double_INF"] == Double_INF
+ assert message_properties.application_headers["Double_Negative_INF"] == Double_Negative_INF
+
+ assert message_properties.application_headers["char_1byte"] == char_1byte
+ assert message_properties.application_headers["char_2byte"] == char_2byte
+ assert message_properties.application_headers["char_3byte"] == char_3byte
+ assert message_properties.application_headers["char_4byte"] == char_4byte
+
+# assert message_properties.application_headers["timestamp"] == timestamp
+# assert message_properties.application_headers["UUID"] == UUID
+ assert message_properties.application_headers["String_Greek"] == String_Greek
+ assert message_properties.application_headers["String_Empty"] == String_Empty
+
+
diff --git a/qpid/python/perftest b/qpid/python/perftest
index f4d3c95e96..f867566fd0 100755
--- a/qpid/python/perftest
+++ b/qpid/python/perftest
@@ -44,8 +44,8 @@ def publisher(n):
consumer = "consumer"
queue = client.queue(consumer)
channel.message_subscribe(queue="sync_queue", destination=consumer)
- channel.message_flow(consumer, 0, 0xFFFFFFFF)
- channel.message_flow(consumer, 1, 0xFFFFFFFF)
+ channel.message_flow(consumer, 0, 0xFFFFFFFFL)
+ channel.message_flow(consumer, 1, 0xFFFFFFFFL)
queue.get(block = True)
print "done"
channel.session_close()
@@ -62,8 +62,8 @@ def consumer():
consumer = "consumer"
queue = client.queue(consumer)
channel.message_subscribe(queue="message_queue", destination=consumer)
- channel.message_flow(consumer, 0, 0xFFFFFFFF)
- channel.message_flow(consumer, 1, 0xFFFFFFFF)
+ channel.message_flow(consumer, 0, 0xFFFFFFFFL)
+ channel.message_flow(consumer, 1, 0xFFFFFFFFL)
final = "That's done"
content = ""
message = None
diff --git a/qpid/python/qmf/console.py b/qpid/python/qmf/console.py
index 867d707f31..3b99595f1f 100644
--- a/qpid/python/qmf/console.py
+++ b/qpid/python/qmf/console.py
@@ -20,6 +20,7 @@
""" Console API for Qpid Management Framework """
import os
+import platform
import qpid
import struct
import socket
@@ -27,7 +28,7 @@ import re
from qpid.peer import Closed
from qpid.session import SessionDetached
from qpid.connection import Connection, ConnectionFailed
-from qpid.datatypes import UUID, uuid4, Message, RangedSet
+from qpid.datatypes import Message, RangedSet
from qpid.util import connect, ssl, URL
from qpid.codec010 import StringCodec as Codec
from threading import Lock, Condition, Thread
@@ -414,7 +415,7 @@ class Session:
self.console.brokerDisconnected(broker)
def _handleBrokerResp(self, broker, codec, seq):
- broker.brokerId = UUID(codec.read_uuid())
+ broker.brokerId = codec.read_uuid()
if self.console != None:
self.console.brokerInfo(broker)
@@ -615,7 +616,7 @@ class Session:
elif typecode == 11: data = codec.read_uint8() != 0 # BOOL
elif typecode == 12: data = codec.read_float() # FLOAT
elif typecode == 13: data = codec.read_double() # DOUBLE
- elif typecode == 14: data = UUID(codec.read_uuid()) # UUID
+ elif typecode == 14: data = codec.read_uuid() # UUID
elif typecode == 15: data = codec.read_map() # FTABLE
elif typecode == 16: data = codec.read_int8() # S8
elif typecode == 17: data = codec.read_int16() # S16
@@ -1230,6 +1231,7 @@ class ManagedConnection(Thread):
class Broker:
""" This object represents a connection (or potential connection) to a QMF broker. """
SYNC_TIME = 60
+ nextSeq = 1
def __init__(self, session, host, port, authMech, authUser, authPass, ssl=False):
self.session = session
@@ -1242,7 +1244,8 @@ class Broker:
self.error = None
self.brokerId = None
self.connected = False
- self.amqpSessionId = "%s.%d" % (os.uname()[1], os.getpid())
+ self.amqpSessionId = "%s.%d.%d" % (platform.uname()[1], os.getpid(), Broker.nextSeq)
+ Broker.nextSeq += 1
if self.session.manageConnections:
self.thread = ManagedConnection(self)
self.thread.start()
@@ -1334,8 +1337,8 @@ class Broker:
acquire_mode=self.amqpSession.acquire_mode.pre_acquired)
self.amqpSession.incoming("rdest").listen(self._replyCb, self._exceptionCb)
self.amqpSession.message_set_flow_mode(destination="rdest", flow_mode=1)
- self.amqpSession.message_flow(destination="rdest", unit=0, value=0xFFFFFFFF)
- self.amqpSession.message_flow(destination="rdest", unit=1, value=0xFFFFFFFF)
+ self.amqpSession.message_flow(destination="rdest", unit=0, value=0xFFFFFFFFL)
+ self.amqpSession.message_flow(destination="rdest", unit=1, value=0xFFFFFFFFL)
self.topicName = "topic-%s" % self.amqpSessionId
self.amqpSession.queue_declare(queue=self.topicName, exclusive=True, auto_delete=True)
@@ -1344,8 +1347,8 @@ class Broker:
acquire_mode=self.amqpSession.acquire_mode.pre_acquired)
self.amqpSession.incoming("tdest").listen(self._replyCb)
self.amqpSession.message_set_flow_mode(destination="tdest", flow_mode=1)
- self.amqpSession.message_flow(destination="tdest", unit=0, value=0xFFFFFFFF)
- self.amqpSession.message_flow(destination="tdest", unit=1, value=0xFFFFFFFF)
+ self.amqpSession.message_flow(destination="tdest", unit=0, value=0xFFFFFFFFL)
+ self.amqpSession.message_flow(destination="tdest", unit=1, value=0xFFFFFFFFL)
self.connected = True
self.session._handleBrokerConnect(self)
diff --git a/qpid/python/qpid/codec010.py b/qpid/python/qpid/codec010.py
index f34025ef17..f07362c38d 100644
--- a/qpid/python/qpid/codec010.py
+++ b/qpid/python/qpid/codec010.py
@@ -19,7 +19,7 @@
import datetime
from packer import Packer
-from datatypes import serial, timestamp, RangedSet, Struct
+from datatypes import serial, timestamp, RangedSet, Struct, UUID
class CodecException(Exception): pass
@@ -118,6 +118,8 @@ class Codec(Packer):
def read_vbin8(self):
return self.read(self.read_uint8())
def write_vbin8(self, b):
+ if isinstance(b, buffer):
+ b = str(b)
self.write_uint8(len(b))
self.write(b)
@@ -131,10 +133,17 @@ class Codec(Packer):
def write_str16(self, s):
self.write_vbin16(s.encode("utf8"))
+ def read_str16_latin(self):
+ return self.read_vbin16().decode("iso-8859-15")
+ def write_str16_latin(self, s):
+ self.write_vbin16(s.encode("iso-8859-15"))
+
def read_vbin16(self):
return self.read(self.read_uint16())
def write_vbin16(self, b):
+ if isinstance(b, buffer):
+ b = str(b)
self.write_uint16(len(b))
self.write(b)
@@ -158,6 +167,8 @@ class Codec(Packer):
def read_vbin32(self):
return self.read(self.read_uint32())
def write_vbin32(self, b):
+ if isinstance(b, buffer):
+ b = str(b)
self.write_uint32(len(b))
self.write(b)
@@ -166,7 +177,7 @@ class Codec(Packer):
if m is not None:
sc.write_uint32(len(m))
for k, v in m.items():
- type = self.spec.encoding(v.__class__)
+ type = self.spec.encoding(v)
if type == None:
raise CodecException("no encoding for %s" % v.__class__)
sc.write_str8(k)
@@ -191,9 +202,9 @@ class Codec(Packer):
sc = StringCodec(self.spec)
if a is not None:
if len(a) > 0:
- type = self.spec.encoding(a[0].__class__)
+ type = self.spec.encoding(a[0])
else:
- type = self.spec.encoding(None.__class__)
+ type = self.spec.encoding(None)
sc.write_uint8(type.code)
sc.write_uint32(len(a))
for o in a:
@@ -216,7 +227,7 @@ class Codec(Packer):
if l is not None:
sc.write_uint32(len(l))
for o in l:
- type = self.spec.encoding(o.__class__)
+ type = self.spec.encoding(o)
sc.write_uint8(type.code)
type.encode(sc, o)
self.write_vbin32(sc.encoded)
@@ -273,9 +284,11 @@ class Codec(Packer):
getattr(self, attr)(n)
def read_uuid(self):
- return self.unpack("16s")
+ return UUID(self.unpack("16s"))
def write_uuid(self, s):
+ if isinstance(s, UUID):
+ s = s.bytes
self.pack("16s", s)
def read_bin128(self):
diff --git a/qpid/python/qpid/datatypes.py b/qpid/python/qpid/datatypes.py
index eb1f86b0b0..b2dcbe74ab 100644
--- a/qpid/python/qpid/datatypes.py
+++ b/qpid/python/qpid/datatypes.py
@@ -125,7 +125,7 @@ def serial(o):
class Serial:
def __init__(self, value):
- self.value = value & 0xFFFFFFFF
+ self.value = value & 0xFFFFFFFFL
def __hash__(self):
return hash(self.value)
@@ -136,8 +136,8 @@ class Serial:
other = serial(other)
- delta = (self.value - other.value) & 0xFFFFFFFF
- neg = delta & 0x80000000
+ delta = (self.value - other.value) & 0xFFFFFFFFL
+ neg = delta & 0x80000000L
mag = delta & 0x7FFFFFFF
if neg:
@@ -289,7 +289,8 @@ class UUID:
def __cmp__(self, other):
if isinstance(other, UUID):
return cmp(self.bytes, other.bytes)
- raise NotImplemented()
+ else:
+ return -1
def __str__(self):
return "%08x-%04x-%04x-%04x-%04x%08x" % struct.unpack("!LHHHHL", self.bytes)
diff --git a/qpid/python/qpid/delegates.py b/qpid/python/qpid/delegates.py
index 7cfd9b11db..a720e2e1c7 100644
--- a/qpid/python/qpid/delegates.py
+++ b/qpid/python/qpid/delegates.py
@@ -21,6 +21,7 @@ import os, connection, session
from util import notify
from datatypes import RangedSet
from logging import getLogger
+import sys
log = getLogger("qpid.io.ctl")
@@ -141,7 +142,10 @@ class Client(Delegate):
PROPERTIES = {"product": "qpid python client",
"version": "development",
- "platform": os.name}
+ "platform": os.name,
+ "qpid.client_process": os.path.basename(sys.argv[0]),
+ "qpid.client_pid": os.getpid(),
+ "qpid.client_ppid": os.getppid()}
def __init__(self, connection, username="guest", password="guest",
mechanism="PLAIN", heartbeat=None):
diff --git a/qpid/python/qpid/disp.py b/qpid/python/qpid/disp.py
index e46cb33c60..1b315c9d98 100644
--- a/qpid/python/qpid/disp.py
+++ b/qpid/python/qpid/disp.py
@@ -21,16 +21,115 @@
from time import strftime, gmtime
+class Header:
+ """ """
+ NONE = 1
+ KMG = 2
+ YN = 3
+ Y = 4
+ TIME_LONG = 5
+ TIME_SHORT = 6
+ DURATION = 7
+
+ def __init__(self, text, format=NONE):
+ self.text = text
+ self.format = format
+
+ def __repr__(self):
+ return self.text
+
+ def __str__(self):
+ return self.text
+
+ def formatted(self, value):
+ try:
+ if value == None:
+ return ''
+ if self.format == Header.NONE:
+ return value
+ if self.format == Header.KMG:
+ return self.num(value)
+ if self.format == Header.YN:
+ if value:
+ return 'Y'
+ return 'N'
+ if self.format == Header.Y:
+ if value:
+ return 'Y'
+ return ''
+ if self.format == Header.TIME_LONG:
+ return strftime("%c", gmtime(value / 1000000000))
+ if self.format == Header.TIME_SHORT:
+ return strftime("%X", gmtime(value / 1000000000))
+ if self.format == Header.DURATION:
+ if value < 0: value = 0
+ sec = value / 1000000000
+ min = sec / 60
+ hour = min / 60
+ day = hour / 24
+ result = ""
+ if day > 0:
+ result = "%dd " % day
+ if hour > 0 or result != "":
+ result += "%dh " % (hour % 24)
+ if min > 0 or result != "":
+ result += "%dm " % (min % 60)
+ result += "%ds" % (sec % 60)
+ return result
+ except:
+ return "?"
+
+ def numCell(self, value, tag):
+ fp = float(value) / 1000.
+ if fp < 10.0:
+ return "%1.2f%c" % (fp, tag)
+ if fp < 100.0:
+ return "%2.1f%c" % (fp, tag)
+ return "%4d%c" % (value / 1000, tag)
+
+ def num(self, value):
+ if value < 1000:
+ return "%4d" % value
+ if value < 1000000:
+ return self.numCell(value, 'k')
+ value /= 1000
+ if value < 1000000:
+ return self.numCell(value, 'm')
+ value /= 1000
+ return self.numCell(value, 'g')
+
+
class Display:
""" Display formatting for QPID Management CLI """
- def __init__ (self):
- self.tableSpacing = 2
- self.tablePrefix = " "
+ def __init__(self, spacing=2, prefix=" "):
+ self.tableSpacing = spacing
+ self.tablePrefix = prefix
self.timestampFormat = "%X"
- def table (self, title, heads, rows):
- """ Print a formatted table with autosized columns """
+ def formattedTable(self, title, heads, rows):
+ fRows = []
+ for row in rows:
+ fRow = []
+ col = 0
+ for cell in row:
+ fRow.append(heads[col].formatted(cell))
+ col += 1
+ fRows.append(fRow)
+ headtext = []
+ for head in heads:
+ headtext.append(head.text)
+ self.table(title, headtext, fRows)
+
+ def table(self, title, heads, rows):
+ """ Print a table with autosized columns """
+
+ # Pad the rows to the number of heads
+ for row in rows:
+ diff = len(heads) - len(row)
+ for idx in range(diff):
+ row.append("")
+
print title
if len (rows) == 0:
return
@@ -77,3 +176,59 @@ class Display:
def timestamp (self, nsec):
""" Format a nanosecond-since-the-epoch timestamp for printing """
return strftime (self.timestampFormat, gmtime (nsec / 1000000000))
+
+ def duration(self, nsec):
+ if nsec < 0: nsec = 0
+ sec = nsec / 1000000000
+ min = sec / 60
+ hour = min / 60
+ day = hour / 24
+ result = ""
+ if day > 0:
+ result = "%dd " % day
+ if hour > 0 or result != "":
+ result += "%dh " % (hour % 24)
+ if min > 0 or result != "":
+ result += "%dm " % (min % 60)
+ result += "%ds" % (sec % 60)
+ return result
+
+class Sortable:
+ """ """
+ def __init__(self, row, sortIndex):
+ self.row = row
+ self.sortIndex = sortIndex
+ if sortIndex >= len(row):
+ raise Exception("sort index exceeds row boundary")
+
+ def __cmp__(self, other):
+ return cmp(self.row[self.sortIndex], other.row[self.sortIndex])
+
+ def getRow(self):
+ return self.row
+
+class Sorter:
+ """ """
+ def __init__(self, heads, rows, sortCol, limit=0, inc=True):
+ col = 0
+ for head in heads:
+ if head.text == sortCol:
+ break
+ col += 1
+ if col == len(heads):
+ raise Exception("sortCol '%s', not found in headers" % sortCol)
+
+ list = []
+ for row in rows:
+ list.append(Sortable(row, col))
+ list.sort(reverse=not inc)
+ count = 0
+ self.sorted = []
+ for row in list:
+ self.sorted.append(row.getRow())
+ count += 1
+ if count == limit:
+ break
+
+ def getSorted(self):
+ return self.sorted
diff --git a/qpid/python/qpid/management.py b/qpid/python/qpid/management.py
index 477f3e8f2b..546e68ae8e 100644
--- a/qpid/python/qpid/management.py
+++ b/qpid/python/qpid/management.py
@@ -177,12 +177,12 @@ class managementChannel:
ssn.incoming ("rdest").listen (self.replyCb)
ssn.message_set_flow_mode (destination="tdest", flow_mode=1)
- ssn.message_flow (destination="tdest", unit=0, value=0xFFFFFFFF)
- ssn.message_flow (destination="tdest", unit=1, value=0xFFFFFFFF)
+ ssn.message_flow (destination="tdest", unit=0, value=0xFFFFFFFFL)
+ ssn.message_flow (destination="tdest", unit=1, value=0xFFFFFFFFL)
ssn.message_set_flow_mode (destination="rdest", flow_mode=1)
- ssn.message_flow (destination="rdest", unit=0, value=0xFFFFFFFF)
- ssn.message_flow (destination="rdest", unit=1, value=0xFFFFFFFF)
+ ssn.message_flow (destination="rdest", unit=0, value=0xFFFFFFFFL)
+ ssn.message_flow (destination="rdest", unit=1, value=0xFFFFFFFFL)
def setBrokerInfo (self, data):
self.brokerInfo = data
diff --git a/qpid/python/qpid/managementdata.py b/qpid/python/qpid/managementdata.py
index 46c746c0f9..e1fd8d54eb 100644
--- a/qpid/python/qpid/managementdata.py
+++ b/qpid/python/qpid/managementdata.py
@@ -29,6 +29,7 @@ import re
import socket
import struct
import os
+import platform
import locale
from qpid.management import managementChannel, managementClient
from threading import Lock
@@ -202,7 +203,7 @@ class ManagementData:
self.lastUnit = None
self.methodSeq = 1
self.methodsPending = {}
- self.sessionId = "%s.%d" % (os.uname()[1], os.getpid())
+ self.sessionId = "%s.%d" % (platform.uname()[1], os.getpid())
self.broker = Broker (host)
self.conn = Connection (connect (self.broker.host, self.broker.port),
@@ -262,7 +263,7 @@ class ManagementData:
else:
return "True"
elif typecode == 14:
- return "%08x-%04x-%04x-%04x-%04x%08x" % struct.unpack ("!LHHHHL", value)
+ return str (value)
elif typecode == 15:
return str (value)
return "*type-error*"
diff --git a/qpid/python/qpid/peer.py b/qpid/python/qpid/peer.py
index 648f32ceef..18d7848b8d 100644
--- a/qpid/python/qpid/peer.py
+++ b/qpid/python/qpid/peer.py
@@ -460,6 +460,6 @@ class IncomingCompletion:
#TODO: record and manage the ranges properly
range = [mark, mark]
if (self.mark == -1):#hack until wraparound is implemented
- self.channel.execution_complete(cumulative_execution_mark=0xFFFFFFFF, ranged_execution_set=range)
+ self.channel.execution_complete(cumulative_execution_mark=0xFFFFFFFFL, ranged_execution_set=range)
else:
self.channel.execution_complete(cumulative_execution_mark=self.mark, ranged_execution_set=range)
diff --git a/qpid/python/qpid/spec010.py b/qpid/python/qpid/spec010.py
index cbc85a5e8b..eabc8e2983 100644
--- a/qpid/python/qpid/spec010.py
+++ b/qpid/python/qpid/spec010.py
@@ -467,19 +467,31 @@ class Exception(Named, Node):
node.exceptions.append(self)
Node.register(self)
+def direct(t):
+ return lambda x: t
+
+def map_str(s):
+ for c in s:
+ if ord(c) >= 0x80:
+ return "vbin16"
+ return "str16"
+
class Spec(Node):
ENCODINGS = {
- basestring: "vbin16",
- int: "int64",
- long: "int64",
- float: "float",
- None.__class__: "void",
- list: "list",
- tuple: "list",
- dict: "map",
- datatypes.timestamp: "datetime",
- datetime.datetime: "datetime"
+ unicode: direct("str16"),
+ str: map_str,
+ buffer: direct("vbin32"),
+ int: direct("int64"),
+ long: direct("int64"),
+ float: direct("double"),
+ None.__class__: direct("void"),
+ list: direct("list"),
+ tuple: direct("list"),
+ dict: direct("map"),
+ datatypes.timestamp: direct("datetime"),
+ datetime.datetime: direct("datetime"),
+ datatypes.UUID: direct("uuid")
}
def __init__(self, major, minor, port, children):
@@ -500,11 +512,14 @@ class Spec(Node):
self.structs_by_name = {}
self.enums = {}
- def encoding(self, klass):
+ def encoding(self, obj):
+ return self._encoding(obj.__class__, obj)
+
+ def _encoding(self, klass, obj):
if Spec.ENCODINGS.has_key(klass):
- return self.named[Spec.ENCODINGS[klass]]
+ return self.named[Spec.ENCODINGS[klass](obj)]
for base in klass.__bases__:
- result = self.encoding(base)
+ result = self._encoding(base, obj)
if result != None:
return result
diff --git a/qpid/python/qpid/testlib.py b/qpid/python/qpid/testlib.py
index 31f52169ae..7f5ac1fcd2 100644
--- a/qpid/python/qpid/testlib.py
+++ b/qpid/python/qpid/testlib.py
@@ -288,16 +288,16 @@ class TestBase(unittest.TestCase):
else: self.uniqueTag += 1
consumer_tag = "tag" + str(self.uniqueTag)
self.channel.message_subscribe(queue=queueName, destination=consumer_tag)
- self.channel.message_flow(destination=consumer_tag, unit=0, value=0xFFFFFFFF)
- self.channel.message_flow(destination=consumer_tag, unit=1, value=0xFFFFFFFF)
+ self.channel.message_flow(destination=consumer_tag, unit=0, value=0xFFFFFFFFL)
+ self.channel.message_flow(destination=consumer_tag, unit=1, value=0xFFFFFFFFL)
return self.client.queue(consumer_tag)
def subscribe(self, channel=None, **keys):
channel = channel or self.channel
consumer_tag = keys["destination"]
channel.message_subscribe(**keys)
- channel.message_flow(destination=consumer_tag, unit=0, value=0xFFFFFFFF)
- channel.message_flow(destination=consumer_tag, unit=1, value=0xFFFFFFFF)
+ channel.message_flow(destination=consumer_tag, unit=0, value=0xFFFFFFFFL)
+ channel.message_flow(destination=consumer_tag, unit=1, value=0xFFFFFFFFL)
def assertEmpty(self, queue):
"""Assert that the queue is empty"""
@@ -388,5 +388,5 @@ class TestBase010(unittest.TestCase):
session = session or self.session
consumer_tag = keys["destination"]
session.message_subscribe(**keys)
- session.message_flow(destination=consumer_tag, unit=0, value=0xFFFFFFFF)
- session.message_flow(destination=consumer_tag, unit=1, value=0xFFFFFFFF)
+ session.message_flow(destination=consumer_tag, unit=0, value=0xFFFFFFFFL)
+ session.message_flow(destination=consumer_tag, unit=1, value=0xFFFFFFFFL)
diff --git a/qpid/python/setup.py b/qpid/python/setup.py
index a49fa6ca51..069cb14a3c 100644
--- a/qpid/python/setup.py
+++ b/qpid/python/setup.py
@@ -19,7 +19,7 @@
#
from distutils.core import setup
-setup(name="qpid", version="0.1", packages=["qpid"], scripts=["amqp-doc"],
- url="http://incubator.apache.org/qpid",
+setup(name="qpid", version="0.5", packages=["qpid"], scripts=["amqp-doc"],
+ url="http://qpid.apache.org/",
license="Apache Software License",
description="Python language client implementation for Apache Qpid")
diff --git a/qpid/python/tests/codec010.py b/qpid/python/tests/codec010.py
index 1912eac591..a1f89dc3f4 100644
--- a/qpid/python/tests/codec010.py
+++ b/qpid/python/tests/codec010.py
@@ -23,7 +23,7 @@ from unittest import TestCase
from qpid.spec010 import load
from qpid.codec010 import StringCodec
from qpid.testlib import testrunner
-from qpid.datatypes import timestamp
+from qpid.datatypes import timestamp, uuid4
class CodecTest(TestCase):
@@ -42,6 +42,17 @@ class CodecTest(TestCase):
def testMapString(self):
self.check("map", {"string": "this is a test"})
+ def testMapUnicode(self):
+ self.check("map", {"unicode": u"this is a unicode test"})
+
+ def testMapBinary(self):
+ self.check("map", {"binary": "\x7f\xb4R^\xe5\xf0:\x89\x96E1\xf6\xfe\xb9\x1b\xf5"})
+
+ def testMapBuffer(self):
+ s = "\x7f\xb4R^\xe5\xf0:\x89\x96E1\xf6\xfe\xb9\x1b\xf5"
+ dec = self.check("map", {"buffer": buffer(s)}, False)
+ assert dec["buffer"] == s
+
def testMapInt(self):
self.check("map", {"int": 3})
@@ -68,14 +79,20 @@ class CodecTest(TestCase):
def testMapList(self):
self.check("map", {"list": [1, "two", 3.0, -4]})
+ def testMapUUID(self):
+ self.check("map", {"uuid": uuid4()})
+
def testMapAll(self):
decoded = self.check("map", {"string": "this is a test",
+ "unicode": u"this is a unicode test",
+ "binary": "\x7f\xb4R^\xe5\xf0:\x89\x96E1\xf6\xfe\xb9\x1b\xf5",
"int": 3,
"long": 2**32,
"timestamp": timestamp(0),
"none": None,
"map": {"string": "nested map"},
- "list": [1, "two", 3.0, -4]})
+ "list": [1, "two", 3.0, -4],
+ "uuid": uuid4()})
assert isinstance(decoded["timestamp"], timestamp)
def testMapEmpty(self):
diff --git a/qpid/python/tests/datatypes.py b/qpid/python/tests/datatypes.py
index 4b9e1bcc78..e9e09094fa 100644
--- a/qpid/python/tests/datatypes.py
+++ b/qpid/python/tests/datatypes.py
@@ -25,16 +25,16 @@ from qpid.datatypes import *
class SerialTest(TestCase):
def test(self):
- for s in (serial(0), serial(0x8FFFFFFF), serial(0xFFFFFFFF)):
+ for s in (serial(0), serial(0x8FFFFFFFL), serial(0xFFFFFFFFL)):
assert s + 1 > s
assert s - 1 < s
assert s < s + 1
assert s > s - 1
- assert serial(0xFFFFFFFF) + 1 == serial(0)
+ assert serial(0xFFFFFFFFL) + 1 == serial(0)
- assert min(serial(0xFFFFFFFF), serial(0x0)) == serial(0xFFFFFFFF)
- assert max(serial(0xFFFFFFFF), serial(0x0)) == serial(0x0)
+ assert min(serial(0xFFFFFFFFL), serial(0x0)) == serial(0xFFFFFFFFL)
+ assert max(serial(0xFFFFFFFFL), serial(0x0)) == serial(0x0)
def testIncr(self):
s = serial(0)
@@ -44,7 +44,7 @@ class SerialTest(TestCase):
def testIn(self):
l = [serial(1), serial(2), serial(3), serial(4)]
assert serial(1) in l
- assert serial(0xFFFFFFFF + 2) in l
+ assert serial(0xFFFFFFFFL + 2) in l
assert 4 in l
def testNone(self):
diff --git a/qpid/python/tests_0-10/alternate_exchange.py b/qpid/python/tests_0-10/alternate_exchange.py
index aac8a5e15b..3b75145907 100644
--- a/qpid/python/tests_0-10/alternate_exchange.py
+++ b/qpid/python/tests_0-10/alternate_exchange.py
@@ -41,16 +41,16 @@ class AlternateExchangeTests(TestBase010):
session.queue_declare(queue="returns", exclusive=True, auto_delete=True)
session.exchange_bind(queue="returns", exchange="secondary")
session.message_subscribe(destination="a", queue="returns")
- session.message_flow(destination="a", unit=session.credit_unit.message, value=0xFFFFFFFF)
- session.message_flow(destination="a", unit=session.credit_unit.byte, value=0xFFFFFFFF)
+ session.message_flow(destination="a", unit=session.credit_unit.message, value=0xFFFFFFFFL)
+ session.message_flow(destination="a", unit=session.credit_unit.byte, value=0xFFFFFFFFL)
returned = session.incoming("a")
#declare, bind (to the primary exchange) and consume from a queue for 'processed' messages
session.queue_declare(queue="processed", exclusive=True, auto_delete=True)
session.exchange_bind(queue="processed", exchange="primary", binding_key="my-key")
session.message_subscribe(destination="b", queue="processed")
- session.message_flow(destination="b", unit=session.credit_unit.message, value=0xFFFFFFFF)
- session.message_flow(destination="b", unit=session.credit_unit.byte, value=0xFFFFFFFF)
+ session.message_flow(destination="b", unit=session.credit_unit.message, value=0xFFFFFFFFL)
+ session.message_flow(destination="b", unit=session.credit_unit.byte, value=0xFFFFFFFFL)
processed = session.incoming("b")
#publish to the primary exchange
@@ -81,8 +81,8 @@ class AlternateExchangeTests(TestBase010):
session.queue_declare(queue="deleted", exclusive=True, auto_delete=True)
session.exchange_bind(exchange="dlq", queue="deleted")
session.message_subscribe(destination="dlq", queue="deleted")
- session.message_flow(destination="dlq", unit=session.credit_unit.message, value=0xFFFFFFFF)
- session.message_flow(destination="dlq", unit=session.credit_unit.byte, value=0xFFFFFFFF)
+ session.message_flow(destination="dlq", unit=session.credit_unit.message, value=0xFFFFFFFFL)
+ session.message_flow(destination="dlq", unit=session.credit_unit.byte, value=0xFFFFFFFFL)
dlq = session.incoming("dlq")
#create a queue using the dlq as its alternate exchange:
diff --git a/qpid/python/tests_0-10/broker.py b/qpid/python/tests_0-10/broker.py
index d4aa57765c..81d723e322 100644
--- a/qpid/python/tests_0-10/broker.py
+++ b/qpid/python/tests_0-10/broker.py
@@ -36,8 +36,8 @@ class BrokerTests(TestBase010):
# No ack consumer
ctag = "tag1"
session.message_subscribe(queue = "myqueue", destination = ctag)
- session.message_flow(destination=ctag, unit=session.credit_unit.message, value=0xFFFFFFFF)
- session.message_flow(destination=ctag, unit=session.credit_unit.byte, value=0xFFFFFFFF)
+ session.message_flow(destination=ctag, unit=session.credit_unit.message, value=0xFFFFFFFFL)
+ session.message_flow(destination=ctag, unit=session.credit_unit.byte, value=0xFFFFFFFFL)
body = "test no-ack"
session.message_transfer(message=Message(session.delivery_properties(routing_key="myqueue"), body))
msg = session.incoming(ctag).get(timeout = 5)
@@ -47,8 +47,8 @@ class BrokerTests(TestBase010):
session.queue_declare(queue = "otherqueue", exclusive=True, auto_delete=True)
ctag = "tag2"
session.message_subscribe(queue = "otherqueue", destination = ctag, accept_mode = 1)
- session.message_flow(destination=ctag, unit=session.credit_unit.message, value=0xFFFFFFFF)
- session.message_flow(destination=ctag, unit=session.credit_unit.byte, value=0xFFFFFFFF)
+ session.message_flow(destination=ctag, unit=session.credit_unit.message, value=0xFFFFFFFFL)
+ session.message_flow(destination=ctag, unit=session.credit_unit.byte, value=0xFFFFFFFFL)
body = "test ack"
session.message_transfer(message=Message(session.delivery_properties(routing_key="otherqueue"), body))
msg = session.incoming(ctag).get(timeout = 5)
@@ -64,8 +64,8 @@ class BrokerTests(TestBase010):
session.exchange_bind(queue="test-queue", exchange="amq.fanout")
consumer_tag = "tag1"
session.message_subscribe(queue="test-queue", destination=consumer_tag)
- session.message_flow(unit = session.credit_unit.message, value = 0xFFFFFFFF, destination = consumer_tag)
- session.message_flow(unit = session.credit_unit.byte, value = 0xFFFFFFFF, destination = consumer_tag)
+ session.message_flow(unit = session.credit_unit.message, value = 0xFFFFFFFFL, destination = consumer_tag)
+ session.message_flow(unit = session.credit_unit.byte, value = 0xFFFFFFFFL, destination = consumer_tag)
queue = session.incoming(consumer_tag)
body = "Immediate Delivery"
@@ -86,8 +86,8 @@ class BrokerTests(TestBase010):
consumer_tag = "tag1"
session.message_subscribe(queue="test-queue", destination=consumer_tag)
- session.message_flow(unit = session.credit_unit.message, value = 0xFFFFFFFF, destination = consumer_tag)
- session.message_flow(unit = session.credit_unit.byte, value = 0xFFFFFFFF, destination = consumer_tag)
+ session.message_flow(unit = session.credit_unit.message, value = 0xFFFFFFFFL, destination = consumer_tag)
+ session.message_flow(unit = session.credit_unit.byte, value = 0xFFFFFFFFL, destination = consumer_tag)
queue = session.incoming(consumer_tag)
msg = queue.get(timeout=5)
self.assert_(msg.body == body)
diff --git a/qpid/python/tests_0-10/dtx.py b/qpid/python/tests_0-10/dtx.py
index 25c2defd3b..2823385a3b 100644
--- a/qpid/python/tests_0-10/dtx.py
+++ b/qpid/python/tests_0-10/dtx.py
@@ -575,7 +575,7 @@ class DtxTests(TestBase010):
session2.dtx_start(xid=tx)
session2.message_subscribe(queue="dummy", destination="dummy")
session2.message_flow(destination="dummy", unit=session2.credit_unit.message, value=1)
- session2.message_flow(destination="dummy", unit=session2.credit_unit.byte, value=0xFFFFFFFF)
+ session2.message_flow(destination="dummy", unit=session2.credit_unit.byte, value=0xFFFFFFFFL)
msg = session2.incoming("dummy").get(timeout=1)
session2.message_accept(RangedSet(msg.id))
session2.message_cancel(destination="dummy")
@@ -736,7 +736,7 @@ class DtxTests(TestBase010):
#consume from src:
session.message_subscribe(destination="temp-swap", queue=src)
session.message_flow(destination="temp-swap", unit=session.credit_unit.message, value=1)
- session.message_flow(destination="temp-swap", unit=session.credit_unit.byte, value=0xFFFFFFFF)
+ session.message_flow(destination="temp-swap", unit=session.credit_unit.byte, value=0xFFFFFFFFL)
msg = session.incoming("temp-swap").get(timeout=1)
session.message_cancel(destination="temp-swap")
session.message_accept(RangedSet(msg.id))
@@ -753,7 +753,7 @@ class DtxTests(TestBase010):
def assertMessageId(self, expected, queue):
self.session.message_subscribe(queue=queue, destination="results")
self.session.message_flow(destination="results", unit=self.session.credit_unit.message, value=1)
- self.session.message_flow(destination="results", unit=self.session.credit_unit.byte, value=0xFFFFFFFF)
+ self.session.message_flow(destination="results", unit=self.session.credit_unit.byte, value=0xFFFFFFFFL)
self.assertEqual(expected, self.getMessageProperty(self.session.incoming("results").get(timeout=1), 'correlation_id'))
self.session.message_cancel(destination="results")
diff --git a/qpid/python/tests_0-10/example.py b/qpid/python/tests_0-10/example.py
index 83d208192b..e36907d501 100644
--- a/qpid/python/tests_0-10/example.py
+++ b/qpid/python/tests_0-10/example.py
@@ -69,8 +69,8 @@ class ExampleTest (TestBase010):
# field that is filled if the reply includes content. In this case the
# interesting field is the consumer_tag.
session.message_subscribe(queue="test-queue", destination="consumer_tag")
- session.message_flow(destination="consumer_tag", unit=session.credit_unit.message, value=0xFFFFFFFF)
- session.message_flow(destination="consumer_tag", unit=session.credit_unit.byte, value=0xFFFFFFFF)
+ session.message_flow(destination="consumer_tag", unit=session.credit_unit.message, value=0xFFFFFFFFL)
+ session.message_flow(destination="consumer_tag", unit=session.credit_unit.byte, value=0xFFFFFFFFL)
# We can use the session.incoming(...) method to access the messages
# delivered for our consumer_tag.
diff --git a/qpid/python/tests_0-10/exchange.py b/qpid/python/tests_0-10/exchange.py
index 4b5dc78143..738e3c4def 100644
--- a/qpid/python/tests_0-10/exchange.py
+++ b/qpid/python/tests_0-10/exchange.py
@@ -108,8 +108,8 @@ class TestHelper(TestBase010):
else: self.uniqueTag += 1
consumer_tag = "tag" + str(self.uniqueTag)
self.session.message_subscribe(queue=queueName, destination=consumer_tag)
- self.session.message_flow(destination=consumer_tag, unit=self.session.credit_unit.message, value=0xFFFFFFFF)
- self.session.message_flow(destination=consumer_tag, unit=self.session.credit_unit.byte, value=0xFFFFFFFF)
+ self.session.message_flow(destination=consumer_tag, unit=self.session.credit_unit.message, value=0xFFFFFFFFL)
+ self.session.message_flow(destination=consumer_tag, unit=self.session.credit_unit.byte, value=0xFFFFFFFFL)
return self.session.incoming(consumer_tag)
diff --git a/qpid/python/tests_0-10/management.py b/qpid/python/tests_0-10/management.py
index 0632d85da4..545dc3db3b 100644
--- a/qpid/python/tests_0-10/management.py
+++ b/qpid/python/tests_0-10/management.py
@@ -192,8 +192,8 @@ class ManagementTest (TestBase010):
"Consume the messages of the queue and check they are all there in order"
session.message_subscribe(queue="src-queue", destination="tag")
- session.message_flow(destination="tag", unit=session.credit_unit.message, value=0xFFFFFFFF)
- session.message_flow(destination="tag", unit=session.credit_unit.byte, value=0xFFFFFFFF)
+ session.message_flow(destination="tag", unit=session.credit_unit.message, value=0xFFFFFFFFL)
+ session.message_flow(destination="tag", unit=session.credit_unit.byte, value=0xFFFFFFFFL)
queue = session.incoming("tag")
for count in twenty:
consumed_msg = queue.get(timeout=1)
diff --git a/qpid/python/tests_0-10/message.py b/qpid/python/tests_0-10/message.py
index cbcef5602f..f80eca6363 100644
--- a/qpid/python/tests_0-10/message.py
+++ b/qpid/python/tests_0-10/message.py
@@ -230,8 +230,8 @@ class MessageTests(TestBase010):
session.message_subscribe(destination="my-consumer", queue="test-queue-4")
myqueue = session.incoming("my-consumer")
- session.message_flow(destination="my-consumer", unit=session.credit_unit.message, value=0xFFFFFFFF)
- session.message_flow(destination="my-consumer", unit=session.credit_unit.byte, value=0xFFFFFFFF)
+ session.message_flow(destination="my-consumer", unit=session.credit_unit.message, value=0xFFFFFFFFL)
+ session.message_flow(destination="my-consumer", unit=session.credit_unit.byte, value=0xFFFFFFFFL)
#should flush here
@@ -258,8 +258,8 @@ class MessageTests(TestBase010):
session.queue_declare(queue="test-ack-queue", auto_delete=True)
session.message_subscribe(queue = "test-ack-queue", destination = "consumer")
- session.message_flow(destination="consumer", unit=session.credit_unit.message, value=0xFFFFFFFF)
- session.message_flow(destination="consumer", unit=session.credit_unit.byte, value=0xFFFFFFFF)
+ session.message_flow(destination="consumer", unit=session.credit_unit.message, value=0xFFFFFFFFL)
+ session.message_flow(destination="consumer", unit=session.credit_unit.byte, value=0xFFFFFFFFL)
queue = session.incoming("consumer")
delivery_properties = session.delivery_properties(routing_key="test-ack-queue")
@@ -289,8 +289,8 @@ class MessageTests(TestBase010):
session.close(timeout=10)
session = self.session
- session.message_flow(destination="checker", unit=session.credit_unit.message, value=0xFFFFFFFF)
- session.message_flow(destination="checker", unit=session.credit_unit.byte, value=0xFFFFFFFF)
+ session.message_flow(destination="checker", unit=session.credit_unit.message, value=0xFFFFFFFFL)
+ session.message_flow(destination="checker", unit=session.credit_unit.byte, value=0xFFFFFFFFL)
queue = session.incoming("checker")
msg3b = queue.get(timeout=1)
@@ -311,16 +311,16 @@ class MessageTests(TestBase010):
session.exchange_bind(queue = "r", exchange = "amq.fanout")
session.message_subscribe(queue = "q", destination = "consumer")
- session.message_flow(destination="consumer", unit=session.credit_unit.message, value=0xFFFFFFFF)
- session.message_flow(destination="consumer", unit=session.credit_unit.byte, value=0xFFFFFFFF)
+ session.message_flow(destination="consumer", unit=session.credit_unit.message, value=0xFFFFFFFFL)
+ session.message_flow(destination="consumer", unit=session.credit_unit.byte, value=0xFFFFFFFFL)
session.message_transfer(message=Message(session.delivery_properties(routing_key="q"), "blah, blah"))
msg = session.incoming("consumer").get(timeout = 1)
self.assertEquals(msg.body, "blah, blah")
session.message_reject(RangedSet(msg.id))
session.message_subscribe(queue = "r", destination = "checker")
- session.message_flow(destination="checker", unit=session.credit_unit.message, value=0xFFFFFFFF)
- session.message_flow(destination="checker", unit=session.credit_unit.byte, value=0xFFFFFFFF)
+ session.message_flow(destination="checker", unit=session.credit_unit.message, value=0xFFFFFFFFL)
+ session.message_flow(destination="checker", unit=session.credit_unit.byte, value=0xFFFFFFFFL)
msg = session.incoming("checker").get(timeout = 1)
self.assertEquals(msg.body, "blah, blah")
@@ -341,7 +341,7 @@ class MessageTests(TestBase010):
#set message credit to finite amount (less than enough for all messages)
session.message_flow(unit = session.credit_unit.message, value = 5, destination = "c")
#set infinite byte credit
- session.message_flow(unit = session.credit_unit.byte, value = 0xFFFFFFFF, destination = "c")
+ session.message_flow(unit = session.credit_unit.byte, value = 0xFFFFFFFFL, destination = "c")
#check that expected number were received
q = session.incoming("c")
for i in range(1, 6):
@@ -374,7 +374,7 @@ class MessageTests(TestBase010):
#set byte credit to finite amount (less than enough for all messages)
session.message_flow(unit = session.credit_unit.byte, value = msg_size*5, destination = "c")
#set infinite message credit
- session.message_flow(unit = session.credit_unit.message, value = 0xFFFFFFFF, destination = "c")
+ session.message_flow(unit = session.credit_unit.message, value = 0xFFFFFFFFL, destination = "c")
#check that expected number were received
q = session.incoming("c")
for i in range(5):
@@ -405,7 +405,7 @@ class MessageTests(TestBase010):
#set message credit to finite amount (less than enough for all messages)
session.message_flow(unit = session.credit_unit.message, value = 5, destination = "c")
#set infinite byte credit
- session.message_flow(unit = session.credit_unit.byte, value = 0xFFFFFFFF, destination = "c")
+ session.message_flow(unit = session.credit_unit.byte, value = 0xFFFFFFFFL, destination = "c")
#check that expected number were received
q = session.incoming("c")
for i in range(1, 6):
@@ -443,7 +443,7 @@ class MessageTests(TestBase010):
#set byte credit to finite amount (less than enough for all messages)
session.message_flow(unit = session.credit_unit.byte, value = msg_size*5, destination = "c")
#set infinite message credit
- session.message_flow(unit = session.credit_unit.message, value = 0xFFFFFFFF, destination = "c")
+ session.message_flow(unit = session.credit_unit.message, value = 0xFFFFFFFFL, destination = "c")
#check that expected number were received
q = session.incoming("c")
msgs = []
@@ -462,6 +462,42 @@ class MessageTests(TestBase010):
self.assertDataEquals(session, q.get(timeout = 1), "abcdefgh")
self.assertEmpty(q)
+ def test_window_flush_ack_flow(self):
+ """
+ Test basic window based flow control with unit = bytes
+ """
+ #declare an exclusive queue
+ ssn = self.session
+ ssn.queue_declare(queue = "q", exclusive=True, auto_delete=True)
+ #create consumer
+ ssn.message_subscribe(queue = "q", destination = "c",
+ accept_mode=ssn.accept_mode.explicit)
+ ssn.message_set_flow_mode(flow_mode = ssn.flow_mode.window, destination = "c")
+
+ #send message A
+ ssn.message_transfer(message=Message(ssn.delivery_properties(routing_key="q"), "A"))
+
+ for unit in ssn.credit_unit.values():
+ ssn.message_flow("c", unit, 0xFFFFFFFFL)
+
+ q = ssn.incoming("c")
+ msgA = q.get(timeout=10)
+
+ ssn.message_flush(destination="c")
+
+ # XXX
+ ssn.receiver._completed.add(msgA.id)
+ ssn.channel.session_completed(ssn.receiver._completed)
+ ssn.message_accept(RangedSet(msgA.id))
+
+ for unit in ssn.credit_unit.values():
+ ssn.message_flow("c", unit, 0xFFFFFFFFL)
+
+ #send message B
+ ssn.message_transfer(message=Message(ssn.delivery_properties(routing_key="q"), "B"))
+
+ msgB = q.get(timeout=10)
+
def test_subscribe_not_acquired(self):
"""
Test the not-acquired modes works as expected for a simple case
@@ -472,11 +508,11 @@ class MessageTests(TestBase010):
session.message_transfer(message=Message(session.delivery_properties(routing_key="q"), "Message %s" % i))
session.message_subscribe(queue = "q", destination = "a", acquire_mode = 1)
- session.message_flow(unit = session.credit_unit.message, value = 0xFFFFFFFF, destination = "a")
- session.message_flow(unit = session.credit_unit.byte, value = 0xFFFFFFFF, destination = "a")
+ session.message_flow(unit = session.credit_unit.message, value = 0xFFFFFFFFL, destination = "a")
+ session.message_flow(unit = session.credit_unit.byte, value = 0xFFFFFFFFL, destination = "a")
session.message_subscribe(queue = "q", destination = "b", acquire_mode = 1)
- session.message_flow(unit = session.credit_unit.message, value = 0xFFFFFFFF, destination = "b")
- session.message_flow(unit = session.credit_unit.byte, value = 0xFFFFFFFF, destination = "b")
+ session.message_flow(unit = session.credit_unit.message, value = 0xFFFFFFFFL, destination = "b")
+ session.message_flow(unit = session.credit_unit.byte, value = 0xFFFFFFFFL, destination = "b")
for i in range(6, 11):
session.message_transfer(message=Message(session.delivery_properties(routing_key="q"), "Message %s" % i))
@@ -508,8 +544,8 @@ class MessageTests(TestBase010):
session.message_subscribe(queue = "q", destination = "a", acquire_mode = 1, accept_mode = 1)
session.message_set_flow_mode(flow_mode = session.flow_mode.credit, destination = "a")
- session.message_flow(unit = session.credit_unit.message, value = 0xFFFFFFFF, destination = "a")
- session.message_flow(unit = session.credit_unit.byte, value = 0xFFFFFFFF, destination = "a")
+ session.message_flow(unit = session.credit_unit.message, value = 0xFFFFFFFFL, destination = "a")
+ session.message_flow(unit = session.credit_unit.byte, value = 0xFFFFFFFFL, destination = "a")
msg = session.incoming("a").get(timeout = 1)
self.assertEquals("acquire me", msg.body)
#message should still be on the queue:
@@ -532,8 +568,8 @@ class MessageTests(TestBase010):
session.message_transfer(message=Message(session.delivery_properties(routing_key="q"), "acquire me"))
session.message_subscribe(queue = "q", destination = "a", acquire_mode = 1)
- session.message_flow(destination="a", unit=session.credit_unit.message, value=0xFFFFFFFF)
- session.message_flow(destination="a", unit=session.credit_unit.byte, value=0xFFFFFFFF)
+ session.message_flow(destination="a", unit=session.credit_unit.message, value=0xFFFFFFFFL)
+ session.message_flow(destination="a", unit=session.credit_unit.byte, value=0xFFFFFFFFL)
msg = session.incoming("a").get(timeout = 1)
self.assertEquals("acquire me", msg.body)
#message should still be on the queue:
@@ -558,8 +594,8 @@ class MessageTests(TestBase010):
session.message_transfer(message=Message(session.delivery_properties(routing_key="q"), "release me"))
session.message_subscribe(queue = "q", destination = "a")
- session.message_flow(destination="a", unit=session.credit_unit.message, value=0xFFFFFFFF)
- session.message_flow(destination="a", unit=session.credit_unit.byte, value=0xFFFFFFFF)
+ session.message_flow(destination="a", unit=session.credit_unit.message, value=0xFFFFFFFFL)
+ session.message_flow(destination="a", unit=session.credit_unit.byte, value=0xFFFFFFFFL)
msg = session.incoming("a").get(timeout = 1)
self.assertEquals("release me", msg.body)
session.message_cancel(destination = "a")
@@ -579,7 +615,7 @@ class MessageTests(TestBase010):
session.message_subscribe(queue = "q", destination = "a")
session.message_flow(unit = session.credit_unit.message, value = 10, destination = "a")
- session.message_flow(unit = session.credit_unit.byte, value = 0xFFFFFFFF, destination = "a")
+ session.message_flow(unit = session.credit_unit.byte, value = 0xFFFFFFFFL, destination = "a")
queue = session.incoming("a")
first = queue.get(timeout = 1)
for i in range(2, 10):
@@ -612,7 +648,7 @@ class MessageTests(TestBase010):
session.message_subscribe(queue = "q", destination = "a")
session.message_flow(unit = session.credit_unit.message, value = 10, destination = "a")
- session.message_flow(unit = session.credit_unit.byte, value = 0xFFFFFFFF, destination = "a")
+ session.message_flow(unit = session.credit_unit.byte, value = 0xFFFFFFFFL, destination = "a")
queue = session.incoming("a")
ids = []
for i in range (1, 11):
@@ -637,8 +673,8 @@ class MessageTests(TestBase010):
session.close(timeout=10)
session = self.session
- session.message_flow(destination="checker", unit=session.credit_unit.message, value=0xFFFFFFFF)
- session.message_flow(destination="checker", unit=session.credit_unit.byte, value=0xFFFFFFFF)
+ session.message_flow(destination="checker", unit=session.credit_unit.message, value=0xFFFFFFFFL)
+ session.message_flow(destination="checker", unit=session.credit_unit.byte, value=0xFFFFFFFFL)
queue = session.incoming("checker")
self.assertEquals("message 4", queue.get(timeout = 1).body)
@@ -656,7 +692,7 @@ class MessageTests(TestBase010):
session.message_subscribe(queue = "q", destination = "a")
session.message_set_flow_mode(flow_mode = 0, destination = "a")
session.message_flow(unit = session.credit_unit.message, value = 5, destination = "a")
- session.message_flow(unit = session.credit_unit.byte, value = 0xFFFFFFFF, destination = "a")
+ session.message_flow(unit = session.credit_unit.byte, value = 0xFFFFFFFFL, destination = "a")
queue = session.incoming("a")
for i in range(1, 6):
@@ -671,7 +707,7 @@ class MessageTests(TestBase010):
#now create a not-acquired subscriber
session.message_subscribe(queue = "q", destination = "b", acquire_mode=1)
- session.message_flow(unit = session.credit_unit.byte, value = 0xFFFFFFFF, destination = "b")
+ session.message_flow(unit = session.credit_unit.byte, value = 0xFFFFFFFFL, destination = "b")
#check it gets those not consumed
queue = session.incoming("b")
@@ -699,7 +735,7 @@ class MessageTests(TestBase010):
#create a not-acquired subscriber
session.message_subscribe(queue = "q", destination = "a", acquire_mode=1)
- session.message_flow(unit = session.credit_unit.byte, value = 0xFFFFFFFF, destination = "a")
+ session.message_flow(unit = session.credit_unit.byte, value = 0xFFFFFFFFL, destination = "a")
session.message_flow(unit = session.credit_unit.message, value = 10, destination = "a")
#browse through messages
@@ -721,7 +757,7 @@ class MessageTests(TestBase010):
#create a second not-acquired subscriber
session.message_subscribe(queue = "q", destination = "b", acquire_mode=1)
- session.message_flow(unit = session.credit_unit.byte, value = 0xFFFFFFFF, destination = "b")
+ session.message_flow(unit = session.credit_unit.byte, value = 0xFFFFFFFFL, destination = "b")
session.message_flow(unit = session.credit_unit.message, value = 1, destination = "b")
#check it gets those not consumed
queue = session.incoming("b")
@@ -748,12 +784,12 @@ class MessageTests(TestBase010):
#create two 'browsers'
session.message_subscribe(queue = "q", destination = "a", acquire_mode=1)
- session.message_flow(unit = session.credit_unit.byte, value = 0xFFFFFFFF, destination = "a")
+ session.message_flow(unit = session.credit_unit.byte, value = 0xFFFFFFFFL, destination = "a")
session.message_flow(unit = session.credit_unit.message, value = 10, destination = "a")
queueA = session.incoming("a")
session.message_subscribe(queue = "q", destination = "b", acquire_mode=1)
- session.message_flow(unit = session.credit_unit.byte, value = 0xFFFFFFFF, destination = "b")
+ session.message_flow(unit = session.credit_unit.byte, value = 0xFFFFFFFFL, destination = "b")
session.message_flow(unit = session.credit_unit.message, value = 10, destination = "b")
queueB = session.incoming("b")
@@ -770,7 +806,7 @@ class MessageTests(TestBase010):
#create consumer
session.message_subscribe(queue = "q", destination = "c")
- session.message_flow(unit = session.credit_unit.byte, value = 0xFFFFFFFF, destination = "c")
+ session.message_flow(unit = session.credit_unit.byte, value = 0xFFFFFFFFL, destination = "c")
session.message_flow(unit = session.credit_unit.message, value = 10, destination = "c")
queueC = session.incoming("c")
#consume the message then ack it
@@ -787,8 +823,8 @@ class MessageTests(TestBase010):
consumer_tag = "tag1"
session.message_subscribe(queue="xyz", destination=consumer_tag)
- session.message_flow(unit = session.credit_unit.message, value = 0xFFFFFFFF, destination = consumer_tag)
- session.message_flow(unit = session.credit_unit.byte, value = 0xFFFFFFFF, destination = consumer_tag)
+ session.message_flow(unit = session.credit_unit.message, value = 0xFFFFFFFFL, destination = consumer_tag)
+ session.message_flow(unit = session.credit_unit.byte, value = 0xFFFFFFFFL, destination = consumer_tag)
queue = session.incoming(consumer_tag)
msg = queue.get(timeout=1)
self.assertEquals("", msg.body)
@@ -827,7 +863,7 @@ class MessageTests(TestBase010):
messages = session.incoming(d)
sleep(1)
session.message_flow(unit = session.credit_unit.message, value=2, destination=d)
- session.message_flow(unit = session.credit_unit.byte, value=0xFFFFFFFF, destination=d)
+ session.message_flow(unit = session.credit_unit.byte, value=0xFFFFFFFFL, destination=d)
assert messages.get(timeout=1).body == "second"
self.assertEmpty(messages)
diff --git a/qpid/python/tests_0-10/persistence.py b/qpid/python/tests_0-10/persistence.py
index 815ad1f3dc..b93bb0bbfb 100644
--- a/qpid/python/tests_0-10/persistence.py
+++ b/qpid/python/tests_0-10/persistence.py
@@ -49,7 +49,7 @@ class PersistenceTests(TestBase010):
#create consumer
session.message_subscribe(queue = "q", destination = "a", accept_mode = 1, acquire_mode=0)
- session.message_flow(unit = session.credit_unit.byte, value = 0xFFFFFFFF, destination = "a")
+ session.message_flow(unit = session.credit_unit.byte, value = 0xFFFFFFFFL, destination = "a")
session.message_flow(unit = session.credit_unit.message, value = 10, destination = "a")
queue = session.incoming("a")
diff --git a/qpid/python/tests_0-10/queue.py b/qpid/python/tests_0-10/queue.py
index 05e18081fa..eb38965190 100644
--- a/qpid/python/tests_0-10/queue.py
+++ b/qpid/python/tests_0-10/queue.py
@@ -49,8 +49,8 @@ class QueueTests(TestBase010):
#send a further message and consume it, ensuring that the other messages are really gone
session.message_transfer(message=Message(session.delivery_properties(routing_key="test-queue"), "four"))
session.message_subscribe(queue="test-queue", destination="tag")
- session.message_flow(destination="tag", unit=session.credit_unit.message, value=0xFFFFFFFF)
- session.message_flow(destination="tag", unit=session.credit_unit.byte, value=0xFFFFFFFF)
+ session.message_flow(destination="tag", unit=session.credit_unit.message, value=0xFFFFFFFFL)
+ session.message_flow(destination="tag", unit=session.credit_unit.byte, value=0xFFFFFFFFL)
queue = session.incoming("tag")
msg = queue.get(timeout=1)
self.assertEqual("four", msg.body)
@@ -182,11 +182,11 @@ class QueueTests(TestBase010):
session.queue_declare(queue="queue-2", exclusive=True, auto_delete=True)
session.message_subscribe(queue="queue-1", destination="queue-1")
- session.message_flow(destination="queue-1", unit=session.credit_unit.message, value=0xFFFFFFFF)
- session.message_flow(destination="queue-1", unit=session.credit_unit.byte, value=0xFFFFFFFF)
+ session.message_flow(destination="queue-1", unit=session.credit_unit.message, value=0xFFFFFFFFL)
+ session.message_flow(destination="queue-1", unit=session.credit_unit.byte, value=0xFFFFFFFFL)
session.message_subscribe(queue="queue-2", destination="queue-2")
- session.message_flow(destination="queue-2", unit=session.credit_unit.message, value=0xFFFFFFFF)
- session.message_flow(destination="queue-2", unit=session.credit_unit.byte, value=0xFFFFFFFF)
+ session.message_flow(destination="queue-2", unit=session.credit_unit.message, value=0xFFFFFFFFL)
+ session.message_flow(destination="queue-2", unit=session.credit_unit.byte, value=0xFFFFFFFFL)
queue1 = session.incoming("queue-1")
queue2 = session.incoming("queue-2")
@@ -283,8 +283,8 @@ class QueueTests(TestBase010):
#empty queue:
session.message_subscribe(destination="consumer_tag", queue="delete-me-2")
- session.message_flow(destination="consumer_tag", unit=session.credit_unit.message, value=0xFFFFFFFF)
- session.message_flow(destination="consumer_tag", unit=session.credit_unit.byte, value=0xFFFFFFFF)
+ session.message_flow(destination="consumer_tag", unit=session.credit_unit.message, value=0xFFFFFFFFL)
+ session.message_flow(destination="consumer_tag", unit=session.credit_unit.byte, value=0xFFFFFFFFL)
queue = session.incoming("consumer_tag")
msg = queue.get(timeout=1)
self.assertEqual("message", msg.body)
diff --git a/qpid/python/tests_0-10/tx.py b/qpid/python/tests_0-10/tx.py
index da162d54ec..463fbcb888 100644
--- a/qpid/python/tests_0-10/tx.py
+++ b/qpid/python/tests_0-10/tx.py
@@ -251,13 +251,13 @@ class TxTests(TestBase010):
session = session or self.session
consumer_tag = keys["destination"]
session.message_subscribe(**keys)
- session.message_flow(destination=consumer_tag, unit=session.credit_unit.message, value=0xFFFFFFFF)
- session.message_flow(destination=consumer_tag, unit=session.credit_unit.byte, value=0xFFFFFFFF)
+ session.message_flow(destination=consumer_tag, unit=session.credit_unit.message, value=0xFFFFFFFFL)
+ session.message_flow(destination=consumer_tag, unit=session.credit_unit.byte, value=0xFFFFFFFFL)
def enable_flow(self, tag, session=None):
session = session or self.session
- session.message_flow(destination=tag, unit=session.credit_unit.message, value=0xFFFFFFFF)
- session.message_flow(destination=tag, unit=session.credit_unit.byte, value=0xFFFFFFFF)
+ session.message_flow(destination=tag, unit=session.credit_unit.message, value=0xFFFFFFFFL)
+ session.message_flow(destination=tag, unit=session.credit_unit.byte, value=0xFFFFFFFFL)
def complete(self, session, msg):
session.receiver._completed.add(msg.id)#TODO: this may be done automatically
diff --git a/qpid/ruby/Makefile b/qpid/ruby/Makefile
new file mode 100644
index 0000000000..9cac3207c0
--- /dev/null
+++ b/qpid/ruby/Makefile
@@ -0,0 +1,47 @@
+#
+# 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.
+#
+
+SASL_DIR = ext/sasl
+SASL_MODULE = $(SASL_DIR)/sasl.so
+RUBY_LIB = lib
+SPEC_CACHE_SCRIPT = sc.rb
+
+.PHONY: spec_cache all clean distclean
+
+all : build
+
+$(SASL_MODULE) : $(SASL_DIR)/sasl.c
+ cd $(SASL_DIR); ruby extconf.rb
+ $(MAKE) -C $(SASL_DIR)
+
+spec_cache :
+ echo "require 'qpid'" > $(SPEC_CACHE_SCRIPT)
+ echo "Qpid::Spec010::load()" >> $(SPEC_CACHE_SCRIPT)
+ ruby -I $(RUBY_LIB) -I $(SASL_DIR) $(SPEC_CACHE_SCRIPT)
+ rm $(SPEC_CACHE_SCRIPT)
+
+build: $(SASL_MODULE) spec_cache
+
+clean:
+ cd $(SASL_DIR); make clean
+
+distclean:
+ cd $(SASL_DIR); make distclean
+ rm -rf $(RUBY_LIB)/qpid/spec_cache
+
diff --git a/qpid/ruby/lib/qpid/delegates.rb b/qpid/ruby/lib/qpid/delegates.rb
index 9707cdbc76..171f310e48 100644
--- a/qpid/ruby/lib/qpid/delegates.rb
+++ b/qpid/ruby/lib/qpid/delegates.rb
@@ -168,7 +168,10 @@ module Qpid
# analog in Ruby
PROPERTIES = {"product" => "qpid python client",
"version" => "development",
- "platform" => Config::CONFIG["build_os"]}
+ "platform" => Config::CONFIG["build_os"],
+ "qpid.client_process" => File.basename($0),
+ "qpid.client_pid" => Process.pid,
+ "qpid.client_ppid" => Process.ppid}
def initialize(connection, args)
diff --git a/qpid/specs/management-schema.xml b/qpid/specs/management-schema.xml
index 307ced1245..bc38350a45 100644
--- a/qpid/specs/management-schema.xml
+++ b/qpid/specs/management-schema.xml
@@ -70,6 +70,7 @@
<property name="mgmtPubInterval" type="uint16" access="RW" unit="second" min="1" desc="Interval for management broadcasts"/>
<property name="version" type="sstr" access="RO" desc="Running software version"/>
<property name="dataDir" type="sstr" access="RO" optional="y" desc="Persistent configuration storage location"/>
+ <statistic name="uptime" type="deltaTime"/>
<method name="echo" desc="Request a response to test the path to the management broker">
<arg name="sequence" dir="IO" type="uint32" default="0"/>
@@ -206,6 +207,9 @@
<property name="SystemConnection" type="bool" access="RC" desc="Infrastucture/ Inter-system connection (Cluster, Federation, ...)"/>
<property name="federationLink" type="bool" access="RO" desc="Is this a federation link"/>
<property name="authIdentity" type="sstr" access="RO" desc="authId of connection if authentication enabled"/>
+ <property name="remoteProcessName" type="sstr" access="RO" optional="y" desc="Name of executable running as remote client"/>
+ <property name="remotePid" type="uint32" access="RO" optional="y" desc="Process ID of remote client"/>
+ <property name="remoteParentPid" type="uint32" access="RO" optional="y" desc="Parent Process ID of remote client"/>
<statistic name="closing" type="bool" desc="This client is closing by management request"/>
<statistic name="framesFromClient" type="count64"/>
<statistic name="framesToClient" type="count64"/>