summaryrefslogtreecommitdiff
path: root/java
diff options
context:
space:
mode:
Diffstat (limited to 'java')
-rwxr-xr-x[-rw-r--r--]java/broker/bin/msTool.sh (renamed from java/integrationtests/src/resources/org/apache/qpid/interop/connection.properties)76
-rw-r--r--java/broker/bin/qpid-passwd2
-rw-r--r--java/broker/bin/qpid-server6
-rw-r--r--java/broker/distribution/src/main/assembly/broker-bin.xml4
-rw-r--r--java/broker/etc/debug.log4j.xml114
-rw-r--r--java/broker/etc/log4j.xml36
-rw-r--r--java/broker/etc/messagestoretool-log4j.xml53
-rw-r--r--java/broker/etc/mstool-log4j.xml54
-rw-r--r--java/broker/pom.xml19
-rw-r--r--java/broker/src/main/java/org/apache/log4j/QpidCompositeRollingAppender.java3
-rw-r--r--java/broker/src/main/java/org/apache/qpid/configuration/Configuration.java188
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/AMQChannel.java10
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/Main.java56
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/exchange/AbstractExchange.java6
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/exchange/DefaultExchangeRegistry.java19
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/exchange/DestNameExchange.java11
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/exchange/DestWildExchange.java21
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/exchange/Exchange.java28
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/exchange/ExchangeRegistry.java4
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/exchange/FanoutExchange.java29
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/exchange/HeadersExchange.java61
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/handler/BasicConsumeMethodHandler.java18
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/handler/BasicPublishMethodHandler.java10
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/handler/ConnectionStartOkMethodHandler.java3
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/handler/ExchangeBoundHandler.java25
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/handler/ExchangeDeclareHandler.java4
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/handler/QueueBindHandler.java17
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/handler/QueueDeclareHandler.java7
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/management/JMXManagedObjectRegistry.java44
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/management/MBeanInvocationHandlerImpl.java25
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/protocol/AMQPFastProtocolHandler.java28
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/queue/AMQMessage.java16
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/queue/AMQQueue.java250
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/queue/AMQQueueMBean.java66
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/queue/ConcurrentSelectorDeliveryManager.java109
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/queue/DefaultQueueRegistry.java17
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/queue/ExchangeBindings.java13
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/queue/MessageMetaData.java24
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/queue/NotificationCheck.java25
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/queue/QueueNotificationListener.java26
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/queue/QueueRegistry.java6
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/queue/TransientMessageData.java25
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/txn/NonTransactionalContext.java25
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/txn/TransactionalContext.java124
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/virtualhost/VirtualHost.java262
-rw-r--r--java/broker/src/main/java/org/apache/qpid/tools/messagestore/MessageStoreTool.java648
-rw-r--r--java/broker/src/main/java/org/apache/qpid/tools/messagestore/commands/AbstractCommand.java66
-rw-r--r--java/broker/src/main/java/org/apache/qpid/tools/messagestore/commands/Clear.java85
-rw-r--r--java/broker/src/main/java/org/apache/qpid/tools/messagestore/commands/Command.java (renamed from java/integrationtests/src/main/java/org/apache/qpid/interop/coordinator/ListeningCoordinatorTest.java)16
-rw-r--r--java/broker/src/main/java/org/apache/qpid/tools/messagestore/commands/Copy.java56
-rw-r--r--java/broker/src/main/java/org/apache/qpid/tools/messagestore/commands/Dump.java299
-rw-r--r--java/broker/src/main/java/org/apache/qpid/tools/messagestore/commands/Help.java98
-rw-r--r--java/broker/src/main/java/org/apache/qpid/tools/messagestore/commands/List.java314
-rw-r--r--java/broker/src/main/java/org/apache/qpid/tools/messagestore/commands/Load.java94
-rw-r--r--java/broker/src/main/java/org/apache/qpid/tools/messagestore/commands/Move.java166
-rw-r--r--java/broker/src/main/java/org/apache/qpid/tools/messagestore/commands/Purge.java68
-rw-r--r--java/broker/src/main/java/org/apache/qpid/tools/messagestore/commands/Quit.java54
-rw-r--r--java/broker/src/main/java/org/apache/qpid/tools/messagestore/commands/Select.java233
-rw-r--r--java/broker/src/main/java/org/apache/qpid/tools/messagestore/commands/Show.java513
-rw-r--r--java/broker/src/main/java/org/apache/qpid/tools/security/Passwd.java (renamed from java/broker/src/main/java/org/apache/qpid/server/security/Passwd.java)2
-rw-r--r--java/broker/src/main/java/org/apache/qpid/tools/utils/CommandParser.java51
-rw-r--r--java/broker/src/main/java/org/apache/qpid/tools/utils/Console.java90
-rw-r--r--java/broker/src/main/java/org/apache/qpid/tools/utils/SimpleCommandParser.java121
-rw-r--r--java/broker/src/main/java/org/apache/qpid/tools/utils/SimpleConsole.java363
-rw-r--r--java/broker/src/main/java/org/apache/qpid/tools/utils/utils/CommandParser.java51
-rw-r--r--java/broker/src/main/java/org/apache/qpid/tools/utils/utils/Console.java75
-rw-r--r--java/broker/src/main/java/org/apache/qpid/tools/utils/utils/RSHCommandParser.java352
-rw-r--r--java/broker/src/main/java/org/apache/qpid/tools/utils/utils/SimpleCommandParser.java116
-rw-r--r--java/broker/src/test/java/org/apache/qpid/server/exchange/ExchangeMBeanTest.java25
-rw-r--r--java/broker/src/test/java/org/apache/qpid/server/protocol/TestMinaProtocolSession.java25
-rw-r--r--java/broker/src/test/java/org/apache/qpid/server/queue/AMQQueueAlertTest.java25
-rw-r--r--java/broker/src/test/java/org/apache/qpid/server/queue/AMQQueueMBeanTest.java25
-rw-r--r--java/client/example/src/main/java/org/apache/qpid/example/publisher/MonitorMessageDispatcher.java59
-rw-r--r--java/client/example/src/main/java/org/apache/qpid/example/publisher/MonitorPublisher.java53
-rw-r--r--java/client/example/src/main/java/org/apache/qpid/example/pubsub/Client.java72
-rw-r--r--java/client/example/src/main/java/org/apache/qpid/example/pubsub/ConnectionSetup.java123
-rw-r--r--java/client/example/src/main/java/org/apache/qpid/example/pubsub/Publisher.java81
-rw-r--r--java/client/example/src/main/java/org/apache/qpid/example/pubsub/Subscriber.java98
-rw-r--r--java/client/pom.xml44
-rw-r--r--java/client/src/main/java/org/apache/qpid/client/AMQConnection.java4
-rw-r--r--java/client/src/main/java/org/apache/qpid/client/AMQConnectionURL.java31
-rw-r--r--java/client/src/main/java/org/apache/qpid/client/AMQSession.java10
-rw-r--r--java/client/src/main/java/org/apache/qpid/client/handler/ExchangeBoundOkMethodHandler.java25
-rw-r--r--java/client/src/main/java/org/apache/qpid/client/handler/QueueDeleteOkMethodHandler.java25
-rw-r--r--java/client/src/test/java/org/apache/qpid/test/unit/client/channelclose/CloseWithBlockingReceiveTest.java25
-rw-r--r--java/client/src/test/java/org/apache/qpid/test/unit/client/forwardall/CombinedTest.java17
-rw-r--r--java/client/src/test/java/org/apache/qpid/test/unit/transacted/CommitRollbackTest.java118
-rw-r--r--java/cluster/src/main/java/org/apache/qpid/server/cluster/SimpleBodySendable.java25
-rw-r--r--java/common/pom.xml26
-rw-r--r--java/common/src/main/java/org/apache/qpid/framing/AMQShortString.java56
-rw-r--r--java/common/src/main/java/org/apache/qpid/framing/abstraction/MessagePublishInfoConverter.java25
-rw-r--r--java/common/src/main/java/org/apache/qpid/framing/abstraction/ProtocolVersionMethodConverter.java25
-rw-r--r--java/common/src/main/java/org/apache/qpid/util/CommandLineParser.java14
-rw-r--r--java/distribution/pom.xml7
-rw-r--r--java/distribution/src/main/assembly/bin-test.xml151
-rw-r--r--java/distribution/src/main/assembly/bin.xml178
-rw-r--r--java/distribution/src/main/assembly/management-eclipse-plugin-unix.xml39
-rw-r--r--java/distribution/src/main/assembly/management-eclipse-plugin.xml68
-rw-r--r--java/distribution/src/main/assembly/src.xml42
-rw-r--r--java/distribution/src/main/release/DISCLAIMER5
-rw-r--r--java/distribution/src/main/release/NOTICE.txt36
-rw-r--r--java/distribution/src/main/release/README.txt104
-rw-r--r--java/etc/coding_standards.xml3
-rw-r--r--java/integrationtests/docs/RunningSustainedTests.txt14
-rw-r--r--java/integrationtests/pom.xml6
-rw-r--r--java/integrationtests/src/main/java/org/apache/qpid/interop/clienttestcases/TestCase1DummyRun.java (renamed from java/integrationtests/src/main/java/org/apache/qpid/interop/testclient/testcases/TestCase1DummyRun.java)51
-rw-r--r--java/integrationtests/src/main/java/org/apache/qpid/interop/clienttestcases/TestCase2BasicP2P.java (renamed from java/integrationtests/src/main/java/org/apache/qpid/interop/testclient/testcases/TestCase2BasicP2P.java)33
-rw-r--r--java/integrationtests/src/main/java/org/apache/qpid/interop/clienttestcases/TestCase3BasicPubSub.java (renamed from java/integrationtests/src/main/java/org/apache/qpid/interop/testclient/testcases/TestCase3BasicPubSub.java)56
-rw-r--r--java/integrationtests/src/main/java/org/apache/qpid/interop/coordinator/CoordinatingTestCase.java263
-rw-r--r--java/integrationtests/src/main/java/org/apache/qpid/interop/coordinator/ListeningTestDecorator.java200
-rw-r--r--java/integrationtests/src/main/java/org/apache/qpid/interop/old/Listener.java291
-rw-r--r--java/integrationtests/src/main/java/org/apache/qpid/interop/old/Publisher.java244
-rw-r--r--java/integrationtests/src/main/java/org/apache/qpid/interop/testcases/CircuitTestCase.java101
-rw-r--r--java/integrationtests/src/main/java/org/apache/qpid/interop/testcases/InteropTestCase1DummyRun.java (renamed from java/integrationtests/src/main/java/org/apache/qpid/interop/coordinator/testcases/CoordinatingTestCase1DummyRun.java)35
-rw-r--r--java/integrationtests/src/main/java/org/apache/qpid/interop/testcases/InteropTestCase2BasicP2P.java (renamed from java/integrationtests/src/main/java/org/apache/qpid/interop/coordinator/testcases/CoordinatingTestCase2BasicP2P.java)42
-rw-r--r--java/integrationtests/src/main/java/org/apache/qpid/interop/testcases/InteropTestCase3BasicPubSub.java (renamed from java/integrationtests/src/main/java/org/apache/qpid/interop/coordinator/testcases/CoordinatingTestCase3BasicPubSub.java)34
-rw-r--r--java/integrationtests/src/main/java/org/apache/qpid/sustained/SustainedClientTestCase.java905
-rw-r--r--java/integrationtests/src/main/java/org/apache/qpid/sustained/SustainedTestCase.java126
-rw-r--r--java/integrationtests/src/main/java/org/apache/qpid/sustained/SustainedTestClient.java8
-rw-r--r--java/integrationtests/src/main/java/org/apache/qpid/sustained/SustainedTestCoordinator.java222
-rw-r--r--java/integrationtests/src/main/java/org/apache/qpid/sustained/TestClient.java157
-rw-r--r--java/integrationtests/src/main/java/org/apache/qpid/sustained/TestCoordinator.java117
-rw-r--r--java/integrationtests/src/main/java/org/apache/qpid/test/framework/distributedtesting/InteropClientTestCase.java (renamed from java/integrationtests/src/main/java/org/apache/qpid/interop/testclient/InteropClientTestCase.java)21
-rw-r--r--java/integrationtests/src/main/java/org/apache/qpid/test/framework/distributedtesting/TestClient.java (renamed from java/integrationtests/src/main/java/org/apache/qpid/interop/testclient/TestClient.java)229
-rw-r--r--java/management/eclipse-plugin/pom.xml41
-rw-r--r--java/management/eclipse-plugin/src/test/java/org/apache/qpid/management/ui/ManagementConsoleTest.java24
-rw-r--r--java/perftests/pom.xml230
-rw-r--r--java/perftests/src/main/java/org/apache/qpid/client/message/TestMessageFactory.java25
-rw-r--r--java/perftests/src/main/java/org/apache/qpid/ping/PingDurableClient.java27
-rw-r--r--java/perftests/src/main/java/org/apache/qpid/ping/PingSendOnlyClient.java2
-rw-r--r--java/perftests/src/main/java/org/apache/qpid/requestreply/PingPongProducer.java35
-rw-r--r--java/pom.xml62
-rw-r--r--java/release-docs/RELEASE_NOTES.txt127
-rw-r--r--[-rwxr-xr-x]java/resources/LICENSE (renamed from java/distribution/src/main/release/LICENSE.txt)0
-rw-r--r--java/resources/META-INF/DISCLAIMER10
-rw-r--r--java/resources/META-INF/DISCLAIMER.txt7
-rw-r--r--[-rwxr-xr-x]java/resources/META-INF/LICENSE (renamed from java/resources/LICENSE.txt)0
-rw-r--r--java/resources/META-INF/NOTICE105
-rw-r--r--java/resources/NOTICE105
-rw-r--r--java/resources/NOTICE.txt36
-rw-r--r--java/resources/README (renamed from java/resources/README.txt)0
-rw-r--r--java/systests/pom.xml3
-rw-r--r--java/systests/src/main/java/org/apache/qpid/server/AMQBrokerManagerMBeanTest.java48
-rw-r--r--java/systests/src/main/java/org/apache/qpid/server/exchange/ImmediateMessageTest.java827
-rw-r--r--java/systests/src/main/java/org/apache/qpid/server/exchange/MandatoryMessageTest.java210
-rw-r--r--java/systests/src/main/java/org/apache/qpid/server/exchange/ReturnUnroutableMandatoryMessageTest.java12
-rw-r--r--java/systests/src/main/java/org/apache/qpid/server/protocol/AMQProtocolSessionMBeanTest.java25
-rw-r--r--java/systests/src/main/java/org/apache/qpid/server/protocol/MaxChannelsTest.java25
-rw-r--r--java/systests/src/main/java/org/apache/qpid/server/queue/PersistentTestManual.java69
-rw-r--r--java/systests/src/main/java/org/apache/qpid/test/VMTestCase.java28
-rw-r--r--java/systests/src/main/java/org/apache/qpid/test/framework/Assertion.java39
-rw-r--r--java/systests/src/main/java/org/apache/qpid/test/framework/AssertionBase.java66
-rw-r--r--java/systests/src/main/java/org/apache/qpid/test/framework/Circuit.java109
-rw-r--r--java/systests/src/main/java/org/apache/qpid/test/framework/CircuitEnd.java77
-rw-r--r--java/systests/src/main/java/org/apache/qpid/test/framework/CircuitEndBase.java119
-rw-r--r--java/systests/src/main/java/org/apache/qpid/test/framework/DropInTest.java51
-rw-r--r--java/systests/src/main/java/org/apache/qpid/test/framework/ExceptionMonitor.java151
-rw-r--r--java/systests/src/main/java/org/apache/qpid/test/framework/FrameworkBaseCase.java207
-rw-r--r--java/systests/src/main/java/org/apache/qpid/test/framework/MessageMonitor.java46
-rw-r--r--java/systests/src/main/java/org/apache/qpid/test/framework/MessagingTestConfigProperties.java (renamed from java/systests/src/main/java/org/apache/qpid/server/exchange/MessagingTestConfigProperties.java)20
-rw-r--r--java/systests/src/main/java/org/apache/qpid/test/framework/Publisher.java56
-rw-r--r--java/systests/src/main/java/org/apache/qpid/test/framework/Receiver.java48
-rw-r--r--java/systests/src/main/java/org/apache/qpid/test/framework/TestClientDetails.java (renamed from java/integrationtests/src/main/java/org/apache/qpid/interop/coordinator/TestClientDetails.java)15
-rw-r--r--java/systests/src/main/java/org/apache/qpid/test/framework/TestUtils.java156
-rw-r--r--java/systests/src/main/java/org/apache/qpid/test/framework/distributedcircuit/DistributedCircuitImpl.java116
-rw-r--r--java/systests/src/main/java/org/apache/qpid/test/framework/distributedtesting/Coordinator.java (renamed from java/integrationtests/src/main/java/org/apache/qpid/interop/coordinator/Coordinator.java)242
-rw-r--r--java/systests/src/main/java/org/apache/qpid/test/framework/distributedtesting/DistributedTestCase.java81
-rw-r--r--java/systests/src/main/java/org/apache/qpid/test/framework/distributedtesting/DistributedTestDecorator.java166
-rw-r--r--java/systests/src/main/java/org/apache/qpid/test/framework/distributedtesting/FanOutTestDecorator.java201
-rw-r--r--java/systests/src/main/java/org/apache/qpid/test/framework/distributedtesting/InteropTestDecorator.java (renamed from java/integrationtests/src/main/java/org/apache/qpid/interop/coordinator/InvitingTestDecorator.java)121
-rw-r--r--java/systests/src/main/java/org/apache/qpid/test/framework/distributedtesting/OptOutTestCase.java (renamed from java/integrationtests/src/main/java/org/apache/qpid/interop/coordinator/OptOutTestCase.java)13
-rw-r--r--java/systests/src/main/java/org/apache/qpid/test/framework/listeners/XMLTestListener.java (renamed from java/integrationtests/src/main/java/org/apache/qpid/interop/coordinator/XMLTestListener.java)96
-rw-r--r--java/systests/src/main/java/org/apache/qpid/test/framework/localcircuit/CircuitImpl.java394
-rw-r--r--java/systests/src/main/java/org/apache/qpid/test/framework/localcircuit/PublisherImpl.java162
-rw-r--r--java/systests/src/main/java/org/apache/qpid/test/framework/localcircuit/ReceiverImpl.java90
-rw-r--r--java/systests/src/main/java/org/apache/qpid/test/framework/package.html22
-rw-r--r--java/systests/src/main/java/org/apache/qpid/test/framework/sequencers/BaseDistributedTestSequencer.java129
-rw-r--r--java/systests/src/main/java/org/apache/qpid/test/framework/sequencers/DistributedTestSequencer.java75
-rw-r--r--java/systests/src/main/java/org/apache/qpid/test/framework/sequencers/FanOutTestSequencer.java171
-rw-r--r--java/systests/src/main/java/org/apache/qpid/test/framework/sequencers/InteropTestSequencer.java137
-rw-r--r--java/systests/src/main/java/org/apache/qpid/test/framework/sequencers/TestCaseSequencer.java66
-rw-r--r--java/systests/src/main/java/org/apache/qpid/util/ClasspathScanner.java (renamed from java/integrationtests/src/main/java/org/apache/qpid/util/ClasspathScanner.java)0
-rw-r--r--java/systests/src/main/java/org/apache/qpid/util/ConversationFactory.java (renamed from java/integrationtests/src/main/java/org/apache/qpid/util/ConversationFactory.java)0
-rw-r--r--java/tasks/src/org/apache/qpid/tasks/BaseTask.java74
-rw-r--r--java/tasks/src/org/apache/qpid/tasks/Foreach.java84
-rw-r--r--java/tasks/src/org/apache/qpid/tasks/Map.java94
-rw-r--r--java/tasks/src/org/apache/qpid/tasks/Require.java80
187 files changed, 11998 insertions, 4603 deletions
diff --git a/java/integrationtests/src/resources/org/apache/qpid/interop/connection.properties b/java/broker/bin/msTool.sh
index a5fb611dfa..4d55ee7811 100644..100755
--- a/java/integrationtests/src/resources/org/apache/qpid/interop/connection.properties
+++ b/java/broker/bin/msTool.sh
@@ -1,20 +1,56 @@
-#
-# Licensed to the Apache Software Foundation (ASF) under one
-# or more contributor license agreements. See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership. The ASF licenses this file
-# to you under the Apache License, Version 2.0 (the
-# "License"); you may not use this file except in compliance
-# with the License. You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing,
-# software distributed under the License is distributed on an
-# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-# KIND, either express or implied. See the License for the
-# specific language governing permissions and limitations
-# under the License.
-#
-java.naming.factory.initial = org.apache.qpid.jndi.PropertiesFileInitialContextFactory
-connectionfactory.broker = amqp://guest:guest@clientid/?brokerlist='tcp://localhost:5672'
+#!/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.
+#
+
+# Set classpath to include Qpid jar with all required jars in manifest
+QPID_LIBS=$QPID_TOOLS/lib/qpid-incubating.jar
+
+die() {
+ if [[ $1 = -usage ]]; then
+ shift
+ usage=true
+ else
+ usage=false
+ fi
+ echo "$@"
+ $usage && echo
+ $usage && usage
+ exit 1
+}
+
+cygwin=false
+if [[ "$(uname -a | fgrep Cygwin)" != "" ]]; then
+ cygwin=true
+fi
+
+if $cygwin; then
+ QPID_TOOLS=$(cygpath -w $QPID_TOOLS)
+fi
+
+# Set other variables used by the qpid-run script before calling
+export JAVA=java \
+ JAVA_VM=-server \
+ JAVA_OPTS=-Dlog4j.configuration=file:$QPID_TOOLS/etc/mstool-log4j.xml \
+ QPID_CLASSPATH=$QPID_LIBS
+
+if [ -z "$QPID_TOOLS" ]; then
+ die "QPID_TOOLS be set"
+fi
+
+. qpid-run org.apache.qpid.tools.messagestore.MessageStoreTool "$@"
diff --git a/java/broker/bin/qpid-passwd b/java/broker/bin/qpid-passwd
index 6e64af6e70..f046252522 100644
--- a/java/broker/bin/qpid-passwd
+++ b/java/broker/bin/qpid-passwd
@@ -27,4 +27,4 @@ export JAVA=java \
JAVA_MEM=-Xmx1024m \
QPID_CLASSPATH=$QPID_LIBS
-. qpid-run org.apache.qpid.server.security.Passwd "$@"
+. qpid-run org.apache.qpid.tools.security.Passwd "$@"
diff --git a/java/broker/bin/qpid-server b/java/broker/bin/qpid-server
index 76d0ad786d..fabf7e941c 100644
--- a/java/broker/bin/qpid-server
+++ b/java/broker/bin/qpid-server
@@ -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
@@ -25,7 +25,7 @@ QPID_LIBS=$QPID_HOME/lib/qpid-incubating.jar:$QPID_HOME/lib/bdbstore-launch.jar
export JAVA=java \
JAVA_VM=-server \
JAVA_MEM=-Xmx1024m \
- JAVA_GC=-XX:-UseConcMarkSweepGC
+ JAVA_GC=-XX:-UseConcMarkSweepGC \
QPID_CLASSPATH=$QPID_LIBS
. qpid-run org.apache.qpid.server.Main "$@"
diff --git a/java/broker/distribution/src/main/assembly/broker-bin.xml b/java/broker/distribution/src/main/assembly/broker-bin.xml
index 4b32630771..e66190a3f4 100644
--- a/java/broker/distribution/src/main/assembly/broker-bin.xml
+++ b/java/broker/distribution/src/main/assembly/broker-bin.xml
@@ -114,9 +114,9 @@
<fileMode>473</fileMode>
</file>
<file>
- <source>../bin/passwd</source>
+ <source>../bin/qpid-passwd</source>
<outputDirectory>qpid-${qpid.version}/bin</outputDirectory>
- <destName>passwd</destName>
+ <destName>qpid-passwd</destName>
<fileMode>473</fileMode>
</file>
<file>
diff --git a/java/broker/etc/debug.log4j.xml b/java/broker/etc/debug.log4j.xml
new file mode 100644
index 0000000000..e8fd7e119d
--- /dev/null
+++ b/java/broker/etc/debug.log4j.xml
@@ -0,0 +1,114 @@
+<?xml version="1.0"?>
+<!--
+ -
+ - Licensed to the Apache Software Foundation (ASF) under one
+ - or more contributor license agreements. See the NOTICE file
+ - distributed with this work for additional information
+ - regarding copyright ownership. The ASF licenses this file
+ - to you under the Apache License, Version 2.0 (the
+ - "License"); you may not use this file except in compliance
+ - with the License. You may obtain a copy of the License at
+ -
+ - http://www.apache.org/licenses/LICENSE-2.0
+ -
+ - Unless required by applicable law or agreed to in writing,
+ - software distributed under the License is distributed on an
+ - "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ - KIND, either express or implied. See the License for the
+ - specific language governing permissions and limitations
+ - under the License.
+ -
+ -->
+<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
+<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/">
+ <appender name="ArchivingFileAppender" class="org.apache.log4j.QpidCompositeRollingAppender">
+ <!-- Ensure that logs allways have the dateFormat set-->
+ <param name="StaticLogFileName" value="false"/>
+ <param name="File" value="${QPID_WORK}/log/${logprefix}qpid${logsuffix}.log"/>
+ <param name="Append" value="false"/>
+ <!-- Change the direction so newer files have bigger numbers -->
+ <!-- So log.1 is written then log.2 etc This prevents a lot of file renames at log rollover -->
+ <param name="CountDirection" value="1"/>
+ <!-- Use default 10MB -->
+ <!--param name="MaxFileSize" value="100000"/-->
+ <param name="DatePattern" value="'.'yyyy-MM-dd-HH-mm"/>
+ <!-- Unlimited number of backups -->
+ <param name="MaxSizeRollBackups" value="-1"/>
+ <!-- Compress(gzip) the backup files-->
+ <param name="CompressBackupFiles" value="true"/>
+ <!-- Compress the backup files using a second thread -->
+ <param name="CompressAsync" value="true"/>
+ <!-- Start at zero numbered files-->
+ <param name="ZeroBased" value="true"/>
+ <!-- Backup Location -->
+ <param name="backupFilesToPath" value="${QPID_WORK}/backup/log"/>
+
+ <layout class="org.apache.log4j.PatternLayout">
+ <param name="ConversionPattern" value="%d %-5p [%t] %C{2} (%F:%L) - %m%n"/>
+ </layout>
+ </appender>
+
+ <appender name="FileAppender" class="org.apache.log4j.FileAppender">
+ <param name="File" value="${QPID_WORK}/log/${logprefix}qpid${logsuffix}.log"/>
+ <param name="Append" value="false"/>
+
+ <layout class="org.apache.log4j.PatternLayout">
+ <param name="ConversionPattern" value="%d %-5p [%t] %C{2} (%F:%L) - %m%n"/>
+ </layout>
+ </appender>
+
+ <appender name="AlertFile" class="org.apache.log4j.FileAppender">
+ <param name="File" value="${QPID_WORK}/log/alert.log"/>
+ <param name="Append" value="false"/>
+
+ <layout class="org.apache.log4j.PatternLayout">
+ <param name="ConversionPattern" value="%d %-5p [%t] %C{2} (%F:%L) - %m%n"/>
+ </layout>
+ </appender>
+
+ <appender name="STDOUT" class="org.apache.log4j.ConsoleAppender">
+
+ <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">
+ <priority value="debug"/>
+ <appender-ref ref="AlertFile"/>
+ <!--appender-ref ref="STDOUT"/-->
+ </category>
+
+
+ <category 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">
+ <priority value="warn"/>
+ <appender-ref ref="STDOUT"/>
+ </category-->
+
+
+ <!-- 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">
+ <priority value="debug"/>
+ </category>-->
+
+ <!--<category name="org.apache.qpid.server.store">
+ <priority value="debug"/>
+ </category-->
+
+ <!-- Log all info events to file -->
+ <root>
+ <priority value="info"/>
+ <appender-ref ref="STDOUT"/>
+ <appender-ref ref="FileAppender"/>
+ </root>
+
+</log4j:configuration>
diff --git a/java/broker/etc/log4j.xml b/java/broker/etc/log4j.xml
index 2fb7b80c96..2060246b7f 100644
--- a/java/broker/etc/log4j.xml
+++ b/java/broker/etc/log4j.xml
@@ -44,7 +44,7 @@
<param name="backupFilesToPath" value="${QPID_WORK}/backup/log"/>
<layout class="org.apache.log4j.PatternLayout">
- <param name="ConversionPattern" value="%d %-5p [%t] %C{2} (%F:%L) - %m%n"/>
+ <param name="ConversionPattern" value="%d %-5p [%t] %C{2} (%F:%L) - %m%n"/>
</layout>
</appender>
@@ -57,6 +57,15 @@
</layout>
</appender>
+ <appender name="AlertFile" class="org.apache.log4j.FileAppender">
+ <param name="File" value="${QPID_WORK}/log/alert.log"/>
+ <param name="Append" value="false"/>
+
+ <layout class="org.apache.log4j.PatternLayout">
+ <param name="ConversionPattern" value="%d %-5p [%t] %C{2} (%F:%L) - %m%n"/>
+ </layout>
+ </appender>
+
<appender name="STDOUT" class="org.apache.log4j.ConsoleAppender">
<layout class="org.apache.log4j.PatternLayout">
@@ -64,15 +73,27 @@
</layout>
</appender>
- <category name="Qpid.Broker">
+ <category name="Qpid.Broker">
+ <priority value="debug"/>
+ <appender-ref ref="AlertFile"/>
+ </category>
+
+ <category 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">
+ <priority value="warn"/>
+ <appender-ref ref="STDOUT"/>
</category>
- <!--<category name="org.apache.qpid.server.store">
- <priority value="debug"/>
- </category-->
- <!--category name="org.apache.qpid.server.queue">
+ <!-- Examples of additional logging settings -->
+ <!-- Used to generate extra debug. See debug.log4j.xml -->
+
+ <!--<category name="org.apache.qpid.server.store">
<priority value="debug"/>
</category-->
@@ -80,10 +101,11 @@
<priority value="debug"/>
</category>-->
+ <!-- Log all info events to file -->
<root>
<priority value="info"/>
- <appender-ref ref="STDOUT"/>
<appender-ref ref="FileAppender"/>
<!--appender-ref ref="ArchivingFileAppender"/-->
</root>
+
</log4j:configuration>
diff --git a/java/broker/etc/messagestoretool-log4j.xml b/java/broker/etc/messagestoretool-log4j.xml
new file mode 100644
index 0000000000..0313de4f95
--- /dev/null
+++ b/java/broker/etc/messagestoretool-log4j.xml
@@ -0,0 +1,53 @@
+<?xml version="1.0"?>
+<!--
+ -
+ - Licensed to the Apache Software Foundation (ASF) under one
+ - or more contributor license agreements. See the NOTICE file
+ - distributed with this work for additional information
+ - regarding copyright ownership. The ASF licenses this file
+ - to you under the Apache License, Version 2.0 (the
+ - "License"); you may not use this file except in compliance
+ - with the License. You may obtain a copy of the License at
+ -
+ - http://www.apache.org/licenses/LICENSE-2.0
+ -
+ - Unless required by applicable law or agreed to in writing,
+ - software distributed under the License is distributed on an
+ - "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ - KIND, either express or implied. See the License for the
+ - specific language governing permissions and limitations
+ - under the License.
+ -
+ -->
+<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
+<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/">
+
+ <appender name="STDOUT" class="org.apache.log4j.ConsoleAppender">
+
+ <layout class="org.apache.log4j.PatternLayout">
+ <param name="ConversionPattern" value="%d %-5p [%t] %C{2} (%F:%L) - %m%n"/>
+ </layout>
+ </appender>
+
+ <category name="org.apache.qpid.tools">
+ <priority value="info"/>
+ </category>
+
+ <category name="org.apache.qpid">
+ <priority value="info"/>
+ </category>
+
+ <category name="org.apache.qpid.server.security">
+ <priority value="info"/>
+ </category>
+
+ <category name="org.apache.qpid.server.management">
+ <priority value="error"/>
+ </category>
+
+
+ <root>
+ <priority value="info"/>
+ <appender-ref ref="STDOUT"/>
+ </root>
+</log4j:configuration>
diff --git a/java/broker/etc/mstool-log4j.xml b/java/broker/etc/mstool-log4j.xml
new file mode 100644
index 0000000000..8c46010e2d
--- /dev/null
+++ b/java/broker/etc/mstool-log4j.xml
@@ -0,0 +1,54 @@
+<?xml version="1.0"?>
+<!--
+ -
+ - Licensed to the Apache Software Foundation (ASF) under one
+ - or more contributor license agreements. See the NOTICE file
+ - distributed with this work for additional information
+ - regarding copyright ownership. The ASF licenses this file
+ - to you under the Apache License, Version 2.0 (the
+ - "License"); you may not use this file except in compliance
+ - with the License. You may obtain a copy of the License at
+ -
+ - http://www.apache.org/licenses/LICENSE-2.0
+ -
+ - Unless required by applicable law or agreed to in writing,
+ - software distributed under the License is distributed on an
+ - "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ - KIND, either express or implied. See the License for the
+ - specific language governing permissions and limitations
+ - under the License.
+ -
+ -->
+<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
+<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/">
+
+ <appender name="STDOUT" class="org.apache.log4j.ConsoleAppender">
+
+ <layout class="org.apache.log4j.PatternLayout">
+ <!--param name="ConversionPattern" value="%d %-5p [%t] %C{2} (%F:%L) - %m%n"/-->
+ <param name="ConversionPattern" value="%d %-5p [%t] (%F:%L) - %m%n"/>
+ </layout>
+ </appender>
+
+ <category name="org.apache.qpid.tools">
+ <priority value="info"/>
+ </category>
+
+ <category name="org.apache.qpid">
+ <priority value="error"/>
+ </category>
+
+ <category name="org.apache.qpid.server.security">
+ <priority value="error"/>
+ </category>
+
+ <category name="org.apache.qpid.server.management">
+ <priority value="error"/>
+ </category>
+
+
+ <root>
+ <priority value="info"/>
+ <appender-ref ref="STDOUT"/>
+ </root>
+</log4j:configuration>
diff --git a/java/broker/pom.xml b/java/broker/pom.xml
index 81c5d22b22..35c29d504f 100644
--- a/java/broker/pom.xml
+++ b/java/broker/pom.xml
@@ -101,6 +101,25 @@
<build>
<plugins>
+
+
+ <!--plugin>
+ <artifactId>minijar-maven-plugin</artifactId>
+ <groupId>org.codehaus.mojo</groupId>
+ <executions>
+ <execution>
+ <phase>package</phase>
+ <goals>
+ <goal>minijars</goal>
+ </goals>
+ <configuration>
+ <stripUnusedClasses>true</stripUnusedClasses>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin-->
+
+
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-antrun-plugin</artifactId>
diff --git a/java/broker/src/main/java/org/apache/log4j/QpidCompositeRollingAppender.java b/java/broker/src/main/java/org/apache/log4j/QpidCompositeRollingAppender.java
index 931c15a664..7e0c4defe1 100644
--- a/java/broker/src/main/java/org/apache/log4j/QpidCompositeRollingAppender.java
+++ b/java/broker/src/main/java/org/apache/log4j/QpidCompositeRollingAppender.java
@@ -31,7 +31,6 @@ import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;
import java.util.concurrent.atomic.AtomicBoolean;
-import java.util.concurrent.atomic.AtomicInteger;
import java.util.zip.GZIPOutputStream;
import org.apache.log4j.helpers.CountingQuietWriter;
@@ -39,8 +38,6 @@ import org.apache.log4j.helpers.LogLog;
import org.apache.log4j.helpers.OptionConverter;
import org.apache.log4j.spi.LoggingEvent;
-import org.apache.qpid.framing.FieldTable;
-
/**
* <p>CompositeRollingAppender combines RollingFileAppender and DailyRollingFileAppender<br> It can function as either
* or do both at the same time (making size based rolling files like RollingFileAppender until a data/time boundary is
diff --git a/java/broker/src/main/java/org/apache/qpid/configuration/Configuration.java b/java/broker/src/main/java/org/apache/qpid/configuration/Configuration.java
new file mode 100644
index 0000000000..40ff590a0a
--- /dev/null
+++ b/java/broker/src/main/java/org/apache/qpid/configuration/Configuration.java
@@ -0,0 +1,188 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT 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.configuration;
+
+import org.apache.commons.cli.CommandLine;
+import org.apache.commons.cli.Option;
+import org.apache.commons.cli.Options;
+import org.apache.commons.cli.ParseException;
+import org.apache.commons.cli.PosixParser;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.File;
+
+public class Configuration
+{
+ public static final String QPID_HOME = "QPID_HOME";
+
+ final String QPIDHOME = System.getProperty(QPID_HOME);
+
+ private static Logger _devlog = LoggerFactory.getLogger(Configuration.class);
+
+ public static final String DEFAULT_LOG_CONFIG_FILENAME = "log4j.xml";
+ public static final String DEFAULT_CONFIG_FILE = "etc/config.xml";
+
+ protected final Options _options = new Options();
+ protected CommandLine _commandLine;
+ protected File _configFile;
+
+
+ public Configuration()
+ {
+
+ }
+
+ public void processCommandline(String[] args) throws InitException
+ {
+ try
+ {
+ _commandLine = new PosixParser().parse(_options, args);
+ }
+ catch (ParseException e)
+ {
+ throw new InitException("Unable to parse commmandline", e);
+ }
+
+ final File defaultConfigFile = new File(QPIDHOME, DEFAULT_CONFIG_FILE);
+ setConfig(new File(_commandLine.getOptionValue("c", defaultConfigFile.getPath())));
+ }
+
+ public void setConfig(File file)
+ {
+ _configFile = file;
+ }
+
+ /**
+ * @param option The option to set.
+ */
+ public void setOption(Option option)
+ {
+ _options.addOption(option);
+ }
+
+ /**
+ * getOptionValue from the configuration
+ * @param option variable argument, first string is option to get, second if present is the default value.
+ * @return the String for the given option or null if not present (if default value not specified)
+ */
+ public String getOptionValue(String... option)
+ {
+ if (option.length == 1)
+ {
+ return _commandLine.getOptionValue(option[0]);
+ }
+ else if (option.length == 2)
+ {
+ return _commandLine.getOptionValue(option[0], option[1]);
+ }
+ return null;
+ }
+
+ public void loadConfig(File file) throws InitException
+ {
+ setConfig(file);
+ loadConfig();
+ }
+
+ private void loadConfig() throws InitException
+ {
+ if (!_configFile.exists())
+ {
+ String error = "File " + _configFile + " could not be found. Check the file exists and is readable.";
+
+ if (QPIDHOME == null)
+ {
+ error = error + "\nNote: " + QPID_HOME + " is not set.";
+ }
+
+ throw new InitException(error, null);
+ }
+ else
+ {
+ _devlog.debug("Using configuration file " + _configFile.getAbsolutePath());
+ }
+
+// String logConfig = _commandLine.getOptionValue("l");
+// String logWatchConfig = _commandLine.getOptionValue("w", "0");
+// if (logConfig != null)
+// {
+// File logConfigFile = new File(logConfig);
+// configureLogging(logConfigFile, logWatchConfig);
+// }
+// else
+// {
+// File configFileDirectory = _configFile.getParentFile();
+// File logConfigFile = new File(configFileDirectory, DEFAULT_LOG_CONFIG_FILENAME);
+// configureLogging(logConfigFile, logWatchConfig);
+// }
+ }
+
+
+// private void configureLogging(File logConfigFile, String logWatchConfig)
+// {
+// int logWatchTime = 0;
+// try
+// {
+// logWatchTime = Integer.parseInt(logWatchConfig);
+// }
+// catch (NumberFormatException e)
+// {
+// _devlog.error("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())
+// {
+// _devlog.info("Configuring logger using configuration file " + logConfigFile.getAbsolutePath());
+// if (logWatchTime > 0)
+// {
+// _devlog.info("log file " + logConfigFile.getAbsolutePath() + " will be checked for changes every "
+// + logWatchTime + " seconds");
+// // log4j expects the watch interval in milliseconds
+// DOMConfigurator.configureAndWatch(logConfigFile.getAbsolutePath(), logWatchTime * 1000);
+// }
+// else
+// {
+// DOMConfigurator.configure(logConfigFile.getAbsolutePath());
+// }
+// }
+// else
+// {
+// System.err.println("Logging configuration error: unable to read file " + logConfigFile.getAbsolutePath());
+// System.err.println("Using basic log4j configuration");
+// BasicConfigurator.configure();
+// }
+// }
+
+ public File getConfigFile()
+ {
+ return _configFile;
+ }
+
+
+ public class InitException extends Exception
+ {
+ InitException(String msg, Throwable cause)
+ {
+ super(msg, cause);
+ }
+ }
+} \ No newline at end of file
diff --git a/java/broker/src/main/java/org/apache/qpid/server/AMQChannel.java b/java/broker/src/main/java/org/apache/qpid/server/AMQChannel.java
index 28a9e85489..7f14946834 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/AMQChannel.java
+++ b/java/broker/src/main/java/org/apache/qpid/server/AMQChannel.java
@@ -582,9 +582,9 @@ public class AMQChannel
final List<UnacknowledgedMessage> msgToRequeue = new LinkedList<UnacknowledgedMessage>();
final List<UnacknowledgedMessage> msgToResend = new LinkedList<UnacknowledgedMessage>();
- if (_log.isInfoEnabled())
+ if (_log.isDebugEnabled())
{
- _log.info("unacked map Size:" + _unacknowledgedMessageMap.size());
+ _log.debug("unacked map Size:" + _unacknowledgedMessageMap.size());
}
// Process the Unacked-Map.
@@ -640,15 +640,15 @@ public class AMQChannel
});
// Process Messages to Resend
- if (_log.isInfoEnabled())
+ if (_log.isDebugEnabled())
{
if (!msgToResend.isEmpty())
{
- _log.info("Preparing (" + msgToResend.size() + ") message to resend.");
+ _log.debug("Preparing (" + msgToResend.size() + ") message to resend.");
}
else
{
- _log.info("No message to resend.");
+ _log.debug("No message to resend.");
}
}
diff --git a/java/broker/src/main/java/org/apache/qpid/server/Main.java b/java/broker/src/main/java/org/apache/qpid/server/Main.java
index 29ea69caf7..dd6546585f 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/Main.java
+++ b/java/broker/src/main/java/org/apache/qpid/server/Main.java
@@ -34,6 +34,7 @@ import org.apache.commons.cli.OptionBuilder;
import org.apache.commons.cli.Options;
import org.apache.commons.cli.ParseException;
import org.apache.commons.cli.PosixParser;
+import org.apache.commons.configuration.Configuration;
import org.apache.commons.configuration.ConfigurationException;
import org.apache.log4j.BasicConfigurator;
import org.apache.log4j.Logger;
@@ -48,6 +49,7 @@ 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.protocol.AMQPFastProtocolHandler;
import org.apache.qpid.server.protocol.AMQPProtocolProvider;
import org.apache.qpid.server.registry.ApplicationRegistry;
@@ -55,11 +57,19 @@ 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.
*
*/
-@SuppressWarnings({ "AccessStaticViaInstance" })
+@SuppressWarnings({"AccessStaticViaInstance"})
public class Main
{
/** Used for debugging. */
@@ -133,6 +143,12 @@ public class Main
OptionBuilder.withArgName("port").hasArg()
.withDescription("listen on the specified port. Overrides any value in the config file")
.withLongOpt("port").create("p");
+ Option mport =
+ OptionBuilder.withArgName("mport").hasArg()
+ .withDescription("listen on the specified management port. Overrides any value in the config file")
+ .withLongOpt("mport").create("m");
+
+
Option bind =
OptionBuilder.withArgName("bind").hasArg()
.withDescription("bind to the specified address. Overrides any value in the config file")
@@ -153,6 +169,7 @@ public class Main
options.addOption(logconfig);
options.addOption(logwatchconfig);
options.addOption(port);
+ options.addOption(mport);
options.addOption(bind);
}
@@ -203,15 +220,19 @@ public class Main
catch (InitException e)
{
System.out.println(e.getMessage());
+ _brokerLogger.error("Initialisation Error : " + e.getMessage());
+
}
catch (ConfigurationException e)
{
System.out.println("Error configuring message broker: " + e);
+ _brokerLogger.error("Error configuring message broker: " + e);
e.printStackTrace();
}
catch (Exception e)
{
System.out.println("Error intialising message broker: " + e);
+ _brokerLogger.error("Error intialising message broker: " + e);
e.printStackTrace();
}
}
@@ -260,7 +281,15 @@ public class Main
configureLogging(logConfigFile, logWatchConfig);
}
- ApplicationRegistry.initialise(new ConfigurationFileApplicationRegistry(configFile));
+ ConfigurationFileApplicationRegistry config = new ConfigurationFileApplicationRegistry(configFile);
+
+
+ updateManagementPort(config.getConfiguration(), commandLine.getOptionValue("m"));
+
+
+
+ ApplicationRegistry.initialise(config);
+
// 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
@@ -318,6 +347,29 @@ public class Main
bind(port, connectorConfig);
}
+ /**
+ * Update the configuration data with the management port.
+ * @param configuration
+ * @param managementPort The string from the command line
+ */
+ private void updateManagementPort(Configuration 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);
+ }
+ 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
{
diff --git a/java/broker/src/main/java/org/apache/qpid/server/exchange/AbstractExchange.java b/java/broker/src/main/java/org/apache/qpid/server/exchange/AbstractExchange.java
index 868ac31a54..9ebb893362 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/exchange/AbstractExchange.java
+++ b/java/broker/src/main/java/org/apache/qpid/server/exchange/AbstractExchange.java
@@ -38,9 +38,13 @@ 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;
@@ -189,6 +193,8 @@ public abstract class AbstractExchange implements Exchange, Managable
}
}
+ abstract public Map<AMQShortString, List<AMQQueue>> getBindings();
+
public String toString()
{
return getClass().getName() + "[" + getName() +"]";
diff --git a/java/broker/src/main/java/org/apache/qpid/server/exchange/DefaultExchangeRegistry.java b/java/broker/src/main/java/org/apache/qpid/server/exchange/DefaultExchangeRegistry.java
index f3bdecc32e..377a73dd31 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/exchange/DefaultExchangeRegistry.java
+++ b/java/broker/src/main/java/org/apache/qpid/server/exchange/DefaultExchangeRegistry.java
@@ -20,18 +20,20 @@
*/
package org.apache.qpid.server.exchange;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.ConcurrentMap;
-
import org.apache.log4j.Logger;
import org.apache.qpid.AMQException;
import org.apache.qpid.framing.AMQShortString;
import org.apache.qpid.server.protocol.ExchangeInitialiser;
import org.apache.qpid.server.queue.AMQMessage;
+import org.apache.qpid.server.store.MessageStore;
import org.apache.qpid.server.virtualhost.VirtualHost;
import org.apache.qpid.server.messageStore.MessageStore;
import org.apache.qpid.server.exception.InternalErrorException;
+import java.util.Collection;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+
public class DefaultExchangeRegistry implements ExchangeRegistry
{
private static final Logger _log = Logger.getLogger(DefaultExchangeRegistry.class);
@@ -64,7 +66,7 @@ public class DefaultExchangeRegistry implements ExchangeRegistry
public void registerExchange(Exchange exchange) throws AMQException
{
_exchangeMap.put(exchange.getName(), exchange);
- if(exchange.isDurable())
+ if (exchange.isDurable())
{
try
{
@@ -86,13 +88,18 @@ public class DefaultExchangeRegistry implements ExchangeRegistry
return _defaultExchange;
}
+ public Collection<AMQShortString> getExchangeNames()
+ {
+ return _exchangeMap.keySet();
+ }
+
public void unregisterExchange(AMQShortString name, boolean inUse) throws AMQException
{
// TODO: check inUse argument
Exchange e = _exchangeMap.remove(name);
if (e != null)
{
- if(e.isDurable())
+ if (e.isDurable())
{
try
{
@@ -112,7 +119,7 @@ public class DefaultExchangeRegistry implements ExchangeRegistry
public Exchange getExchange(AMQShortString name)
{
- if((name == null) || name.length() == 0)
+ if ((name == null) || name.length() == 0)
{
return getDefaultExchange();
}
diff --git a/java/broker/src/main/java/org/apache/qpid/server/exchange/DestNameExchange.java b/java/broker/src/main/java/org/apache/qpid/server/exchange/DestNameExchange.java
index 0dcceaddbb..c24f9a37e1 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/exchange/DestNameExchange.java
+++ b/java/broker/src/main/java/org/apache/qpid/server/exchange/DestNameExchange.java
@@ -26,22 +26,16 @@ import java.util.Map;
import javax.management.JMException;
import javax.management.MBeanException;
-import javax.management.openmbean.ArrayType;
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 org.apache.log4j.Logger;
import org.apache.qpid.AMQException;
import org.apache.qpid.exchange.ExchangeDefaults;
import org.apache.qpid.framing.AMQShortString;
-import org.apache.qpid.framing.BasicPublishBody;
import org.apache.qpid.framing.FieldTable;
import org.apache.qpid.framing.abstraction.MessagePublishInfo;
import org.apache.qpid.server.management.MBeanConstructor;
@@ -222,4 +216,9 @@ public class DestNameExchange extends AbstractExchange
{
return !_index.getBindingsMap().isEmpty();
}
+
+ public Map<AMQShortString, List<AMQQueue>> getBindings()
+ {
+ return _index.getBindingsMap();
+ }
}
diff --git a/java/broker/src/main/java/org/apache/qpid/server/exchange/DestWildExchange.java b/java/broker/src/main/java/org/apache/qpid/server/exchange/DestWildExchange.java
index f6a95b5e55..e1a3a24d3e 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/exchange/DestWildExchange.java
+++ b/java/broker/src/main/java/org/apache/qpid/server/exchange/DestWildExchange.java
@@ -21,11 +21,9 @@
package org.apache.qpid.server.exchange;
import org.apache.log4j.Logger;
-
import org.apache.qpid.AMQException;
import org.apache.qpid.exchange.ExchangeDefaults;
import org.apache.qpid.framing.AMQShortString;
-import org.apache.qpid.framing.BasicPublishBody;
import org.apache.qpid.framing.FieldTable;
import org.apache.qpid.framing.abstraction.MessagePublishInfo;
import org.apache.qpid.server.management.MBeanConstructor;
@@ -35,17 +33,11 @@ import org.apache.qpid.server.queue.AMQQueue;
import javax.management.JMException;
import javax.management.MBeanException;
-import javax.management.openmbean.ArrayType;
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 java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
@@ -59,7 +51,7 @@ public class DestWildExchange extends AbstractExchange
private static final Logger _logger = Logger.getLogger(DestWildExchange.class);
private ConcurrentHashMap<AMQShortString, List<AMQQueue>> _routingKey2queues =
- new ConcurrentHashMap<AMQShortString, List<AMQQueue>>();
+ new ConcurrentHashMap<AMQShortString, List<AMQQueue>>();
// private ConcurrentHashMap<AMQShortString, AMQQueue> _routingKey2queue = new ConcurrentHashMap<AMQShortString, AMQQueue>();
private static final String TOPIC_SEPARATOR = ".";
private static final String AMQP_STAR = "*";
@@ -92,7 +84,7 @@ public class DestWildExchange extends AbstractExchange
queueList.add(q.getName().toString());
}
- Object[] bindingItemValues = { key.toString(), queueList.toArray(new String[0]) };
+ Object[] bindingItemValues = {key.toString(), queueList.toArray(new String[0])};
CompositeData bindingData = new CompositeDataSupport(_bindingDataType, _bindingItemNames, bindingItemValues);
_bindingList.put(bindingData);
}
@@ -311,6 +303,11 @@ public class DestWildExchange extends AbstractExchange
}
}
+ public Map<AMQShortString, List<AMQQueue>> getBindings()
+ {
+ return _routingKey2queues;
+ }
+
private List<AMQQueue> getMatchedQueues(AMQShortString routingKey)
{
List<AMQQueue> list = new LinkedList<AMQQueue>();
@@ -358,8 +355,8 @@ public class DestWildExchange extends AbstractExchange
if (queueList.size() > (depth + queueskip))
{ // a hash and it is the last entry
matching =
- queueList.get(depth + queueskip).equals(AMQP_HASH)
- && (queueList.size() == (depth + queueskip + 1));
+ queueList.get(depth + queueskip).equals(AMQP_HASH)
+ && (queueList.size() == (depth + queueskip + 1));
}
}
else if (routingkeyList.size() > (depth + routingskip))
diff --git a/java/broker/src/main/java/org/apache/qpid/server/exchange/Exchange.java b/java/broker/src/main/java/org/apache/qpid/server/exchange/Exchange.java
index a5f77cc2a4..37cd85a8f8 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/exchange/Exchange.java
+++ b/java/broker/src/main/java/org/apache/qpid/server/exchange/Exchange.java
@@ -27,9 +27,13 @@ import org.apache.qpid.server.queue.AMQMessage;
import org.apache.qpid.server.queue.AMQQueue;
import org.apache.qpid.server.virtualhost.VirtualHost;
+import java.util.List;
+import java.util.Map;
+
public interface Exchange
{
AMQShortString getName();
+
AMQShortString getType();
void initialise(VirtualHost host, AMQShortString name, boolean durable, int ticket, boolean autoDelete) throws AMQException;
@@ -51,6 +55,17 @@ public interface Exchange
void route(AMQMessage message) throws AMQException;
+
+ /**
+ * Determines whether a message would be isBound to a particular queue using a specific routing key and arguments
+ * @param routingKey
+ * @param arguments
+ * @param queue
+ * @return
+ * @throws AMQException
+ */
+ boolean isBound(AMQShortString routingKey, FieldTable arguments, AMQQueue queue);
+
/**
* Determines whether a message would be isBound to a particular queue using a specific routing key
* @param routingKey
@@ -58,22 +73,25 @@ public interface Exchange
* @return
* @throws AMQException
*/
- boolean isBound(AMQShortString routingKey, AMQQueue queue) throws AMQException;
+ boolean isBound(AMQShortString routingKey, AMQQueue queue);
/**
- * Determines whether a message is routing to any queue using a specific routing key
+ * Determines whether a message is routing to any queue using a specific _routing key
* @param routingKey
* @return
* @throws AMQException
*/
- boolean isBound(AMQShortString routingKey) throws AMQException;
+ boolean isBound(AMQShortString routingKey);
- boolean isBound(AMQQueue queue) throws AMQException;
+ boolean isBound(AMQQueue queue);
/**
* Returns true if this exchange has at least one binding associated with it.
* @return
* @throws AMQException
*/
- boolean hasBindings() throws AMQException;
+ boolean hasBindings();
+
+ Map<AMQShortString, List<AMQQueue>> getBindings();
+
}
diff --git a/java/broker/src/main/java/org/apache/qpid/server/exchange/ExchangeRegistry.java b/java/broker/src/main/java/org/apache/qpid/server/exchange/ExchangeRegistry.java
index d3a466565f..fe3b19e74e 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/exchange/ExchangeRegistry.java
+++ b/java/broker/src/main/java/org/apache/qpid/server/exchange/ExchangeRegistry.java
@@ -23,6 +23,8 @@ package org.apache.qpid.server.exchange;
import org.apache.qpid.AMQException;
import org.apache.qpid.framing.AMQShortString;
+import java.util.Collection;
+
public interface ExchangeRegistry extends MessageRouter
{
@@ -43,5 +45,7 @@ public interface ExchangeRegistry extends MessageRouter
Exchange getDefaultExchange();
+ Collection<AMQShortString> getExchangeNames();
+
void initialise() throws AMQException;
}
diff --git a/java/broker/src/main/java/org/apache/qpid/server/exchange/FanoutExchange.java b/java/broker/src/main/java/org/apache/qpid/server/exchange/FanoutExchange.java
index bf00eeb9d3..1a705248c1 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/exchange/FanoutExchange.java
+++ b/java/broker/src/main/java/org/apache/qpid/server/exchange/FanoutExchange.java
@@ -21,7 +21,6 @@
package org.apache.qpid.server.exchange;
import org.apache.log4j.Logger;
-
import org.apache.qpid.AMQException;
import org.apache.qpid.exchange.ExchangeDefaults;
import org.apache.qpid.framing.AMQShortString;
@@ -34,17 +33,13 @@ import org.apache.qpid.server.queue.AMQQueue;
import javax.management.JMException;
import javax.management.MBeanException;
-import javax.management.openmbean.ArrayType;
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 java.util.List;
+import java.util.Map;
import java.util.concurrent.CopyOnWriteArraySet;
public class FanoutExchange extends AbstractExchange
@@ -79,7 +74,7 @@ public class FanoutExchange extends AbstractExchange
{
String queueName = queue.getName().toString();
- Object[] bindingItemValues = { queueName, new String[] { queueName } };
+ Object[] bindingItemValues = {queueName, new String[]{queueName}};
CompositeData bindingData = new CompositeDataSupport(_bindingDataType, _bindingItemNames, bindingItemValues);
_bindingList.put(bindingData);
}
@@ -120,6 +115,11 @@ public class FanoutExchange extends AbstractExchange
}
}
+ public Map<AMQShortString, List<AMQQueue>> getBindings()
+ {
+ return null;
+ }
+
public AMQShortString getType()
{
return ExchangeDefaults.FANOUT_EXCHANGE_CLASS;
@@ -181,24 +181,29 @@ public class FanoutExchange extends AbstractExchange
}
}
- public boolean isBound(AMQShortString routingKey, AMQQueue queue) throws AMQException
+ public boolean isBound(AMQShortString routingKey, FieldTable arguments, AMQQueue queue)
+ {
+ return isBound(routingKey, queue);
+ }
+
+ public boolean isBound(AMQShortString routingKey, AMQQueue queue)
{
return _queues.contains(queue);
}
- public boolean isBound(AMQShortString routingKey) throws AMQException
+ public boolean isBound(AMQShortString routingKey)
{
return (_queues != null) && !_queues.isEmpty();
}
- public boolean isBound(AMQQueue queue) throws AMQException
+ public boolean isBound(AMQQueue queue)
{
return _queues.contains(queue);
}
- public boolean hasBindings() throws AMQException
+ public boolean hasBindings()
{
return !_queues.isEmpty();
}
diff --git a/java/broker/src/main/java/org/apache/qpid/server/exchange/HeadersExchange.java b/java/broker/src/main/java/org/apache/qpid/server/exchange/HeadersExchange.java
index e86094e26f..9bb1ee6a62 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/exchange/HeadersExchange.java
+++ b/java/broker/src/main/java/org/apache/qpid/server/exchange/HeadersExchange.java
@@ -20,23 +20,6 @@
*/
package org.apache.qpid.server.exchange;
-import java.util.ArrayList;
-import java.util.Iterator;
-import java.util.List;
-import java.util.concurrent.CopyOnWriteArrayList;
-
-import javax.management.JMException;
-import javax.management.openmbean.ArrayType;
-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 org.apache.log4j.Logger;
import org.apache.qpid.AMQException;
import org.apache.qpid.exchange.ExchangeDefaults;
@@ -50,6 +33,23 @@ import org.apache.qpid.server.management.MBeanDescription;
import org.apache.qpid.server.queue.AMQMessage;
import org.apache.qpid.server.queue.AMQQueue;
+import javax.management.JMException;
+import javax.management.openmbean.ArrayType;
+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 java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.CopyOnWriteArrayList;
+
/**
* An exchange that binds queues based on a set of required headers and header values
* and routes messages to these queues by matching the headers of the message against
@@ -91,13 +91,13 @@ public class HeadersExchange extends AbstractExchange
private final class HeadersExchangeMBean extends ExchangeMBean
{
@MBeanConstructor("Creates an MBean for AMQ Headers exchange")
- public HeadersExchangeMBean() throws JMException
+ public HeadersExchangeMBean() throws JMException
{
super();
_exchangeType = "headers";
init();
}
-
+
/**
* initialises the OpenType objects.
*/
@@ -113,7 +113,7 @@ public class HeadersExchange extends AbstractExchange
_bindingDataType = new CompositeType("Exchange Binding", "Queue name and header bindings",
_bindingItemNames, _bindingItemNames, _bindingItemTypes);
_bindinglistDataType = new TabularType("Exchange Bindings", "List of exchange bindings for " + getName(),
- _bindingDataType, _bindingItemIndexNames);
+ _bindingDataType, _bindingItemIndexNames);
}
public TabularData bindings() throws OpenDataException
@@ -169,7 +169,7 @@ public class HeadersExchange extends AbstractExchange
throw new JMException("Queue \"" + queueName + "\" is not registered with the exchange.");
}
- String[] bindings = binding.split(",");
+ String[] bindings = binding.split(",");
FieldTable bindingMap = new FieldTable();
for (int i = 0; i < bindings.length; i++)
{
@@ -241,17 +241,23 @@ public class HeadersExchange extends AbstractExchange
}
}
- public boolean isBound(AMQShortString routingKey, AMQQueue queue) throws AMQException
+ public boolean isBound(AMQShortString routingKey, FieldTable arguments, AMQQueue queue)
+ {
+ //fixme isBound here should take the arguements in to consideration.
+ return isBound(routingKey, queue);
+ }
+
+ public boolean isBound(AMQShortString routingKey, AMQQueue queue)
{
return isBound(queue);
}
- public boolean isBound(AMQShortString routingKey) throws AMQException
+ public boolean isBound(AMQShortString routingKey)
{
return hasBindings();
}
- public boolean isBound(AMQQueue queue) throws AMQException
+ public boolean isBound(AMQQueue queue)
{
for (Registration r : _bindings)
{
@@ -263,7 +269,7 @@ public class HeadersExchange extends AbstractExchange
return false;
}
- public boolean hasBindings() throws AMQException
+ public boolean hasBindings()
{
return !_bindings.isEmpty();
}
@@ -288,6 +294,11 @@ public class HeadersExchange extends AbstractExchange
}
}
+ public Map<AMQShortString, List<AMQQueue>> getBindings()
+ {
+ return null;
+ }
+
private static class Registration
{
private final HeadersBinding binding;
diff --git a/java/broker/src/main/java/org/apache/qpid/server/handler/BasicConsumeMethodHandler.java b/java/broker/src/main/java/org/apache/qpid/server/handler/BasicConsumeMethodHandler.java
index 9346eecbb2..ab4f2c4e64 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/handler/BasicConsumeMethodHandler.java
+++ b/java/broker/src/main/java/org/apache/qpid/server/handler/BasicConsumeMethodHandler.java
@@ -100,6 +100,12 @@ public class BasicConsumeMethodHandler implements StateAwareMethodListener<Basic
}
else
{
+
+ if (body.consumerTag != null)
+ {
+ body.consumerTag = body.consumerTag.intern();
+ }
+
try
{
AMQShortString consumerTag = channel.subscribeToQueue(body.consumerTag, queue, session, !body.noAck,
@@ -138,15 +144,15 @@ public class BasicConsumeMethodHandler implements StateAwareMethodListener<Basic
// If the above doesn't work then perhaps this is wrong too.
// throw body.getConnectionException(AMQConstant.NOT_ALLOWED,
// "Non-unique consumer tag, '" + body.consumerTag + "'");
- // AMQP version change: Hardwire the version to 0-8 (major=8, minor=0)
+ // AMQP version change: Hardwire the version to 0-8 (major=8, minor=0)
// TODO: Connect this to the session version obtained from ProtocolInitiation for this session.
// Be aware of possible changes to parameter order as versions change.
session.writeFrame(ConnectionCloseBody.createAMQFrame(channelId,
- (byte)8, (byte)0, // AMQP version (major, minor)
- BasicConsumeBody.getClazz((byte)8, (byte)0), // classId
- BasicConsumeBody.getMethod((byte)8, (byte)0), // methodId
- AMQConstant.NOT_ALLOWED.getCode(), // replyCode
- msg)); // replyText
+ (byte) 8, (byte) 0, // AMQP version (major, minor)
+ BasicConsumeBody.getClazz((byte) 8, (byte) 0), // classId
+ BasicConsumeBody.getMethod((byte) 8, (byte) 0), // methodId
+ AMQConstant.NOT_ALLOWED.getCode(), // replyCode
+ msg)); // replyText
}
catch (ExistingExclusiveSubscriptionException e)
{
diff --git a/java/broker/src/main/java/org/apache/qpid/server/handler/BasicPublishMethodHandler.java b/java/broker/src/main/java/org/apache/qpid/server/handler/BasicPublishMethodHandler.java
index 67ade0a744..68d4483df3 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/handler/BasicPublishMethodHandler.java
+++ b/java/broker/src/main/java/org/apache/qpid/server/handler/BasicPublishMethodHandler.java
@@ -67,6 +67,10 @@ public class BasicPublishMethodHandler implements StateAwareMethodListener<Basi
body.exchange = ExchangeDefaults.DEFAULT_EXCHANGE_NAME;
}
+ else
+ {
+ body.exchange = body.exchange.intern();
+ }
VirtualHost vHost = session.getVirtualHost();
Exchange e = vHost.getExchangeRegistry().getExchange(body.exchange);
// if the exchange does not exist we raise a channel exception
@@ -86,6 +90,11 @@ public class BasicPublishMethodHandler implements StateAwareMethodListener<Basi
throw body.getChannelNotFoundException(evt.getChannelId());
}
+ if(body.routingKey != null)
+ {
+ body.routingKey = body.routingKey.intern();
+ }
+
MessagePublishInfo info = session.getRegistry().getProtocolVersionMethodConverter().convertToInfo(body);
channel.setPublishFrame(info, session);
}
@@ -93,3 +102,4 @@ public class BasicPublishMethodHandler implements StateAwareMethodListener<Basi
}
+
diff --git a/java/broker/src/main/java/org/apache/qpid/server/handler/ConnectionStartOkMethodHandler.java b/java/broker/src/main/java/org/apache/qpid/server/handler/ConnectionStartOkMethodHandler.java
index 5dbd1b18de..cd0d0e3b76 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/handler/ConnectionStartOkMethodHandler.java
+++ b/java/broker/src/main/java/org/apache/qpid/server/handler/ConnectionStartOkMethodHandler.java
@@ -35,6 +35,7 @@ import org.apache.qpid.protocol.AMQMethodEvent;
import org.apache.qpid.protocol.AMQConstant;
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;
@@ -72,7 +73,7 @@ public class ConnectionStartOkMethodHandler implements StateAwareMethodListener<
SaslServer ss = null;
try
- {
+ {
ss = authMgr.createSaslServer(String.valueOf(body.mechanism), session.getLocalFQDN());
if (ss == null)
diff --git a/java/broker/src/main/java/org/apache/qpid/server/handler/ExchangeBoundHandler.java b/java/broker/src/main/java/org/apache/qpid/server/handler/ExchangeBoundHandler.java
index f24c96f87f..0ff19bdf9e 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/handler/ExchangeBoundHandler.java
+++ b/java/broker/src/main/java/org/apache/qpid/server/handler/ExchangeBoundHandler.java
@@ -1,18 +1,21 @@
/*
*
- * Copyright (c) 2006 The Apache Software Foundation
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
*
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
+ * http://www.apache.org/licenses/LICENSE-2.0
*
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT 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.handler;
diff --git a/java/broker/src/main/java/org/apache/qpid/server/handler/ExchangeDeclareHandler.java b/java/broker/src/main/java/org/apache/qpid/server/handler/ExchangeDeclareHandler.java
index 855d1a2add..f0f6fde08c 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/handler/ExchangeDeclareHandler.java
+++ b/java/broker/src/main/java/org/apache/qpid/server/handler/ExchangeDeclareHandler.java
@@ -83,7 +83,9 @@ public class ExchangeDeclareHandler implements StateAwareMethodListener<Exchange
try
{
- exchange = exchangeFactory.createExchange(body.exchange, body.type, body.durable,
+ exchange = exchangeFactory.createExchange(body.exchange == null ? null : body.exchange.intern(),
+ body.type == null ? null : body.type.intern(),
+ body.durable,
body.passive, body.ticket);
exchangeRegistry.registerExchange(exchange);
}
diff --git a/java/broker/src/main/java/org/apache/qpid/server/handler/QueueBindHandler.java b/java/broker/src/main/java/org/apache/qpid/server/handler/QueueBindHandler.java
index 4dc67b1970..3e68069838 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/handler/QueueBindHandler.java
+++ b/java/broker/src/main/java/org/apache/qpid/server/handler/QueueBindHandler.java
@@ -28,6 +28,7 @@ import org.apache.qpid.framing.QueueBindBody;
import org.apache.qpid.framing.QueueBindOkBody;
import org.apache.qpid.protocol.AMQConstant;
import org.apache.qpid.protocol.AMQMethodEvent;
+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;
@@ -36,7 +37,6 @@ import org.apache.qpid.server.queue.QueueRegistry;
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;
public class QueueBindHandler implements StateAwareMethodListener<QueueBindBody>
{
@@ -77,7 +77,7 @@ public class QueueBindHandler implements StateAwareMethodListener<QueueBindBody>
{
throw body.getChannelException(AMQConstant.NOT_FOUND, "No default queue defined on channel and queue was null");
}
-
+
if (body.routingKey == null)
{
body.routingKey = queue.getName();
@@ -97,9 +97,18 @@ public class QueueBindHandler implements StateAwareMethodListener<QueueBindBody>
{
throw body.getChannelException(AMQConstant.NOT_FOUND, "Exchange " + body.exchange + " does not exist.");
}
+
+ if (body.routingKey != null)
+ {
+ body.routingKey = body.routingKey.intern();
+ }
+
try
- {
- queue.bind(body.routingKey, body.arguments, exch);
+ {
+ if (!exch.isBound(body.routingKey, body.arguments, queue))
+ {
+ queue.bind(body.routingKey, body.arguments, exch);
+ }
}
catch (AMQInvalidRoutingKeyException rke)
{
diff --git a/java/broker/src/main/java/org/apache/qpid/server/handler/QueueDeclareHandler.java b/java/broker/src/main/java/org/apache/qpid/server/handler/QueueDeclareHandler.java
index f9e94af697..28967841a2 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/handler/QueueDeclareHandler.java
+++ b/java/broker/src/main/java/org/apache/qpid/server/handler/QueueDeclareHandler.java
@@ -93,8 +93,15 @@ public class QueueDeclareHandler implements StateAwareMethodListener<QueueDeclar
synchronized (queueRegistry)
{
+
+
if (((queue = queueRegistry.getQueue(body.queue)) == null))
{
+ if(body.queue != null)
+ {
+ body.queue = body.queue.intern();
+ }
+
if (body.passive)
{
String msg = "Queue: " + body.queue + " not found on VirtualHost(" + virtualHost + ").";
diff --git a/java/broker/src/main/java/org/apache/qpid/server/management/JMXManagedObjectRegistry.java b/java/broker/src/main/java/org/apache/qpid/server/management/JMXManagedObjectRegistry.java
index f277398b50..4caae2b26f 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/management/JMXManagedObjectRegistry.java
+++ b/java/broker/src/main/java/org/apache/qpid/server/management/JMXManagedObjectRegistry.java
@@ -20,14 +20,14 @@
*/
package org.apache.qpid.server.management;
-import java.io.IOException;
-import java.lang.management.ManagementFactory;
-import java.rmi.RemoteException;
-import java.rmi.registry.LocateRegistry;
-import java.rmi.registry.Registry;
-import java.rmi.server.UnicastRemoteObject;
-import java.util.HashMap;
-import java.util.Map;
+import org.apache.log4j.Logger;
+import org.apache.qpid.AMQException;
+import org.apache.qpid.server.registry.ApplicationRegistry;
+import org.apache.qpid.server.registry.IApplicationRegistry;
+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.crammd5.CRAMMD5HashedInitialiser;
import javax.management.JMException;
import javax.management.MBeanServer;
@@ -43,17 +43,14 @@ import javax.security.auth.callback.PasswordCallback;
import javax.security.auth.callback.UnsupportedCallbackException;
import javax.security.auth.login.AccountNotFoundException;
import javax.security.sasl.AuthorizeCallback;
-
-import org.apache.log4j.Logger;
-
-import org.apache.qpid.AMQException;
-import org.apache.qpid.server.registry.ApplicationRegistry;
-import org.apache.qpid.server.registry.IApplicationRegistry;
-import org.apache.qpid.server.security.auth.database.PrincipalDatabase;
-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.sasl.UsernamePrincipal;
-import org.apache.qpid.server.security.auth.sasl.crammd5.CRAMMD5HashedInitialiser;
+import java.io.IOException;
+import java.lang.management.ManagementFactory;
+import java.rmi.RemoteException;
+import java.rmi.registry.LocateRegistry;
+import java.rmi.registry.Registry;
+import java.rmi.server.UnicastRemoteObject;
+import java.util.HashMap;
+import java.util.Map;
/**
* This class starts up an MBeanserver. If out of the box agent is being used then there are no security features
@@ -68,6 +65,9 @@ public class JMXManagedObjectRegistry implements ManagedObjectRegistry
private final MBeanServer _mbeanServer;
private Registry _rmiRegistry;
private JMXServiceURL _jmxURL;
+
+ public static final String MANAGEMENT_PORT_CONFIG_PATH = "management.jmxport";
+ public static final int MANAGEMENT_PORT_DEFAULT = 8999;
public JMXManagedObjectRegistry() throws AMQException
{
@@ -95,7 +95,7 @@ public class JMXManagedObjectRegistry implements ManagedObjectRegistry
IApplicationRegistry appRegistry = ApplicationRegistry.getInstance();
boolean security = appRegistry.getConfiguration().getBoolean("management.security-enabled", false);
- int port = appRegistry.getConfiguration().getInt("management.jmxport", 8999);
+ int port = appRegistry.getConfiguration().getInt(MANAGEMENT_PORT_CONFIG_PATH, MANAGEMENT_PORT_DEFAULT);
if (security)
{
@@ -144,13 +144,13 @@ public class JMXManagedObjectRegistry implements ManagedObjectRegistry
MBeanServerForwarder mbsf = MBeanInvocationHandlerImpl.newProxyInstance();
cs.setMBeanServerForwarder(mbsf);
cs.start();
- _log.warn("JMX: Started JMXConnector server with SASL");
+ _log.warn("JMX: Started JMXConnector server on port '" + port + "' with SASL");
}
else
{
startJMXConnectorServer(port);
- _log.warn("JMX: Started JMXConnector server with security disabled");
+ _log.warn("JMX: Started JMXConnector server on port '" + port + "' with security disabled");
}
}
diff --git a/java/broker/src/main/java/org/apache/qpid/server/management/MBeanInvocationHandlerImpl.java b/java/broker/src/main/java/org/apache/qpid/server/management/MBeanInvocationHandlerImpl.java
index 3ab23e8b46..4fb260472d 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/management/MBeanInvocationHandlerImpl.java
+++ b/java/broker/src/main/java/org/apache/qpid/server/management/MBeanInvocationHandlerImpl.java
@@ -1,18 +1,21 @@
/*
*
- * Copyright (c) 2006 The Apache Software Foundation
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
*
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
+ * http://www.apache.org/licenses/LICENSE-2.0
*
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT 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.management;
diff --git a/java/broker/src/main/java/org/apache/qpid/server/protocol/AMQPFastProtocolHandler.java b/java/broker/src/main/java/org/apache/qpid/server/protocol/AMQPFastProtocolHandler.java
index 84ec91d569..5c88edf86f 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/protocol/AMQPFastProtocolHandler.java
+++ b/java/broker/src/main/java/org/apache/qpid/server/protocol/AMQPFastProtocolHandler.java
@@ -44,6 +44,9 @@ 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.
@@ -80,7 +83,7 @@ public class AMQPFastProtocolHandler extends IoHandlerAdapter
final AMQCodecFactory codecFactory = new AMQCodecFactory(true);
createSession(protocolSession, _applicationRegistry, codecFactory);
- _logger.info("Protocol session created");
+ _logger.info("Protocol session created for:" + protocolSession.getRemoteAddress());
final ProtocolCodecFilter pcf = new ProtocolCodecFilter(codecFactory);
@@ -127,12 +130,12 @@ public class AMQPFastProtocolHandler extends IoHandlerAdapter
public void sessionOpened(IoSession protocolSession) throws Exception
{
- _logger.info("Session opened");
+ _logger.info("Session opened for:" + protocolSession.getRemoteAddress());
}
public void sessionClosed(IoSession protocolSession) throws Exception
{
- _logger.info("Protocol Session closed");
+ _logger.info("Protocol Session closed for:" + protocolSession.getRemoteAddress());
final AMQProtocolSession amqProtocolSession = AMQMinaProtocolSession.getAMQProtocolSession(protocolSession);
// fixme -- this can be null
if (amqProtocolSession != null)
@@ -143,7 +146,7 @@ public class AMQPFastProtocolHandler extends IoHandlerAdapter
public void sessionIdle(IoSession session, IdleStatus status) throws Exception
{
- _logger.debug("Protocol Session [" + this + "] idle: " + status);
+ _logger.debug("Protocol Session [" + this + "] idle: " + status + " :for:" + session.getRemoteAddress());
if (IdleStatus.WRITER_IDLE.equals(status))
{
// write heartbeat frame:
@@ -167,7 +170,7 @@ public class AMQPFastProtocolHandler extends IoHandlerAdapter
protocolSession.close();
- _logger.error("Error in protocol initiation " + session + ": " + throwable.getMessage(), throwable);
+ _logger.error("Error in protocol initiation " + session + ":" + protocolSession.getRemoteAddress() + " :" + throwable.getMessage(), throwable);
}
else if (throwable instanceof IOException)
{
@@ -178,13 +181,14 @@ public class AMQPFastProtocolHandler extends IoHandlerAdapter
_logger.error("Exception caught in" + session + ", closing session explictly: " + throwable, throwable);
// Be aware of possible changes to parameter order as versions change.
- protocolSession.write(ConnectionCloseBody.createAMQFrame(0, session.getProtocolMajorVersion(),
- session.getProtocolMinorVersion(), // AMQP version (major, minor)
- 0, // classId
- 0, // methodId
- 200, // replyCode
- new AMQShortString(throwable.getMessage()) // replyText
- ));
+ protocolSession.write(ConnectionCloseBody.createAMQFrame(0,
+ session.getProtocolMajorVersion(),
+ session.getProtocolMinorVersion(), // AMQP version (major, minor)
+ 0, // classId
+ 0, // methodId
+ 200, // replyCode
+ new AMQShortString(throwable.getMessage()) // replyText
+ ));
protocolSession.close();
}
}
diff --git a/java/broker/src/main/java/org/apache/qpid/server/queue/AMQMessage.java b/java/broker/src/main/java/org/apache/qpid/server/queue/AMQMessage.java
index 95f75fdb36..44634eb877 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/queue/AMQMessage.java
+++ b/java/broker/src/main/java/org/apache/qpid/server/queue/AMQMessage.java
@@ -53,6 +53,7 @@ import org.apache.qpid.server.txn.TransactionalContext;
*/
public class AMQMessage implements StorableMessage
{
+ /** Used for debugging purposes. */
private static final Logger _log = Logger.getLogger(AMQMessage.class);
// The ordered list of queues into which this message is enqueued.
@@ -76,19 +77,16 @@ public class AMQMessage implements StorableMessage
private AMQMessageHandle _messageHandle;
- // TODO: ideally this should be able to go into the transient message date - check this! (RG)
+ /** Holds the transactional context in which this message is being processed. */
private TransactionalContext _txnContext;
/**
- * Flag to indicate whether message has been delivered to a consumer. Used in implementing return functionality for
- * messages published with the 'immediate' flag.
+ * 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 boolean _deliveredToConsumer;
- /**
- * We need to keep track of whether the message was 'immediate' as in extreme circumstances, when the
- * checkDelieveredToConsumer is called, the message may already have been received and acknowledged, and the body
- * removed from the store.
- */
+
+ /** Flag to indicate that this message requires 'immediate' delivery. */
private boolean _immediate;
// private Subscription _takenBySubcription;
@@ -494,7 +492,7 @@ public class AMQMessage implements StorableMessage
*/
public AMQMessage takeReference()
{
- _referenceCount.incrementAndGet();
+ incrementReference(); // _referenceCount.incrementAndGet();
return this;
}
diff --git a/java/broker/src/main/java/org/apache/qpid/server/queue/AMQQueue.java b/java/broker/src/main/java/org/apache/qpid/server/queue/AMQQueue.java
index 6273ac997b..0c2fd294d2 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/queue/AMQQueue.java
+++ b/java/broker/src/main/java/org/apache/qpid/server/queue/AMQQueue.java
@@ -33,7 +33,6 @@ import java.util.concurrent.atomic.AtomicLong;
import javax.management.JMException;
import org.apache.log4j.Logger;
-
import org.apache.qpid.AMQException;
import org.apache.qpid.configuration.Configured;
import org.apache.qpid.framing.AMQShortString;
@@ -46,11 +45,11 @@ import org.apache.qpid.server.management.ManagedObject;
import org.apache.qpid.server.messageStore.StorableMessage;
import org.apache.qpid.server.messageStore.StorableQueue;
import org.apache.qpid.server.protocol.AMQProtocolSession;
+import org.apache.qpid.server.store.MessageStore;
import org.apache.qpid.server.store.StoreContext;
import org.apache.qpid.server.virtualhost.VirtualHost;
import javax.management.JMException;
-
import java.text.MessageFormat;
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;
@@ -163,22 +162,22 @@ public class AMQQueue implements Managable, Comparable, StorableQueue
}
public AMQQueue(AMQShortString name, boolean durable, AMQShortString owner, boolean autoDelete, VirtualHost virtualHost)
- throws AMQException
+ throws AMQException
{
this(name, durable, owner, autoDelete, virtualHost, AsyncDeliveryConfig.getAsyncDeliveryExecutor(),
- new SubscriptionSet(), new SubscriptionImpl.Factory());
+ new SubscriptionSet(), new SubscriptionImpl.Factory());
}
protected AMQQueue(AMQShortString name, boolean durable, AMQShortString owner, boolean autoDelete,
- VirtualHost virtualHost, SubscriptionSet subscribers) throws AMQException
+ VirtualHost virtualHost, SubscriptionSet subscribers) throws AMQException
{
this(name, durable, owner, autoDelete, virtualHost, AsyncDeliveryConfig.getAsyncDeliveryExecutor(), subscribers,
- new SubscriptionImpl.Factory());
+ new SubscriptionImpl.Factory());
}
protected AMQQueue(AMQShortString name, boolean durable, AMQShortString owner, boolean autoDelete,
- VirtualHost virtualHost, Executor asyncDelivery, SubscriptionSet subscribers,
- SubscriptionFactory subscriptionFactory) throws AMQException
+ VirtualHost virtualHost, Executor asyncDelivery, SubscriptionSet subscribers,
+ SubscriptionFactory subscriptionFactory) throws AMQException
{
if (name == null)
{
@@ -260,7 +259,7 @@ public class AMQQueue implements Managable, Comparable, StorableQueue
}
/**
- * Returns messages within the given range of message Ids
+ * Returns messages within the given range of message Ids.
*
* @param fromMessageId
* @param toMessageId
@@ -292,38 +291,220 @@ public class AMQQueue implements Managable, Comparable, StorableQueue
}
/**
- * moves messages from this queue to another queue. to do this the approach is following- - setup the queue for
- * moving messages (stop the async delivery) - get all the messages available in the given message id range - setup
- * the other queue for moving messages (stop the async delivery) - send these available messages to the other queue
- * (enqueue in other queue) - Once sending to other Queue is successful, remove messages from this queue - remove
- * locks from both queues and start async delivery
+ * Moves messages from this queue to another queue, and also commits the move on the message store. Delivery activity
+ * on the queues being moved between is suspended during the move.
*
- * @param fromMessageId
- * @param toMessageId
- * @param queueName
- * @param storeContext
+ * @param fromMessageId The first message id to move.
+ * @param toMessageId The last message id to move.
+ * @param queueName The queue to move the messages to.
+ * @param storeContext The context of the message store under which to perform the move. This is associated with
+ * the stores transactional context.
*/
public synchronized void moveMessagesToAnotherQueue(long fromMessageId, long toMessageId, String queueName,
- StoreContext storeContext)
+ StoreContext storeContext)
{
- // prepare the delivery manager for moving messages by stopping the async delivery and creating a lock
- AMQQueue anotherQueue = getVirtualHost().getQueueRegistry().getQueue(new AMQShortString(queueName));
+ AMQQueue toQueue = getVirtualHost().getQueueRegistry().getQueue(new AMQShortString(queueName));
+
+ MessageStore fromStore = getVirtualHost().getMessageStore();
+ MessageStore toStore = toQueue.getVirtualHost().getMessageStore();
+
+ if (toStore != fromStore)
+ {
+ throw new RuntimeException("Can only move messages between queues on the same message store.");
+ }
+
try
{
+ // Obtain locks to prevent activity on the queues being moved between.
startMovingMessages();
+ toQueue.startMovingMessages();
+
+ // Get the list of messages to move.
List<AMQMessage> foundMessagesList = getMessagesOnTheQueue(fromMessageId, toMessageId);
- // move messages to another queue
- anotherQueue.startMovingMessages();
- anotherQueue.enqueueMovedMessages(storeContext, foundMessagesList);
+ try
+ {
+ fromStore.beginTran(storeContext);
+
+ // Move the messages in on the message store.
+ for (AMQMessage message : foundMessagesList)
+ {
+ fromStore.dequeueMessage(storeContext, _name, message.getMessageId());
+ toStore.enqueueMessage(storeContext, toQueue._name, message.getMessageId());
+ }
+
+ // Commit and flush the move transcations.
+ try
+ {
+ fromStore.commitTran(storeContext);
+ }
+ catch (AMQException e)
+ {
+ throw new RuntimeException("Failed to commit transaction whilst moving messages on message store.", e);
+ }
+
+ // Move the messages on the in-memory queues.
+ toQueue.enqueueMovedMessages(storeContext, foundMessagesList);
+ _deliveryMgr.removeMovedMessages(foundMessagesList);
+ }
+ // Abort the move transactions on move failures.
+ catch (AMQException e)
+ {
+ try
+ {
+ fromStore.abortTran(storeContext);
+ }
+ catch (AMQException ae)
+ {
+ throw new RuntimeException("Failed to abort transaction whilst moving messages on message store.", ae);
+ }
+ }
+ }
+ // Release locks to allow activity on the queues being moved between to continue.
+ finally
+ {
+ toQueue.stopMovingMessages();
+ stopMovingMessages();
+ }
+ }
+
+ /**
+ * Copies messages on this queue to another queue, and also commits the move on the message store. Delivery activity
+ * on the queues being moved between is suspended during the move.
+ *
+ * @param fromMessageId The first message id to move.
+ * @param toMessageId The last message id to move.
+ * @param queueName The queue to move the messages to.
+ * @param storeContext The context of the message store under which to perform the move. This is associated with
+ * the stores transactional context.
+ */
+ public synchronized void copyMessagesToAnotherQueue(long fromMessageId, long toMessageId, String queueName,
+ StoreContext storeContext)
+ {
+ AMQQueue toQueue = getVirtualHost().getQueueRegistry().getQueue(new AMQShortString(queueName));
+
+ MessageStore fromStore = getVirtualHost().getMessageStore();
+ MessageStore toStore = toQueue.getVirtualHost().getMessageStore();
- // moving is successful, now remove from original queue
- _deliveryMgr.removeMovedMessages(foundMessagesList);
+ if (toStore != fromStore)
+ {
+ throw new RuntimeException("Can only move messages between queues on the same message store.");
}
+
+ try
+ {
+ // Obtain locks to prevent activity on the queues being moved between.
+ startMovingMessages();
+ toQueue.startMovingMessages();
+
+ // Get the list of messages to move.
+ List<AMQMessage> foundMessagesList = getMessagesOnTheQueue(fromMessageId, toMessageId);
+
+ try
+ {
+ fromStore.beginTran(storeContext);
+
+ // Move the messages in on the message store.
+ for (AMQMessage message : foundMessagesList)
+ {
+ toStore.enqueueMessage(storeContext, toQueue._name, message.getMessageId());
+ message.takeReference();
+ }
+
+ // Commit and flush the move transcations.
+ try
+ {
+ fromStore.commitTran(storeContext);
+ }
+ catch (AMQException e)
+ {
+ throw new RuntimeException("Failed to commit transaction whilst moving messages on message store.", e);
+ }
+
+ // Move the messages on the in-memory queues.
+ toQueue.enqueueMovedMessages(storeContext, foundMessagesList);
+ }
+ // Abort the move transactions on move failures.
+ catch (AMQException e)
+ {
+ try
+ {
+ fromStore.abortTran(storeContext);
+ }
+ catch (AMQException ae)
+ {
+ throw new RuntimeException("Failed to abort transaction whilst moving messages on message store.", ae);
+ }
+ }
+ }
+ // Release locks to allow activity on the queues being moved between to continue.
+ finally
+ {
+ toQueue.stopMovingMessages();
+ stopMovingMessages();
+ }
+ }
+
+ /**
+ * Removes messages from this queue, and also commits the remove on the message store. Delivery activity
+ * on the queues being moved between is suspended during the remove.
+ *
+ * @param fromMessageId The first message id to move.
+ * @param toMessageId The last message id to move.
+ * @param storeContext The context of the message store under which to perform the move. This is associated with
+ * the stores transactional context.
+ */
+ public synchronized void removeMessagesFromQueue(long fromMessageId, long toMessageId, StoreContext storeContext)
+ {
+ MessageStore fromStore = getVirtualHost().getMessageStore();
+
+ try
+ {
+ // Obtain locks to prevent activity on the queues being moved between.
+ startMovingMessages();
+
+ // Get the list of messages to move.
+ List<AMQMessage> foundMessagesList = getMessagesOnTheQueue(fromMessageId, toMessageId);
+
+ try
+ {
+ fromStore.beginTran(storeContext);
+
+ // remove the messages in on the message store.
+ for (AMQMessage message : foundMessagesList)
+ {
+ fromStore.dequeueMessage(storeContext, _name, message.getMessageId());
+ }
+
+ // Commit and flush the move transcations.
+ try
+ {
+ fromStore.commitTran(storeContext);
+ }
+ catch (AMQException e)
+ {
+ throw new RuntimeException("Failed to commit transaction whilst moving messages on message store.", e);
+ }
+
+ // remove the messages on the in-memory queues.
+ _deliveryMgr.removeMovedMessages(foundMessagesList);
+ }
+ // Abort the move transactions on move failures.
+ catch (AMQException e)
+ {
+ try
+ {
+ fromStore.abortTran(storeContext);
+ }
+ catch (AMQException ae)
+ {
+ throw new RuntimeException("Failed to abort transaction whilst moving messages on message store.", ae);
+ }
+ }
+ }
+ // Release locks to allow activity on the queues being moved between to continue.
finally
{
- // remove the lock and start the async delivery
- anotherQueue.stopMovingMessages();
stopMovingMessages();
}
}
@@ -458,7 +639,7 @@ public class AMQQueue implements Managable, Comparable, StorableQueue
}
public void registerProtocolSession(AMQProtocolSession ps, int channel, AMQShortString consumerTag, boolean acks,
- FieldTable filters, boolean noLocal, boolean exclusive) throws AMQException
+ FieldTable filters, boolean noLocal, boolean exclusive) throws AMQException
{
if (incrementSubscriberCount() > 1)
{
@@ -481,13 +662,12 @@ public class AMQQueue implements Managable, Comparable, StorableQueue
if (_logger.isDebugEnabled())
{
- _logger.debug(MessageFormat.format(
- "Registering protocol session {0} with channel {1} and " + "consumer tag {2} with {3}", ps, channel,
- consumerTag, this));
+ _logger.debug(MessageFormat.format("Registering protocol session {0} with channel {1} and "
+ + "consumer tag {2} with {3}", ps, channel, consumerTag, this));
}
Subscription subscription =
- _subscriptionFactory.createSubscription(channel, ps, consumerTag, acks, filters, noLocal, this);
+ _subscriptionFactory.createSubscription(channel, ps, consumerTag, acks, filters, noLocal, this);
if (subscription.filtersMessages())
{
@@ -525,8 +705,8 @@ public class AMQQueue implements Managable, Comparable, StorableQueue
if (_logger.isDebugEnabled())
{
_logger.debug(MessageFormat.format(
- "Unregistering protocol session {0} with channel {1} and consumer tag {2} from {3}", ps, channel,
- consumerTag, this));
+ "Unregistering protocol session {0} with channel {1} and consumer tag {2} from {3}",
+ ps, channel, consumerTag, this));
}
Subscription removedSubscription;
diff --git a/java/broker/src/main/java/org/apache/qpid/server/queue/AMQQueueMBean.java b/java/broker/src/main/java/org/apache/qpid/server/queue/AMQQueueMBean.java
index bbaa7379f6..07872d7644 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/queue/AMQQueueMBean.java
+++ b/java/broker/src/main/java/org/apache/qpid/server/queue/AMQQueueMBean.java
@@ -18,30 +18,23 @@
* under the License.
*
*/
-/*
- *
- * Copyright (c) 2006 The Apache Software Foundation
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
package org.apache.qpid.server.queue;
-import java.text.SimpleDateFormat;
-import java.util.ArrayList;
-import java.util.Date;
-import java.util.Iterator;
-import java.util.List;
+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.CommonContentHeaderProperties;
+import org.apache.qpid.framing.ContentHeaderBody;
+import org.apache.qpid.framing.abstraction.ContentChunk;
+import org.apache.qpid.server.management.AMQManagedObject;
+import org.apache.qpid.server.management.MBeanConstructor;
+import org.apache.qpid.server.management.MBeanDescription;
+import org.apache.qpid.server.management.ManagedObject;
+import org.apache.qpid.server.store.StoreContext;
import javax.management.JMException;
import javax.management.MBeanException;
@@ -60,30 +53,25 @@ import javax.management.openmbean.TabularData;
import javax.management.openmbean.TabularDataSupport;
import javax.management.openmbean.TabularType;
-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.CommonContentHeaderProperties;
-import org.apache.qpid.framing.ContentHeaderBody;
-import org.apache.qpid.framing.abstraction.ContentChunk;
-import org.apache.qpid.server.management.AMQManagedObject;
-import org.apache.qpid.server.management.MBeanConstructor;
-import org.apache.qpid.server.management.MBeanDescription;
-import org.apache.qpid.server.management.ManagedObject;
-import org.apache.qpid.server.store.StoreContext;
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.Iterator;
+import java.util.List;
/**
- * MBean class for AMQQueue. It implements all the management features exposed
- * for an AMQQueue.
+ * AMQQueueMBean is the management bean for an {@link AMQQueue}.
+ *
+ * <p/><tablse id="crc"><caption>CRC Caption</caption>
+ * <tr><th> Responsibilities <th> Collaborations
+ * </table>
*/
@MBeanDescription("Management Interface for AMQQueue")
public class AMQQueueMBean extends AMQManagedObject implements ManagedQueue, QueueNotificationListener
{
+ /** Used for debugging purposes. */
private static final Logger _logger = Logger.getLogger(AMQQueueMBean.class);
+
private static final SimpleDateFormat _dateFormat = new SimpleDateFormat("MM-dd-yy HH:mm:ss.SSS z");
/**
diff --git a/java/broker/src/main/java/org/apache/qpid/server/queue/ConcurrentSelectorDeliveryManager.java b/java/broker/src/main/java/org/apache/qpid/server/queue/ConcurrentSelectorDeliveryManager.java
index 2aa759b35d..907d68b733 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/queue/ConcurrentSelectorDeliveryManager.java
+++ b/java/broker/src/main/java/org/apache/qpid/server/queue/ConcurrentSelectorDeliveryManager.java
@@ -20,19 +20,6 @@
*/
package org.apache.qpid.server.queue;
-import java.util.ArrayList;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Queue;
-import java.util.Set;
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.concurrent.Executor;
-import java.util.concurrent.atomic.AtomicBoolean;
-import java.util.concurrent.atomic.AtomicLong;
-import java.util.concurrent.atomic.AtomicInteger;
-import java.util.concurrent.locks.ReentrantLock;
-
import org.apache.log4j.Logger;
import org.apache.qpid.AMQException;
import org.apache.qpid.configuration.Configured;
@@ -42,8 +29,21 @@ import org.apache.qpid.server.AMQChannel;
import org.apache.qpid.server.configuration.Configurator;
import org.apache.qpid.server.protocol.AMQProtocolSession;
import org.apache.qpid.server.store.StoreContext;
-import org.apache.qpid.util.MessageQueue;
import org.apache.qpid.util.ConcurrentLinkedMessageQueueAtomicSize;
+import org.apache.qpid.util.MessageQueue;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Queue;
+import java.util.Set;
+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.locks.ReentrantLock;
/** Manages delivery of messages on behalf of a queue */
@@ -87,6 +87,10 @@ public class ConcurrentSelectorDeliveryManager implements DeliveryManager
private final Object _queueHeadLock = new Object();
private String _processingThreadName = "";
+
+ /** Used by any reaping thread to purge messages */
+ private StoreContext _reapingStoreContext = new StoreContext();
+
ConcurrentSelectorDeliveryManager(SubscriptionManager subscriptions, AMQQueue queue)
{
@@ -453,12 +457,31 @@ public class ConcurrentSelectorDeliveryManager implements DeliveryManager
//while (we have a message) && ((The subscriber is not a browser or message is taken ) or we are clearing) && (Check message is taken.)
while (purgeMessage(message, sub))
{
+ // if we are purging then ensure we mark this message taken for the current subscriber
+ // the current subscriber may be null in the case of a get or a purge but this is ok.
+// boolean alreadyTaken = message.taken(_queue, sub);
+
//remove the already taken message or expired
AMQMessage removed = messages.poll();
assert removed == message;
- _totalMessageSize.addAndGet(-message.getSize());
+ // if the message expired then the _totalMessageSize needs adjusting
+ if (message.expired(_queue))
+ {
+ _totalMessageSize.addAndGet(-message.getSize());
+
+ // Use the reapingStoreContext as any sub(if we have one) may be in a tx.
+ message.dequeue(_reapingStoreContext, _queue);
+
+ if (_log.isInfoEnabled())
+ {
+ _log.info(debugIdentity() + " Doing clean up of the main _message queue.");
+ }
+ }
+
+ //else the clean up is not required as the message has already been taken for this queue therefore
+ // it was the responsibility of the code that took the message to ensure the _totalMessageSize was updated.
if (_log.isTraceEnabled())
{
@@ -473,7 +496,10 @@ public class ConcurrentSelectorDeliveryManager implements DeliveryManager
}
/**
- *
+ * This method will return true if the message is to be purged from the queue.
+ *
+ *
+ * SIDE-EFFECT: The message will be taken by the Subscription(sub) for the current Queue(_queue)
* @param message
* @param sub
* @return
@@ -493,15 +519,15 @@ public class ConcurrentSelectorDeliveryManager implements DeliveryManager
// if the message is null then don't purge as we have no messagse.
if (message != null)
{
+ // Check that the message hasn't expired.
+ if (message.expired(_queue))
+ {
+ return true;
+ }
+
// if we have a subscriber perform message checks
if (sub != null)
{
- // Check that the message hasn't expired.
- if (message.expired(sub.getChannel().getStoreContext(), _queue))
- {
- return true;
- }
-
// if we have a queue browser(we don't purge) so check mark the message as taken
purge = ((!sub.isBrowser() || message.isTaken(_queue)));
}
@@ -606,7 +632,10 @@ public class ConcurrentSelectorDeliveryManager implements DeliveryManager
{
if (_log.isInfoEnabled())
{
- _log.info(debugIdentity() + "We could do clean up of the main _message queue here");
+ //fixme - we should do the clean up as the message remains on the _message queue
+ // this is resulting in the next consumer receiving the message and then attempting to purge it
+ //
+ _log.info(debugIdentity() + "We should do clean up of the main _message queue here");
}
}
@@ -617,7 +646,14 @@ public class ConcurrentSelectorDeliveryManager implements DeliveryManager
}
catch (AMQException e)
{
- message.release(_queue);
+ if (message != null)
+ {
+ message.release(_queue);
+ }
+ else
+ {
+ _log.error(debugIdentity() + "Unable to release message as it is null. " + e, e);
+ }
_log.error(debugIdentity() + "Unable to deliver message as dequeue failed: " + e, e);
}
}
@@ -696,25 +732,6 @@ public class ConcurrentSelectorDeliveryManager implements DeliveryManager
}
-// private void sendNextMessage(Subscription sub)
-// {
-// if (sub.filtersMessages())
-// {
-// sendNextMessage(sub, sub.getPreDeliveryQueue());
-// if (sub.isAutoClose())
-// {
-// if (sub.getPreDeliveryQueue().isEmpty())
-// {
-// sub.close();
-// }
-// }
-// }
-// else
-// {
-// sendNextMessage(sub, _messages);
-// }
-// }
-
public void deliver(StoreContext context, AMQShortString name, AMQMessage msg, boolean deliverFirst) throws AMQException
{
@@ -723,8 +740,6 @@ public class ConcurrentSelectorDeliveryManager implements DeliveryManager
{
_log.debug(debugIdentity() + "deliver :first(" + deliverFirst + ") :" + msg);
}
- // This shouldn't be done here.
-// msg.release();
//Check if we have someone to deliver the message to.
_lock.lock();
@@ -800,7 +815,7 @@ public class ConcurrentSelectorDeliveryManager implements DeliveryManager
if (debugEnabled)
{
_log.debug(debugIdentity() + " Subscription(" + System.identityHashCode(s) + ") became " +
- "suspended between nextSubscriber and send for message:" + msg.debugIdentity());
+ "suspended between nextSubscriber and send for message:" + msg.debugIdentity());
}
}
}
@@ -810,7 +825,7 @@ public class ConcurrentSelectorDeliveryManager implements DeliveryManager
if (debugEnabled)
{
_log.debug(debugIdentity() + " Message(" + msg.debugIdentity() + ") has not been taken so recursing!:" +
- " Subscriber:" + System.identityHashCode(s));
+ " Subscriber:" + System.identityHashCode(s));
}
deliver(context, name, msg, deliverFirst);
diff --git a/java/broker/src/main/java/org/apache/qpid/server/queue/DefaultQueueRegistry.java b/java/broker/src/main/java/org/apache/qpid/server/queue/DefaultQueueRegistry.java
index c0f1e7f40c..cbe9246f09 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/queue/DefaultQueueRegistry.java
+++ b/java/broker/src/main/java/org/apache/qpid/server/queue/DefaultQueueRegistry.java
@@ -20,13 +20,14 @@
*/
package org.apache.qpid.server.queue;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.ConcurrentMap;
-
import org.apache.qpid.AMQException;
import org.apache.qpid.framing.AMQShortString;
import org.apache.qpid.server.virtualhost.VirtualHost;
+import java.util.Collection;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+
public class DefaultQueueRegistry implements QueueRegistry
{
private ConcurrentMap<AMQShortString, AMQQueue> _queueMap = new ConcurrentHashMap<AMQShortString, AMQQueue>();
@@ -57,4 +58,14 @@ public class DefaultQueueRegistry implements QueueRegistry
{
return _queueMap.get(name);
}
+
+ public Collection<AMQShortString> getQueueNames()
+ {
+ return _queueMap.keySet();
+ }
+
+ public Collection<AMQQueue> getQueues()
+ {
+ return _queueMap.values();
+ }
}
diff --git a/java/broker/src/main/java/org/apache/qpid/server/queue/ExchangeBindings.java b/java/broker/src/main/java/org/apache/qpid/server/queue/ExchangeBindings.java
index a8247aa2db..60c1a8f574 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/queue/ExchangeBindings.java
+++ b/java/broker/src/main/java/org/apache/qpid/server/queue/ExchangeBindings.java
@@ -46,7 +46,7 @@ class ExchangeBindings
ExchangeBinding(AMQShortString routingKey, Exchange exchange)
{
- this(routingKey, exchange,EMPTY_ARGUMENTS);
+ this(routingKey, exchange, EMPTY_ARGUMENTS);
}
ExchangeBinding(AMQShortString routingKey, Exchange exchange, FieldTable arguments)
@@ -80,7 +80,10 @@ class ExchangeBindings
public boolean equals(Object o)
{
- if (!(o instanceof ExchangeBinding)) return false;
+ if (!(o instanceof ExchangeBinding))
+ {
+ return false;
+ }
ExchangeBinding eb = (ExchangeBinding) o;
return _exchange.equals(eb._exchange)
&& _routingKey.equals(eb._routingKey)
@@ -104,16 +107,16 @@ class ExchangeBindings
*/
void addBinding(AMQShortString routingKey, FieldTable arguments, Exchange exchange)
{
- _bindings.add(new ExchangeBinding(routingKey, exchange, arguments ));
+ _bindings.add(new ExchangeBinding(routingKey, exchange, arguments));
}
public void remove(AMQShortString routingKey, FieldTable arguments, Exchange exchange)
{
- _bindings.remove(new ExchangeBinding(routingKey, exchange, arguments ));
+ _bindings.remove(new ExchangeBinding(routingKey, exchange, arguments));
}
-
+
/**
* Deregisters this queue from any exchange it has been bound to
*/
diff --git a/java/broker/src/main/java/org/apache/qpid/server/queue/MessageMetaData.java b/java/broker/src/main/java/org/apache/qpid/server/queue/MessageMetaData.java
index 285f05fb20..6118a4c11f 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/queue/MessageMetaData.java
+++ b/java/broker/src/main/java/org/apache/qpid/server/queue/MessageMetaData.java
@@ -1,18 +1,22 @@
/*
*
- * Copyright (c) 2006 The Apache Software Foundation
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
*
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
+ * http://www.apache.org/licenses/LICENSE-2.0
*
- * http://www.apache.org/licenses/LICENSE-2.0
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
*
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT 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;
diff --git a/java/broker/src/main/java/org/apache/qpid/server/queue/NotificationCheck.java b/java/broker/src/main/java/org/apache/qpid/server/queue/NotificationCheck.java
index 00ccffdea1..6b3d65661f 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/queue/NotificationCheck.java
+++ b/java/broker/src/main/java/org/apache/qpid/server/queue/NotificationCheck.java
@@ -1,18 +1,21 @@
/*
*
- * Copyright (c) 2006 The Apache Software Foundation
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
*
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
+ * http://www.apache.org/licenses/LICENSE-2.0
*
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT 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;
diff --git a/java/broker/src/main/java/org/apache/qpid/server/queue/QueueNotificationListener.java b/java/broker/src/main/java/org/apache/qpid/server/queue/QueueNotificationListener.java
index 9554d34f00..959ca03c80 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/queue/QueueNotificationListener.java
+++ b/java/broker/src/main/java/org/apache/qpid/server/queue/QueueNotificationListener.java
@@ -1,22 +1,26 @@
/*
*
- * Copyright (c) 2006 The Apache Software Foundation
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
*
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
+ * http://www.apache.org/licenses/LICENSE-2.0
*
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT 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 QueueNotificationListener
{
void notifyClients(NotificationCheck notification, AMQQueue queue, String notificationMsg);
diff --git a/java/broker/src/main/java/org/apache/qpid/server/queue/QueueRegistry.java b/java/broker/src/main/java/org/apache/qpid/server/queue/QueueRegistry.java
index ed2101fd75..13c150f82b 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/queue/QueueRegistry.java
+++ b/java/broker/src/main/java/org/apache/qpid/server/queue/QueueRegistry.java
@@ -25,6 +25,7 @@ import org.apache.qpid.framing.AMQShortString;
import org.apache.qpid.server.virtualhost.VirtualHost;
import org.apache.qpid.server.messageStore.StorableQueue;
+import java.util.Collection;
public interface QueueRegistry
{
@@ -35,4 +36,9 @@ public interface QueueRegistry
void unregisterQueue(AMQShortString name) throws AMQException;
AMQQueue getQueue(AMQShortString name);
+
+ Collection<AMQShortString> getQueueNames();
+
+ Collection<AMQQueue> getQueues();
+
}
diff --git a/java/broker/src/main/java/org/apache/qpid/server/queue/TransientMessageData.java b/java/broker/src/main/java/org/apache/qpid/server/queue/TransientMessageData.java
index 7c8064789e..79ee6b93a3 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/queue/TransientMessageData.java
+++ b/java/broker/src/main/java/org/apache/qpid/server/queue/TransientMessageData.java
@@ -1,18 +1,21 @@
/*
*
- * Copyright (c) 2006 The Apache Software Foundation
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
*
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
+ * http://www.apache.org/licenses/LICENSE-2.0
*
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT 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;
diff --git a/java/broker/src/main/java/org/apache/qpid/server/txn/NonTransactionalContext.java b/java/broker/src/main/java/org/apache/qpid/server/txn/NonTransactionalContext.java
index 8becaf52b9..d9500429af 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/txn/NonTransactionalContext.java
+++ b/java/broker/src/main/java/org/apache/qpid/server/txn/NonTransactionalContext.java
@@ -1,18 +1,21 @@
/*
*
- * Copyright (c) 2006 The Apache Software Foundation
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
*
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
+ * http://www.apache.org/licenses/LICENSE-2.0
*
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT 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.txn;
diff --git a/java/broker/src/main/java/org/apache/qpid/server/txn/TransactionalContext.java b/java/broker/src/main/java/org/apache/qpid/server/txn/TransactionalContext.java
index 88451e2fca..fee25c07df 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/txn/TransactionalContext.java
+++ b/java/broker/src/main/java/org/apache/qpid/server/txn/TransactionalContext.java
@@ -28,24 +28,144 @@ import org.apache.qpid.server.queue.AMQQueue;
import org.apache.qpid.server.store.StoreContext;
/**
- * @author Robert Greig (robert.j.greig@jpmorgan.com)
+ * TransactionalContext provides a context in which transactional operations on {@link AMQMessage}s are performed.
+ * Different levels of transactional support for the delivery of messages may be provided by different implementations
+ * of this interface.
+ *
+ * <p/>The fundamental transactional operations that can be performed on a message queue are 'enqueue' and 'dequeue'.
+ * In this interface, these have been recast as the {@link #messageFullyReceived} and {@link #acknowledgeMessage}
+ * operations. This interface essentially provides a way to make enqueueing and dequeuing transactional.
+ *
+ * <p/><table id="crc"><caption>CRC Card</caption>
+ * <tr><th> Responsibilities
+ * <tr><td> Explicitly accept a transaction start notification.
+ * <tr><td> Commit all pending operations in a transaction.
+ * <tr><td> Rollback all pending operations in a transaction.
+ * <tr><td> Deliver a message to a queue as part of a transaction.
+ * <tr><td> Redeliver a message to a queue as part of a transaction.
+ * <tr><td> Mark a message as acknowledged as part of a transaction.
+ * <tr><td> Accept notification that a message has been completely received as part of a transaction.
+ * <tr><td> Accept notification that a message has been fully processed as part of a transaction.
+ * <tr><td> Associate a message store context with this transaction context.
+ * </table>
+ *
+ * @todo The 'fullyReceived' and 'messageProcessed' events sit uncomfortably in the responsibilities of a transactional
+ * context. They are non-transactional operations, used to trigger other side-effects. Consider moving them
+ * somewhere else, a seperate interface for example.
+ *
+ * @todo This transactional context could be written as a wrapper extension to a Queue implementation, that provides
+ * transactional management of the enqueue and dequeue operations, with added commit/rollback methods. Any
+ * queue implementation could be made transactional by wrapping it as a transactional queue. This would mean
+ * that the enqueue/dequeue operations do not need to be recast as deliver/acknowledge operations, which may be
+ * conceptually neater.
+ *
+ * For example:
+ * <pre>
+ * public interface Transactional
+ * {
+ * public void commit();
+ * public void rollback();
+ * }
+ *
+ * public interface TransactionalQueue<E> extends Transactional, SizeableQueue<E>
+ * {}
+ *
+ * public class Queues
+ * {
+ * ...
+ * // For transactional messaging, take a transactional view onto the queue.
+ * public static <E> TransactionalQueue<E> getTransactionalQueue(SizeableQueue<E> queue) { ... }
+ *
+ * // For non-transactional messaging, take a non-transactional view onto the queue.
+ * public static <E> TransactionalQueue<E> getNonTransactionalQueue(SizeableQueue<E> queue) { ... }
+ * }
+ * </pre>
*/
public interface TransactionalContext
{
+ /**
+ * Explicitly begins the transaction, if it has not already been started. {@link #commit} or {@link #rollback}
+ * should automatically begin the next transaction in the chain.
+ *
+ * @throws AMQException If the transaction cannot be started for any reason.
+ */
void beginTranIfNecessary() throws AMQException;
+ /**
+ * Makes all pending operations on the transaction permanent and visible.
+ *
+ * @throws AMQException If the transaction cannot be committed for any reason.
+ */
void commit() throws AMQException;
+ /**
+ * Erases all pending operations on the transaction.
+ *
+ * @throws AMQException If the transaction cannot be committed for any reason.
+ */
void rollback() throws AMQException;
+ /**
+ * Delivers the specified message to the specified queue. A 'deliverFirst' flag may be set if the message is a
+ * redelivery, and should be placed on the front of the queue.
+ *
+ * <p/>This is an 'enqueue' operation.
+ *
+ * @param message The message to deliver.
+ * @param queue The queue to deliver the message to.
+ * @param deliverFirst <tt>true</tt> to place the message on the front of the queue for redelivery, <tt>false</tt>
+ * for normal FIFO message ordering.
+ *
+ * @throws AMQException If the message cannot be delivered for any reason.
+ */
void deliver(AMQMessage message, AMQQueue queue, boolean deliverFirst) throws AMQException;
+ /**
+ * Acknowledges a message or many messages as delivered. All messages up to a specified one, may be acknowledged by
+ * setting the 'multiple' flag. It is also possible for the acknowledged message id to be zero, when the 'multiple'
+ * flag is set, in which case an acknowledgement up to the latest delivered message should be done.
+ *
+ * <p/>This is a 'dequeue' operation.
+ *
+ * @param deliveryTag The id of the message to acknowledge, or zero, if using multiple acknowledgement
+ * up to the latest message.
+ * @param lastDeliveryTag The latest message delivered.
+ * @param multiple <tt>true</tt> if all message ids up the acknowledged one or latest delivered, are
+ * to be acknowledged, <tt>false</tt> otherwise.
+ * @param unacknowledgedMessageMap The unacknowledged messages in the transaction, to remove the acknowledged message
+ * from.
+ *
+ * @throws AMQException If the message cannot be acknowledged for any reason.
+ */
void acknowledgeMessage(long deliveryTag, long lastDeliveryTag, boolean multiple,
- UnacknowledgedMessageMap unacknowledgedMessageMap) throws AMQException;
+ UnacknowledgedMessageMap unacknowledgedMessageMap) throws AMQException;
+ /**
+ * Notifies the transactional context that a message has been fully received. The actual message that was received
+ * is not specified. This event may be used to trigger a process related to the receipt of the message, for example,
+ * flushing its data to disk.
+ *
+ * @param persistent <tt>true</tt> if the received message is persistent, <tt>false</tt> otherwise.
+ *
+ * @throws AMQException If the fully received event cannot be processed for any reason.
+ */
void messageFullyReceived(boolean persistent) throws AMQException;
+ /**
+ * Notifies the transactional context that a message has been delivered, succesfully or otherwise. The actual
+ * message that was delivered is not specified. This event may be used to trigger a process related to the
+ * outcome of the delivery of the message, for example, cleaning up failed deliveries.
+ *
+ * @param protocolSession The protocol session of the deliverable message.
+ *
+ * @throws AMQException If the message processed event cannot be handled for any reason.
+ */
void messageProcessed(AMQProtocolSession protocolSession) throws AMQException;
+ /**
+ * Gets the message store context associated with this transactional context.
+ *
+ * @return The message store context associated with this transactional context.
+ */
StoreContext getStoreContext();
}
diff --git a/java/broker/src/main/java/org/apache/qpid/server/virtualhost/VirtualHost.java b/java/broker/src/main/java/org/apache/qpid/server/virtualhost/VirtualHost.java
index 6638689299..235555c58b 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/virtualhost/VirtualHost.java
+++ b/java/broker/src/main/java/org/apache/qpid/server/virtualhost/VirtualHost.java
@@ -1,3 +1,4 @@
+<<<<<<< .working
/*
*
* Licensed to the Apache Software Foundation (ASF) under one
@@ -286,3 +287,264 @@ public class VirtualHost implements Accessable
}
}
+=======
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT 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.virtualhost;
+
+import javax.management.NotCompliantMBeanException;
+
+import org.apache.commons.configuration.Configuration;
+import org.apache.log4j.Logger;
+import org.apache.qpid.server.AMQBrokerManagerMBean;
+import org.apache.qpid.server.security.access.AccessManager;
+import org.apache.qpid.server.security.access.AccessManagerImpl;
+import org.apache.qpid.server.security.access.Accessable;
+import org.apache.qpid.server.security.auth.manager.PrincipalDatabaseAuthenticationManager;
+import org.apache.qpid.server.security.auth.manager.AuthenticationManager;
+import org.apache.qpid.server.configuration.Configurator;
+import org.apache.qpid.server.exchange.DefaultExchangeFactory;
+import org.apache.qpid.server.exchange.DefaultExchangeRegistry;
+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.DefaultQueueRegistry;
+import org.apache.qpid.server.queue.QueueRegistry;
+import org.apache.qpid.server.registry.ApplicationRegistry;
+import org.apache.qpid.server.store.MessageStore;
+
+public class VirtualHost implements Accessable
+{
+ private static final Logger _logger = Logger.getLogger(VirtualHost.class);
+
+
+ private final String _name;
+
+ private QueueRegistry _queueRegistry;
+
+ private ExchangeRegistry _exchangeRegistry;
+
+ private ExchangeFactory _exchangeFactory;
+
+ private MessageStore _messageStore;
+
+ protected VirtualHostMBean _virtualHostMBean;
+
+ private AMQBrokerManagerMBean _brokerMBean;
+
+ private AuthenticationManager _authenticationManager;
+
+ private AccessManager _accessManager;
+
+
+ public void setAccessableName(String name)
+ {
+ _logger.warn("Setting Accessable Name for VirualHost is not allowed. ("
+ + name + ") ignored remains :" + getAccessableName());
+ }
+
+ public String getAccessableName()
+ {
+ return _name;
+ }
+
+
+ /**
+ * 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.
+ */
+ public class VirtualHostMBean extends AMQManagedObject implements ManagedVirtualHost
+ {
+ public VirtualHostMBean() throws NotCompliantMBeanException
+ {
+ super(ManagedVirtualHost.class, "VirtualHost");
+ }
+
+ public String getObjectInstanceName()
+ {
+ return _name.toString();
+ }
+
+ public String getName()
+ {
+ return _name.toString();
+ }
+
+ public VirtualHost getVirtualHost()
+ {
+ return VirtualHost.this;
+ }
+
+
+ } // End of MBean class
+
+ /**
+ * Used for testing only
+ * @param name
+ * @param store
+ * @throws Exception
+ */
+ public VirtualHost(String name, MessageStore store) throws Exception
+ {
+ this(name, null, store);
+ }
+
+ /**
+ * Normal Constructor
+ * @param name
+ * @param hostConfig
+ * @throws Exception
+ */
+ public VirtualHost(String name, Configuration hostConfig) throws Exception
+ {
+ this(name, hostConfig, null);
+ }
+
+ private VirtualHost(String name, Configuration hostConfig, MessageStore store) throws Exception
+ {
+ _name = name;
+
+ _virtualHostMBean = new VirtualHostMBean();
+ // This isn't needed to be registered
+ //_virtualHostMBean.register();
+
+ _queueRegistry = new DefaultQueueRegistry(this);
+ _exchangeFactory = new DefaultExchangeFactory(this);
+ _exchangeRegistry = new DefaultExchangeRegistry(this);
+
+ if (store != null)
+ {
+ _messageStore = store;
+ }
+ else
+ {
+ if (hostConfig == null)
+ {
+ throw new IllegalAccessException("HostConfig and MessageStore cannot be null");
+ }
+ initialiseMessageStore(hostConfig);
+ }
+
+ _exchangeRegistry.initialise();
+
+ _authenticationManager = new PrincipalDatabaseAuthenticationManager(name, hostConfig);
+
+ _accessManager = new AccessManagerImpl(name, hostConfig);
+
+ _brokerMBean = new AMQBrokerManagerMBean(_virtualHostMBean);
+ _brokerMBean.register();
+ }
+
+ private void initialiseMessageStore(Configuration config) throws Exception
+ {
+ String messageStoreClass = config.getString("store.class");
+
+ Class clazz = Class.forName(messageStoreClass);
+ Object o = clazz.newInstance();
+
+ if (!(o instanceof MessageStore))
+ {
+ throw new ClassCastException("Message store class must implement " + MessageStore.class + ". Class " + clazz +
+ " does not.");
+ }
+ _messageStore = (MessageStore) o;
+ _messageStore.configure(this, "store", config);
+ }
+
+
+ public <T> T getConfiguredObject(Class<T> instanceType, Configuration config)
+ {
+ T instance;
+ 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);
+
+ return instance;
+ }
+
+
+ public String getName()
+ {
+ return _name;
+ }
+
+ public QueueRegistry getQueueRegistry()
+ {
+ return _queueRegistry;
+ }
+
+ public ExchangeRegistry getExchangeRegistry()
+ {
+ return _exchangeRegistry;
+ }
+
+ public ExchangeFactory getExchangeFactory()
+ {
+ return _exchangeFactory;
+ }
+
+ public ApplicationRegistry getApplicationRegistry()
+ {
+ throw new UnsupportedOperationException();
+ }
+
+ public MessageStore getMessageStore()
+ {
+ return _messageStore;
+ }
+
+ public AuthenticationManager getAuthenticationManager()
+ {
+ return _authenticationManager;
+ }
+
+ public AccessManager getAccessManager()
+ {
+ return _accessManager;
+ }
+
+ public void close() throws Exception
+ {
+ if (_messageStore != null)
+ {
+ _messageStore.close();
+ }
+ }
+
+ public ManagedObject getBrokerMBean()
+ {
+ return _brokerMBean;
+ }
+
+ public ManagedObject getManagedObject()
+ {
+ return _virtualHostMBean;
+ }
+}
+>>>>>>> .merge-right.r553432
diff --git a/java/broker/src/main/java/org/apache/qpid/tools/messagestore/MessageStoreTool.java b/java/broker/src/main/java/org/apache/qpid/tools/messagestore/MessageStoreTool.java
new file mode 100644
index 0000000000..afa7916074
--- /dev/null
+++ b/java/broker/src/main/java/org/apache/qpid/tools/messagestore/MessageStoreTool.java
@@ -0,0 +1,648 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT 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.tools.messagestore;
+
+import org.apache.commons.cli.Option;
+import org.apache.commons.cli.OptionBuilder;
+import org.apache.commons.configuration.ConfigurationException;
+import org.apache.qpid.configuration.Configuration;
+import org.apache.qpid.server.exchange.Exchange;
+import org.apache.qpid.server.queue.AMQQueue;
+import org.apache.qpid.server.registry.ApplicationRegistry;
+import org.apache.qpid.server.registry.ConfigurationFileApplicationRegistry;
+import org.apache.qpid.server.store.MemoryMessageStore;
+import org.apache.qpid.server.virtualhost.VirtualHost;
+import org.apache.qpid.tools.messagestore.commands.Clear;
+import org.apache.qpid.tools.messagestore.commands.Command;
+import org.apache.qpid.tools.messagestore.commands.Copy;
+import org.apache.qpid.tools.messagestore.commands.Dump;
+import org.apache.qpid.tools.messagestore.commands.Help;
+import org.apache.qpid.tools.messagestore.commands.List;
+import org.apache.qpid.tools.messagestore.commands.Load;
+import org.apache.qpid.tools.messagestore.commands.Quit;
+import org.apache.qpid.tools.messagestore.commands.Select;
+import org.apache.qpid.tools.messagestore.commands.Show;
+import org.apache.qpid.tools.utils.CommandParser;
+import org.apache.qpid.tools.utils.Console;
+import org.apache.qpid.tools.utils.SimpleCommandParser;
+import org.apache.qpid.tools.utils.SimpleConsole;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.BufferedReader;
+import java.io.BufferedWriter;
+import java.io.File;
+import java.io.FileReader;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.OutputStream;
+import java.io.OutputStreamWriter;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.LinkedList;
+import java.util.Map;
+import java.util.StringTokenizer;
+
+/**
+ * MessageStoreTool.
+ */
+public class MessageStoreTool
+{
+ /** Text outputted at the start of each console.*/
+ private static final String BOILER_PLATE = "MessageStoreTool - for examining Persistent Qpid Broker MessageStore instances";
+
+ /** I/O Wrapper. */
+ protected Console _console;
+
+ /** Batch mode flag. */
+ protected boolean _batchMode;
+
+ /** Internal State object. */
+ private State _state = new State();
+
+ private HashMap<String, Command> _commands = new HashMap<String, Command>();
+
+ /** SLF4J Logger. */
+ private static Logger _devlog = LoggerFactory.getLogger(MessageStoreTool.class);
+
+ /** Loaded configuration file. */
+ private Configuration _config;
+
+ /** Control used for main run loop. */
+ private boolean _running = true;
+ private boolean _initialised = false;
+
+ //---------------------------------------------------------------------------------------------------/
+
+ public static void main(String[] args) throws Configuration.InitException
+ {
+
+ MessageStoreTool tool = new MessageStoreTool(args);
+
+ tool.start();
+ }
+
+
+ public MessageStoreTool(String[] args) throws Configuration.InitException
+ {
+ this(args, System.in, System.out);
+ }
+
+ public MessageStoreTool(String[] args, InputStream in, OutputStream out) throws Configuration.InitException
+ {
+ BufferedReader consoleReader = new BufferedReader(new InputStreamReader(in));
+ BufferedWriter consoleWriter = new BufferedWriter(new OutputStreamWriter(out));
+
+ Runtime.getRuntime().addShutdownHook(new Thread(new ShutdownHook(this)));
+ _batchMode = false;
+
+ _console = new SimpleConsole(consoleWriter, consoleReader);
+
+ _config = new Configuration();
+
+ setOptions();
+ _config.processCommandline(args);
+ }
+
+
+ private void setOptions()
+ {
+ Option help = new Option("h", "help", false, "print this message");
+ Option version = new Option("v", "version", false, "print the version information and exit");
+ Option configFile =
+ OptionBuilder.withArgName("file").hasArg()
+ .withDescription("use given configuration file By "
+ + "default looks for a file named "
+ + Configuration.DEFAULT_CONFIG_FILE + " in " + Configuration.QPID_HOME)
+ .withLongOpt("config")
+ .create("c");
+
+ _config.setOption(help);
+ _config.setOption(version);
+ _config.setOption(configFile);
+ }
+
+ public State getState()
+ {
+ return _state;
+ }
+
+ public Map<String, Command> getCommands()
+ {
+ return _commands;
+ }
+
+ public void setConfigurationFile(String configfile) throws Configuration.InitException
+ {
+ _config.loadConfig(new File(configfile));
+ setup();
+ }
+
+ public Console getConsole()
+ {
+ return _console;
+ }
+
+ public void setConsole(Console console)
+ {
+ _console = console;
+ }
+
+ /**
+ * Simple ShutdownHook to cleanly shutdown the databases
+ */
+ class ShutdownHook implements Runnable
+ {
+ MessageStoreTool _tool;
+
+ ShutdownHook(MessageStoreTool messageStoreTool)
+ {
+ _tool = messageStoreTool;
+ }
+
+ public void run()
+ {
+ _tool.quit();
+ }
+ }
+
+ public void quit()
+ {
+ _running = false;
+
+ if (_initialised)
+ {
+ ApplicationRegistry.remove(1);
+ }
+
+ _console.println("...exiting");
+
+ _console.close();
+ }
+
+ public void setBatchMode(boolean batchmode)
+ {
+ _batchMode = batchmode;
+ }
+
+ /**
+ * Main loop
+ */
+ protected void start()
+ {
+ setup();
+
+ if (!_initialised)
+ {
+ System.exit(1);
+ }
+
+ _console.println("");
+
+ _console.println(BOILER_PLATE);
+
+ runCLI();
+ }
+
+ private void setup()
+ {
+ loadDefaultVirtualHosts();
+
+ loadCommands();
+
+ _state.clearAll();
+ }
+
+ private void loadCommands()
+ {
+ _commands.clear();
+ //todo Dynamically load the classes that exis in com.redhat.etp.qpid.commands
+ _commands.put("close", new Clear(this));
+ _commands.put("copy", new Copy(this));
+ _commands.put("dump", new Dump(this));
+ _commands.put("help", new Help(this));
+ _commands.put("list", new List(this));
+ _commands.put("load", new Load(this));
+ _commands.put("quit", new Quit(this));
+ _commands.put("select", new Select(this));
+ _commands.put("show", new Show(this));
+ }
+
+ private void loadDefaultVirtualHosts()
+ {
+ final File configFile = _config.getConfigFile();
+
+ loadVirtualHosts(configFile);
+ }
+
+ private void loadVirtualHosts(File configFile)
+ {
+
+ if (!configFile.exists())
+ {
+ _devlog.error("Config file not found:" + configFile.getAbsolutePath());
+ return;
+ }
+ else
+ {
+ _devlog.debug("using config file :" + configFile.getAbsolutePath());
+ }
+
+ try
+ {
+ ConfigurationFileApplicationRegistry registry = new ConfigurationFileApplicationRegistry(configFile);
+
+ ApplicationRegistry.remove(1);
+
+ ApplicationRegistry.initialise(registry);
+
+ checkMessageStores();
+ _initialised = true;
+ }
+ catch (ConfigurationException e)
+ {
+ _console.println("Unable to load configuration due to configuration error: " + e.getMessage());
+ e.printStackTrace();
+ }
+ catch (Exception e)
+ {
+ _console.println("Unable to load configuration due to: " + e.getMessage());
+ e.printStackTrace();
+ }
+
+
+ }
+
+ private void checkMessageStores()
+ {
+ Collection<VirtualHost> vhosts = ApplicationRegistry.getInstance().getVirtualHostRegistry().getVirtualHosts();
+
+ boolean warning = false;
+ for (VirtualHost vhost : vhosts)
+ {
+ if (vhost.getMessageStore() instanceof MemoryMessageStore)
+ {
+ _console.println("WARNING: Virtualhost '" + vhost.getName() + "' is using a MemoryMessageStore. "
+ + "Changes will not persist.");
+ warning = true;
+ }
+ }
+
+ if (warning)
+ {
+ _console.println("");
+ _console.println("Please ensure you are using the correct config file currently using '"
+ + _config.getConfigFile().getAbsolutePath() + "'");
+ _console.println("New config file can be specifed by 'load <config file>' or -c on the commandline.");
+ _console.println("");
+ }
+ }
+
+ private void runCLI()
+ {
+ while (_running)
+ {
+ if (!_batchMode)
+ {
+ printPrompt();
+ }
+
+ String[] args = _console.readCommand();
+
+ while (args != null)
+ {
+ exec(args);
+
+ if (_running)
+ {
+ if (!_batchMode)
+ {
+ printPrompt();
+ }
+
+ args = _console.readCommand();
+ }
+ }
+ }
+ }
+
+ private void printPrompt()
+ {
+ _console.print(prompt());
+ }
+
+
+ /**
+ * Execute a script (batch mode).
+ *
+ * @param script The file script
+ */
+ protected void runScripts(String script)
+ {
+ //Store Current State
+ boolean oldBatch = _batchMode;
+ CommandParser oldParser = _console.getCommandParser();
+ setBatchMode(true);
+
+ try
+ {
+ _devlog.debug("Running script '" + script + "'");
+
+ _console.setCommandParser(new SimpleCommandParser(new BufferedReader(new FileReader(script))));
+
+ start();
+ }
+ catch (java.io.FileNotFoundException e)
+ {
+ _devlog.error("Script not found: '" + script + "' due to:" + e.getMessage());
+ }
+
+ //Restore previous state
+ _console.setCommandParser(oldParser);
+ setBatchMode(oldBatch);
+ }
+
+ public String prompt()
+ {
+ String state = _state.toString();
+ if (state != null && state.length() != 0)
+ {
+ return state + ":bdb$ ";
+ }
+ else
+ {
+ return "bdb$ ";
+ }
+ }
+
+ /**
+ * Execute the command.
+ *
+ * @param args [command, arg0, arg1...].
+ */
+ protected void exec(String[] args)
+ {
+ // Comment lines start with a #
+ if (args.length == 0 || args[0].startsWith("#"))
+ {
+ return;
+ }
+
+ final String command = args[0];
+
+ Command cmd = _commands.get(command);
+
+ if (cmd == null)
+ {
+ _console.println("Command not understood: " + command);
+ }
+ else
+ {
+ cmd.execute(args);
+ }
+ }
+
+
+ /**
+ * Displays usage info.
+ */
+ protected static void help()
+ {
+ System.out.println(BOILER_PLATE);
+ System.out.println("Usage: java " + MessageStoreTool.class + " [Options]");
+ System.out.println(" [-c <broker config file>] : Defaults to \"$QPID_HOME/etc/config.xml\"");
+ }
+
+
+ /**
+ * This class is used to store the current state of the tool.
+ *
+ * This is then interrogated by the various commands to augment their behaviour.
+ *
+ *
+ */
+ public class State
+ {
+ private VirtualHost _vhost = null;
+ private AMQQueue _queue = null;
+ private Exchange _exchange = null;
+ private java.util.List<Long> _msgids = null;
+
+ public State()
+ {
+ }
+
+ public void setQueue(AMQQueue queue)
+ {
+ _queue = queue;
+ }
+
+ public AMQQueue getQueue()
+ {
+ return _queue;
+ }
+
+ public void setVhost(VirtualHost vhost)
+ {
+ _vhost = vhost;
+ }
+
+ public VirtualHost getVhost()
+ {
+ return _vhost;
+ }
+
+ public Exchange getExchange()
+ {
+ return _exchange;
+ }
+
+ public void setExchange(Exchange exchange)
+ {
+ _exchange = exchange;
+ }
+
+ public String toString()
+ {
+ StringBuilder status = new StringBuilder();
+
+ if (_vhost != null)
+ {
+ status.append(_vhost.getName());
+
+ if (_exchange != null)
+ {
+ status.append("[");
+ status.append(_exchange.getName());
+ status.append("]");
+
+ if (_queue != null)
+ {
+ status.append("->'");
+ status.append(_queue.getName());
+ status.append("'");
+
+ if (_msgids != null)
+ {
+ status.append(printMessages());
+ }
+ }
+ }
+ }
+
+ return status.toString();
+ }
+
+
+ public String printMessages()
+ {
+ StringBuilder sb = new StringBuilder();
+
+ Long previous = null;
+
+ Long start = null;
+ for (Long id : _msgids)
+ {
+ if (previous != null)
+ {
+ if (id == previous + 1)
+ {
+ if (start == null)
+ {
+ start = previous;
+ }
+ }
+ else
+ {
+ if (start != null)
+ {
+ sb.append(",");
+ sb.append(start);
+ sb.append("-");
+ sb.append(id);
+ start = null;
+ }
+ else
+ {
+ sb.append(",");
+ sb.append(previous);
+ }
+ }
+ }
+
+ previous = id;
+ }
+
+ if (start != null)
+ {
+ sb.append(",");
+ sb.append(start);
+ sb.append("-");
+ sb.append(_msgids.get(_msgids.size() - 1));
+ }
+ else
+ {
+ sb.append(",");
+ sb.append(previous);
+ }
+
+ // surround list in ()
+ sb.replace(0, 1, "(");
+ sb.append(")");
+ return sb.toString();
+ }
+
+ public void clearAll()
+ {
+ _vhost = null;
+ clearExchange();
+ }
+
+ public void clearExchange()
+ {
+ _exchange = null;
+ clearQueue();
+ }
+
+ public void clearQueue()
+ {
+ _queue = null;
+ clearMessages();
+ }
+
+ public void clearMessages()
+ {
+ _msgids = null;
+ }
+
+ /**
+ * A common location to provide parsing of the message id string
+ * utilised by a number of the commands.
+ * The String is comma separated list of ids that can be individual ids
+ * or a range (4-10)
+ *
+ * @param msgString string of msg ids to parse 1,2,4-10
+ */
+ public void setMessages(String msgString)
+ {
+ StringTokenizer tok = new StringTokenizer(msgString, ",");
+
+ if (tok.hasMoreTokens())
+ {
+ _msgids = new LinkedList<Long>();
+ }
+
+ while (tok.hasMoreTokens())
+ {
+ String next = tok.nextToken();
+ if (next.contains("-"))
+ {
+ Long start = Long.parseLong(next.substring(0, next.indexOf("-")));
+ Long end = Long.parseLong(next.substring(next.indexOf("-") + 1));
+
+ if (end >= start)
+ {
+ for (long l = start; l <= end; l++)
+ {
+ _msgids.add(l);
+ }
+ }
+ }
+ else
+ {
+ _msgids.add(Long.parseLong(next));
+ }
+ }
+
+ }
+
+ public void setMessages(java.util.List<Long> msgids)
+ {
+ _msgids = msgids;
+ }
+
+ public java.util.List<Long> getMessages()
+ {
+ return _msgids;
+ }
+ }//Class State
+
+}//Class MessageStoreTool
diff --git a/java/broker/src/main/java/org/apache/qpid/tools/messagestore/commands/AbstractCommand.java b/java/broker/src/main/java/org/apache/qpid/tools/messagestore/commands/AbstractCommand.java
new file mode 100644
index 0000000000..5444197cb4
--- /dev/null
+++ b/java/broker/src/main/java/org/apache/qpid/tools/messagestore/commands/AbstractCommand.java
@@ -0,0 +1,66 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT 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.tools.messagestore.commands;
+
+import org.apache.qpid.tools.messagestore.MessageStoreTool;
+import org.apache.qpid.tools.utils.Console;
+
+public abstract class AbstractCommand implements Command
+{
+ protected Console _console;
+ protected MessageStoreTool _tool;
+
+ public AbstractCommand(MessageStoreTool tool)
+ {
+ _console = tool.getConsole();
+ _tool = tool;
+ }
+
+ public void setOutput(Console out)
+ {
+ _console = out;
+ }
+
+ protected void commandError(String message, String[] args)
+ {
+ _console.print(getCommand() + " : " + message);
+
+ if (args != null)
+ {
+ for (int i = 1; i < args.length; i++)
+ {
+ _console.print(args[i]);
+ }
+ }
+ _console.println("");
+ _console.println(help());
+ }
+
+
+ public abstract String help();
+
+ public abstract String usage();
+
+ public abstract String getCommand();
+
+
+ public abstract void execute(String... args);
+}
diff --git a/java/broker/src/main/java/org/apache/qpid/tools/messagestore/commands/Clear.java b/java/broker/src/main/java/org/apache/qpid/tools/messagestore/commands/Clear.java
new file mode 100644
index 0000000000..b0006b3fe6
--- /dev/null
+++ b/java/broker/src/main/java/org/apache/qpid/tools/messagestore/commands/Clear.java
@@ -0,0 +1,85 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT 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.tools.messagestore.commands;
+
+import org.apache.qpid.tools.messagestore.MessageStoreTool;
+
+public class Clear extends AbstractCommand
+{
+ public Clear(MessageStoreTool tool)
+ {
+ super(tool);
+ }
+
+ public String help()
+ {
+ return "Clears any selection.";
+ }
+
+ public String usage()
+ {
+ return "clear [ all | virtualhost | exchange | queue | msgs ]";
+ }
+
+ public String getCommand()
+ {
+ return "clear";
+ }
+
+ public void execute(String... args)
+ {
+ assert args.length > 0;
+ assert args[0].equals(getCommand());
+
+ if (args.length < 1)
+ {
+ doClose("all");
+ }
+ else
+ {
+ doClose(args[1]);
+ }
+ }
+
+ private void doClose(String type)
+ {
+ if (type.equals("virtualhost")
+ || type.equals("all"))
+ {
+ _tool.getState().clearAll();
+ }
+
+ if (type.equals("exchange"))
+ {
+ _tool.getState().clearExchange();
+ }
+
+ if (type.equals("queue"))
+ {
+ _tool.getState().clearQueue();
+ }
+
+ if (type.equals("msgs"))
+ {
+ _tool.getState().clearMessages();
+ }
+ }
+}
diff --git a/java/integrationtests/src/main/java/org/apache/qpid/interop/coordinator/ListeningCoordinatorTest.java b/java/broker/src/main/java/org/apache/qpid/tools/messagestore/commands/Command.java
index 1b4461f8c2..bfa775a34a 100644
--- a/java/integrationtests/src/main/java/org/apache/qpid/interop/coordinator/ListeningCoordinatorTest.java
+++ b/java/broker/src/main/java/org/apache/qpid/tools/messagestore/commands/Command.java
@@ -18,11 +18,19 @@
*
*
*/
-package org.apache.qpid.interop.coordinator;
+package org.apache.qpid.tools.messagestore.commands;
-import javax.jms.Message;
+import org.apache.qpid.tools.utils.Console;
-public interface ListeningCoordinatorTest
+public interface Command
{
- public void latejoin(Message message);
+ public void setOutput(Console out);
+
+ public String help();
+
+ public abstract String usage();
+
+ String getCommand();
+
+ public void execute(String... args);
}
diff --git a/java/broker/src/main/java/org/apache/qpid/tools/messagestore/commands/Copy.java b/java/broker/src/main/java/org/apache/qpid/tools/messagestore/commands/Copy.java
new file mode 100644
index 0000000000..96ecb36952
--- /dev/null
+++ b/java/broker/src/main/java/org/apache/qpid/tools/messagestore/commands/Copy.java
@@ -0,0 +1,56 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ *
+ */
+package org.apache.qpid.tools.messagestore.commands;
+
+import org.apache.qpid.server.queue.AMQQueue;
+import org.apache.qpid.server.store.StoreContext;
+import org.apache.qpid.tools.messagestore.MessageStoreTool;
+
+public class Copy extends Move
+{
+ public Copy(MessageStoreTool tool)
+ {
+ super(tool);
+ }
+
+ public String help()
+ {
+ return "Copy messages between queues.\n" +
+ "The currently selected message set will be copied to the specifed queue.\n" +
+ "Alternatively the values can be provided on the command line.";
+ }
+
+ public String usage()
+ {
+ return "copy to=<queue> [from=<queue>] [msgids=<msgids eg, 1,2,4-10>]";
+ }
+
+ public String getCommand()
+ {
+ return "copy";
+ }
+
+ protected void doCommand(AMQQueue fromQueue, long start, long end, AMQQueue toQueue, StoreContext storeContext)
+ {
+ fromQueue.copyMessagesToAnotherQueue(start, end, toQueue.getName().toString(), storeContext);
+ }
+
+}
diff --git a/java/broker/src/main/java/org/apache/qpid/tools/messagestore/commands/Dump.java b/java/broker/src/main/java/org/apache/qpid/tools/messagestore/commands/Dump.java
new file mode 100644
index 0000000000..eea53252c6
--- /dev/null
+++ b/java/broker/src/main/java/org/apache/qpid/tools/messagestore/commands/Dump.java
@@ -0,0 +1,299 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT 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.tools.messagestore.commands;
+
+import org.apache.commons.codec.binary.Hex;
+import org.apache.mina.common.ByteBuffer;
+import org.apache.qpid.framing.abstraction.ContentChunk;
+import org.apache.qpid.server.queue.AMQMessage;
+import org.apache.qpid.tools.messagestore.MessageStoreTool;
+import org.apache.qpid.tools.utils.Console;
+
+import java.io.UnsupportedEncodingException;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+
+public class Dump extends Show
+{
+ private static final int LINE_SIZE = 8;
+ private static final String DEFAULT_ENCODING = "utf-8";
+ private static final boolean SPACE_BYTES = true;
+ private static final String BYTE_SPACER = " ";
+ private static final String NON_PRINTING_ASCII_CHAR = "?";
+
+ protected boolean _content = true;
+
+ public Dump(MessageStoreTool tool)
+ {
+ super(tool);
+ }
+
+ public String help()
+ {
+ return "Dump selected message content. Default: show=content";
+ }
+
+ public String usage()
+ {
+ return getCommand() + " [show=[all],[msgheaders],[_amqHeaders],[routing],[content]] [id=<msgid e.g. 1,2,4-10>]";
+ }
+
+ public String getCommand()
+ {
+ return "dump";
+ }
+
+ public void execute(String... args)
+ {
+ assert args.length > 0;
+ assert args[0].equals(getCommand());
+
+
+ if (args.length >= 2)
+ {
+ for (String arg : args)
+ {
+ if (arg.startsWith("show="))
+ {
+ _content = arg.contains("content") || arg.contains("all");
+ }
+ }
+
+ parseArgs(args);
+ }
+
+ performShow();
+ }
+
+
+ protected List<List> createMessageData(java.util.List<Long> msgids, List<AMQMessage> messages, boolean showHeaders, boolean showRouting,
+ boolean showMessageHeaders)
+ {
+
+ List<List> display = new LinkedList<List>();
+
+ List<String> hex = new LinkedList<String>();
+ List<String> ascii = new LinkedList<String>();
+ display.add(hex);
+ display.add(ascii);
+
+ for (AMQMessage msg : messages)
+ {
+ if (!includeMsg(msg, msgids))
+ {
+ continue;
+ }
+
+ //Add divider between messages
+ hex.add(Console.ROW_DIVIDER);
+ ascii.add(Console.ROW_DIVIDER);
+
+ // Show general message information
+ hex.add(Show.Columns.ID.name());
+ ascii.add(msg.getMessageId().toString());
+
+ hex.add(Console.ROW_DIVIDER);
+ ascii.add(Console.ROW_DIVIDER);
+
+ if (showRouting)
+ {
+ addShowInformation(hex, ascii, msg, "Routing Details", true, false, false);
+ }
+ if (showHeaders)
+ {
+ addShowInformation(hex, ascii, msg, "Headers", false, true, false);
+ }
+ if (showMessageHeaders)
+ {
+ addShowInformation(hex, ascii, msg, null, false, false, true);
+ }
+
+ // Add Content Body seciont
+ hex.add("Content Body");
+ ascii.add("");
+ hex.add(Console.ROW_DIVIDER);
+ ascii.add(Console.ROW_DIVIDER);
+
+ Iterator bodies = msg.getContentBodyIterator();
+ if (bodies.hasNext())
+ {
+
+ hex.add("Hex");
+ hex.add(Console.ROW_DIVIDER);
+
+
+ ascii.add("ASCII");
+ ascii.add(Console.ROW_DIVIDER);
+
+ while (bodies.hasNext())
+ {
+ ContentChunk chunk = (ContentChunk) bodies.next();
+
+ //Duplicate so we don't destroy original data :)
+ ByteBuffer hexBuffer = chunk.getData().duplicate();
+
+ ByteBuffer charBuffer = hexBuffer.duplicate();
+
+ Hex hexencoder = new Hex();
+
+ while (hexBuffer.hasRemaining())
+ {
+ byte[] line = new byte[LINE_SIZE];
+
+ int bufsize = hexBuffer.remaining();
+ if (bufsize < LINE_SIZE)
+ {
+ hexBuffer.get(line, 0, bufsize);
+ }
+ else
+ {
+ bufsize = line.length;
+ hexBuffer.get(line);
+ }
+
+ byte[] encoded = hexencoder.encode(line);
+
+ try
+ {
+ String encStr = new String(encoded, 0, bufsize * 2, DEFAULT_ENCODING);
+ String hexLine = "";
+
+ int strKength = encStr.length();
+ for (int c = 0; c < strKength; c++)
+ {
+ hexLine += encStr.charAt(c);
+
+ if (c % 2 == 1 && SPACE_BYTES)
+ {
+ hexLine += BYTE_SPACER;
+ }
+ }
+
+ hex.add(hexLine);
+ }
+ catch (UnsupportedEncodingException e)
+ {
+ _console.println(e.getMessage());
+ return null;
+ }
+ }
+
+ while (charBuffer.hasRemaining())
+ {
+ String asciiLine = "";
+
+ for (int pos = 0; pos < LINE_SIZE; pos++)
+ {
+ if (charBuffer.hasRemaining())
+ {
+ byte ch = charBuffer.get();
+
+ if (isPrintable(ch))
+ {
+ asciiLine += (char) ch;
+ }
+ else
+ {
+ asciiLine += NON_PRINTING_ASCII_CHAR;
+ }
+
+ if (SPACE_BYTES)
+ {
+ asciiLine += BYTE_SPACER;
+ }
+ }
+ else
+ {
+ break;
+ }
+ }
+
+ ascii.add(asciiLine);
+ }
+ }
+ }
+ else
+ {
+ List<String> result = new LinkedList<String>();
+
+ display.add(result);
+ result.add("No ContentBodies");
+ }
+ }
+
+ // if hex is empty then we have no data to display
+ if (hex.size() == 0)
+ {
+ return null;
+ }
+
+ return display;
+ }
+
+ private void addShowInformation(List<String> column1, List<String> column2, AMQMessage msg,
+ String title, boolean routing, boolean headers, boolean messageHeaders)
+ {
+ List<AMQMessage> single = new LinkedList<AMQMessage>();
+ single.add(msg);
+
+ List<List> routingData = super.createMessageData(null, single, headers, routing, messageHeaders);
+
+ //Reformat data
+ if (title != null)
+ {
+ column1.add(title);
+ column2.add("");
+ column1.add(Console.ROW_DIVIDER);
+ column2.add(Console.ROW_DIVIDER);
+ }
+
+ // look at all columns in the routing Data
+ for (List item : routingData)
+ {
+ // the item should be:
+ // Title
+ // *divider
+ // value
+ // otherwise we can't reason about the correct value
+ if (item.size() == 3)
+ {
+ //Filter out the columns we are not interested in.
+
+ String columnName = item.get(0).toString();
+
+ if (!(columnName.equals(Show.Columns.ID.name())
+ || columnName.equals(Show.Columns.Size.name())))
+ {
+ column1.add(columnName);
+ column2.add(item.get(2).toString());
+ }
+ }
+ }
+ column1.add(Console.ROW_DIVIDER);
+ column2.add(Console.ROW_DIVIDER);
+ }
+
+ private boolean isPrintable(byte c)
+ {
+ return c > 31 && c < 127;
+ }
+}
diff --git a/java/broker/src/main/java/org/apache/qpid/tools/messagestore/commands/Help.java b/java/broker/src/main/java/org/apache/qpid/tools/messagestore/commands/Help.java
new file mode 100644
index 0000000000..0f9546541b
--- /dev/null
+++ b/java/broker/src/main/java/org/apache/qpid/tools/messagestore/commands/Help.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.tools.messagestore.commands;
+
+import org.apache.qpid.tools.messagestore.MessageStoreTool;
+import org.apache.qpid.tools.utils.Console;
+
+import java.util.LinkedList;
+import java.util.Map;
+
+public class Help extends AbstractCommand
+{
+ public Help(MessageStoreTool tool)
+ {
+ super(tool);
+ }
+
+ public String help()
+ {
+ return "Provides detailed help on commands.";
+ }
+
+ public String getCommand()
+ {
+ return "help";
+ }
+
+ public String usage()
+ {
+ return "help [<command>]";
+ }
+
+ public void execute(String... args)
+ {
+ assert args.length > 0;
+ assert args[0].equals(getCommand());
+
+ if (args.length > 1)
+ {
+ Command command = _tool.getCommands().get(args[1]);
+ if (command != null)
+ {
+ _console.println(command.help());
+ _console.println("Usage:" + command.usage());
+ }
+ else
+ {
+ commandError("Command not found: ", args);
+ }
+ }
+ else
+ {
+ java.util.List<java.util.List> data = new LinkedList<java.util.List>();
+
+ java.util.List<String> commandName = new LinkedList<String>();
+ java.util.List<String> commandDescription = new LinkedList<String>();
+
+ data.add(commandName);
+ data.add(commandDescription);
+
+ //Set up Headers
+ commandName.add("Command");
+ commandDescription.add("Description");
+
+ commandName.add(Console.ROW_DIVIDER);
+ commandDescription.add(Console.ROW_DIVIDER);
+
+ //Add current Commands with descriptions
+ Map<String, Command> commands = _tool.getCommands();
+
+ for (Command command : commands.values())
+ {
+ commandName.add(command.getCommand());
+ commandDescription.add(command.help());
+ }
+
+ _console.printMap("Available Commands", data);
+ }
+ }
+}
diff --git a/java/broker/src/main/java/org/apache/qpid/tools/messagestore/commands/List.java b/java/broker/src/main/java/org/apache/qpid/tools/messagestore/commands/List.java
new file mode 100644
index 0000000000..df8b59ec19
--- /dev/null
+++ b/java/broker/src/main/java/org/apache/qpid/tools/messagestore/commands/List.java
@@ -0,0 +1,314 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT 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.tools.messagestore.commands;
+
+import org.apache.qpid.framing.AMQShortString;
+import org.apache.qpid.server.exchange.Exchange;
+import org.apache.qpid.server.queue.AMQQueue;
+import org.apache.qpid.server.registry.ApplicationRegistry;
+import org.apache.qpid.server.virtualhost.VirtualHost;
+import org.apache.qpid.tools.messagestore.MessageStoreTool;
+import org.apache.qpid.tools.utils.Console;
+
+import java.util.Collection;
+import java.util.LinkedList;
+
+public class List extends AbstractCommand
+{
+
+ public List(MessageStoreTool tool)
+ {
+ super(tool);
+ }
+
+ public void setOutput(Console out)
+ {
+ _console = out;
+ }
+
+ public String help()
+ {
+ return "list available items.";
+ }
+
+ public String usage()
+ {
+ return "list queues [<exchange>] | exchanges | bindings [<exchange>] | all";
+ }
+
+ public String getCommand()
+ {
+ return "list";
+ }
+
+ public void execute(String... args)
+ {
+ assert args.length > 0;
+ assert args[0].equals(getCommand());
+
+ if (args.length > 1)
+ {
+ if ((args[1].equals("exchanges"))
+ || (args[1].equals("queues"))
+ || (args[1].equals("bindings"))
+ || (args[1].equals("all")))
+ {
+ if (args.length == 2)
+ {
+ doList(args[1]);
+ }
+ else if (args.length == 3)
+ {
+ doList(args[1], args[2]);
+ }
+ }
+ else
+ {
+ commandError("Unknown options. ", args);
+ }
+ }
+ else if (args.length < 2)
+ {
+ doList("all");
+ }
+ else
+ {
+ doList(args[1]);
+ }
+ }
+
+ private void doList(String... listItem)
+ {
+ if (_tool.getState().getVhost() == null)
+ {
+ _console.println("No Virtualhost open. Open a Virtualhost first.");
+ listVirtualHosts();
+ return;
+ }
+
+ VirtualHost vhost = _tool.getState().getVhost();
+
+ java.util.List<String> data = null;
+
+ if (listItem[0].equals("queues"))
+ {
+ if (listItem.length > 1)
+ {
+ data = listQueues(vhost, new AMQShortString(listItem[1]));
+ }
+ else
+ {
+ Exchange exchange = _tool.getState().getExchange();
+ data = listQueues(vhost, exchange);
+ }
+ }
+
+ if (listItem[0].equals("exchanges"))
+ {
+ data = listExchanges(vhost);
+ }
+
+ if (listItem[0].equals("bindings"))
+ {
+
+ if (listItem.length > 1)
+ {
+ data = listBindings(vhost, new AMQShortString(listItem[1]));
+ }
+ else
+ {
+ Exchange exchange = _tool.getState().getExchange();
+
+ data = listBindings(vhost, exchange);
+ }
+ }
+
+ if (data != null)
+ {
+ if (data.size() == 1)
+ {
+ _console.println("No '" + listItem[0] + "' to display,");
+ }
+ else
+ {
+ _console.displayList(true, data.toArray(new String[0]));
+ }
+ }
+
+
+ if (listItem[0].equals("all"))
+ {
+
+ boolean displayed = false;
+ Exchange exchange = _tool.getState().getExchange();
+
+ //Do the display here for each one so that they are pretty printed
+ data = listQueues(vhost, exchange);
+ if (data != null)
+ {
+ displayed = true;
+ _console.displayList(true, data.toArray(new String[0]));
+ }
+
+ if (exchange == null)
+ {
+ data = listExchanges(vhost);
+ if (data != null)
+ {
+ displayed = true;
+ _console.displayList(true, data.toArray(new String[0]));
+ }
+ }
+
+ data = listBindings(vhost, exchange);
+ if (data != null)
+ {
+ displayed = true;
+ _console.displayList(true, data.toArray(new String[0]));
+ }
+
+ if (!displayed)
+ {
+ _console.println("Nothing to list");
+ }
+ }
+ }
+
+ private void listVirtualHosts()
+ {
+ Collection<VirtualHost> vhosts = ApplicationRegistry.getInstance()
+ .getVirtualHostRegistry().getVirtualHosts();
+
+ String[] data = new String[vhosts.size() + 1];
+
+ data[0] = "Available VirtualHosts";
+
+ int index = 1;
+ for (VirtualHost vhost : vhosts)
+ {
+ data[index] = vhost.getName();
+ index++;
+ }
+
+ _console.displayList(true, data);
+ }
+
+ private java.util.List<String> listBindings(VirtualHost vhost, AMQShortString exchangeName)
+ {
+ return listBindings(vhost, vhost.getExchangeRegistry().getExchange(exchangeName));
+ }
+
+ private java.util.List<String> listBindings(VirtualHost vhost, Exchange exchange)
+ {
+ Collection<AMQShortString> queues = vhost.getQueueRegistry().getQueueNames();
+
+ if (queues == null || queues.size() == 0)
+ {
+ return null;
+ }
+
+ java.util.List<String> data = new LinkedList<String>();
+
+ data.add("Current Bindings");
+
+ for (AMQShortString queue : queues)
+ {
+ if (exchange != null)
+ {
+ if (exchange.isBound(queue))
+ {
+ data.add(queue.toString());
+ }
+ }
+ else
+ {
+ data.add(queue.toString());
+ }
+ }
+
+ return data;
+ }
+
+ private java.util.List<String> listExchanges(VirtualHost vhost)
+ {
+ Collection<AMQShortString> queues = vhost.getExchangeRegistry().getExchangeNames();
+
+ if (queues == null || queues.size() == 0)
+ {
+ return null;
+ }
+
+ java.util.List<String> data = new LinkedList<String>();
+
+ data.add("Available Exchanges");
+
+ for (AMQShortString queue : queues)
+ {
+ data.add(queue.toString());
+ }
+
+ return data;
+ }
+
+ private java.util.List<String> listQueues(VirtualHost vhost, AMQShortString exchangeName)
+ {
+ return listQueues(vhost, vhost.getExchangeRegistry().getExchange(exchangeName));
+ }
+
+ private java.util.List<String> listQueues(VirtualHost vhost, Exchange exchange)
+ {
+ Collection<AMQQueue> queues = vhost.getQueueRegistry().getQueues();
+
+ if (queues == null || queues.size() == 0)
+ {
+ return null;
+ }
+
+ java.util.List<String> data = new LinkedList<String>();
+
+ data.add("Available Queues");
+
+ for (AMQQueue queue : queues)
+ {
+ if (exchange != null)
+ {
+ if (exchange.isBound(queue))
+ {
+ data.add(queue.getName().toString());
+ }
+ }
+ else
+ {
+ data.add(queue.getName().toString());
+ }
+ }
+
+ if (exchange != null)
+ {
+ if (queues.size() == 1)
+ {
+ return null;
+ }
+ }
+
+ return data;
+ }
+}
diff --git a/java/broker/src/main/java/org/apache/qpid/tools/messagestore/commands/Load.java b/java/broker/src/main/java/org/apache/qpid/tools/messagestore/commands/Load.java
new file mode 100644
index 0000000000..244a311c30
--- /dev/null
+++ b/java/broker/src/main/java/org/apache/qpid/tools/messagestore/commands/Load.java
@@ -0,0 +1,94 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT 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.tools.messagestore.commands;
+
+import org.apache.qpid.configuration.Configuration;
+import org.apache.qpid.tools.messagestore.MessageStoreTool;
+
+public class Load extends AbstractCommand
+{
+ public Load(MessageStoreTool tool)
+ {
+ super(tool);
+ }
+
+ public String help()
+ {
+ return "Loads specified broker configuration file.";
+ }
+
+ public String usage()
+ {
+ return "load <configuration file>";
+ }
+
+ public String getCommand()
+ {
+ return "load";
+ }
+
+ public void execute(String... args)
+ {
+ assert args.length > 0;
+ assert args[0].equals(getCommand());
+
+ if (args.length > 2)
+ {
+ _console.print("load " + args[1] + ": additional options not understood:");
+ for (int i = 2; i < args.length; i++)
+ {
+ _console.print(args[i] + " ");
+ }
+ _console.println("");
+ }
+ else if (args.length < 2)
+ {
+ _console.println("Enter Configuration file.");
+ String input = _console.readln();
+ if (input != null)
+ {
+ doLoad(input);
+ }
+ else
+ {
+ _console.println("Did not recognise config file.");
+ }
+ }
+ else
+ {
+ doLoad(args[1]);
+ }
+ }
+
+ private void doLoad(String configfile)
+ {
+ _console.println("Loading Configuration:" + configfile);
+
+ try
+ {
+ _tool.setConfigurationFile(configfile);
+ }
+ catch (Configuration.InitException e)
+ {
+ _console.println("Unable to open config file due to: '" + e.getMessage() + "'");
+ }
+ }
+}
diff --git a/java/broker/src/main/java/org/apache/qpid/tools/messagestore/commands/Move.java b/java/broker/src/main/java/org/apache/qpid/tools/messagestore/commands/Move.java
new file mode 100644
index 0000000000..a9497fd23e
--- /dev/null
+++ b/java/broker/src/main/java/org/apache/qpid/tools/messagestore/commands/Move.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.tools.messagestore.commands;
+
+import org.apache.qpid.framing.AMQShortString;
+import org.apache.qpid.server.queue.AMQQueue;
+import org.apache.qpid.server.store.StoreContext;
+import org.apache.qpid.tools.messagestore.MessageStoreTool;
+
+import java.util.List;
+
+public class Move extends AbstractCommand
+{
+
+ /**
+ * Since the Coopy command is not associated with a real channel we can safely create our own store context
+ * for use in the few methods that require one.
+ */
+ private StoreContext _storeContext = new StoreContext();
+
+ public Move(MessageStoreTool tool)
+ {
+ super(tool);
+ }
+
+ public String help()
+ {
+ return "Move messages between queues.\n" +
+ "The currently selected message set will be moved to the specifed queue.\n" +
+ "Alternatively the values can be provided on the command line.";
+ }
+
+ public String usage()
+ {
+ return "move to=<queue> [from=<queue>] [msgids=<msgids eg, 1,2,4-10>]";
+ }
+
+ public String getCommand()
+ {
+ return "move";
+ }
+
+ public void execute(String... args)
+ {
+ AMQQueue toQueue = null;
+ AMQQueue fromQueue = _tool.getState().getQueue();
+ java.util.List<Long> msgids = _tool.getState().getMessages();
+
+ if (args.length >= 2)
+ {
+ for (String arg : args)
+ {
+ if (arg.startsWith("to="))
+ {
+ String queueName = arg.substring(arg.indexOf("=") + 1);
+ toQueue = _tool.getState().getVhost().getQueueRegistry().getQueue(new AMQShortString(queueName));
+ }
+
+ if (arg.startsWith("from="))
+ {
+ String queueName = arg.substring(arg.indexOf("=") + 1);
+ fromQueue = _tool.getState().getVhost().getQueueRegistry().getQueue(new AMQShortString(queueName));
+ }
+
+ if (arg.startsWith("msgids="))
+ {
+ String msgidStr = arg.substring(arg.indexOf("=") + 1);
+
+ // Record the current message selection
+ java.util.List<Long> currentIDs = _tool.getState().getMessages();
+
+ // Use the ToolState class to perform the messasge parsing
+ _tool.getState().setMessages(msgidStr);
+ msgids = _tool.getState().getMessages();
+
+ // Reset the original selection of messages
+ _tool.getState().setMessages(currentIDs);
+ }
+ }
+ }
+
+ if (!checkRequirements(fromQueue, toQueue, msgids))
+ {
+ return;
+ }
+
+ processIDs(fromQueue, toQueue, msgids);
+ }
+
+ private void processIDs(AMQQueue fromQueue, AMQQueue toQueue, java.util.List<Long> msgids)
+ {
+ Long previous = null;
+ Long start = null;
+
+ for (long id : msgids)
+ {
+ if (previous != null)
+ {
+ if (id == previous + 1)
+ {
+ if (start == null)
+ {
+ start = previous;
+ }
+ }
+ else
+ {
+ if (start != null)
+ {
+ //move a range of ids
+ doCommand(fromQueue, start, id, toQueue, _storeContext);
+ }
+ else
+ {
+ //move a single id
+ doCommand(fromQueue, id, id, toQueue, _storeContext);
+ }
+ }
+ }
+
+ previous = id;
+ }
+ }
+
+ protected boolean checkRequirements(AMQQueue fromQueue, AMQQueue toQueue, List<Long> msgids)
+ {
+ if (toQueue == null)
+ {
+ _console.println("Destination queue not specifed.");
+ _console.println(usage());
+ return false;
+ }
+
+ if (fromQueue == null)
+ {
+ _console.println("Source queue not specifed.");
+ _console.println(usage());
+ return false;
+ }
+
+ return true;
+ }
+
+ protected void doCommand(AMQQueue fromQueue, long start, long id, AMQQueue toQueue, StoreContext storeContext)
+ {
+ fromQueue.moveMessagesToAnotherQueue(start, id, toQueue.getName().toString(), _storeContext);
+ }
+}
diff --git a/java/broker/src/main/java/org/apache/qpid/tools/messagestore/commands/Purge.java b/java/broker/src/main/java/org/apache/qpid/tools/messagestore/commands/Purge.java
new file mode 100644
index 0000000000..7154159b40
--- /dev/null
+++ b/java/broker/src/main/java/org/apache/qpid/tools/messagestore/commands/Purge.java
@@ -0,0 +1,68 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT 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.tools.messagestore.commands;
+
+import org.apache.qpid.server.queue.AMQQueue;
+import org.apache.qpid.server.store.StoreContext;
+import org.apache.qpid.tools.messagestore.MessageStoreTool;
+
+public class Purge extends Move
+{
+ public Purge(MessageStoreTool tool)
+ {
+ super(tool);
+ }
+
+ public String help()
+ {
+ return "Purge messages from a queue.\n" +
+ "The currently selected message set will be purged from the specifed queue.\n" +
+ "Alternatively the values can be provided on the command line.";
+ }
+
+ public String usage()
+ {
+ return "purge from=<queue> [msgids=<msgids eg, 1,2,4-10>]";
+ }
+
+ public String getCommand()
+ {
+ return "purge";
+ }
+
+
+ protected boolean checkRequirements(AMQQueue fromQueue, AMQQueue toQueue, java.util.List<Long> msgids)
+ {
+ if (fromQueue == null)
+ {
+ _console.println("Source queue not specifed.");
+ _console.println(usage());
+ return false;
+ }
+
+ return true;
+ }
+
+ protected void doCommand(AMQQueue fromQueue, long start, long end, AMQQueue toQueue, StoreContext storeContext)
+ {
+ fromQueue.removeMessagesFromQueue(start, end, storeContext);
+ }
+}
diff --git a/java/broker/src/main/java/org/apache/qpid/tools/messagestore/commands/Quit.java b/java/broker/src/main/java/org/apache/qpid/tools/messagestore/commands/Quit.java
new file mode 100644
index 0000000000..a81bc07c38
--- /dev/null
+++ b/java/broker/src/main/java/org/apache/qpid/tools/messagestore/commands/Quit.java
@@ -0,0 +1,54 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ *
+ */
+package org.apache.qpid.tools.messagestore.commands;
+
+import org.apache.qpid.tools.messagestore.MessageStoreTool;
+
+public class Quit extends AbstractCommand
+{
+ public Quit(MessageStoreTool tool)
+ {
+ super(tool);
+ }
+
+ public String help()
+ {
+ return "Quit the tool.";
+ }
+
+ public String usage()
+ {
+ return "quit";
+ }
+
+ public String getCommand()
+ {
+ return "quit";
+ }
+
+ public void execute(String... args)
+ {
+ assert args.length > 0;
+ assert args[0].equals("quit");
+
+ _tool.quit();
+ }
+}
diff --git a/java/broker/src/main/java/org/apache/qpid/tools/messagestore/commands/Select.java b/java/broker/src/main/java/org/apache/qpid/tools/messagestore/commands/Select.java
new file mode 100644
index 0000000000..5e9b7028e9
--- /dev/null
+++ b/java/broker/src/main/java/org/apache/qpid/tools/messagestore/commands/Select.java
@@ -0,0 +1,233 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT 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.tools.messagestore.commands;
+
+import org.apache.qpid.framing.AMQShortString;
+import org.apache.qpid.server.exchange.Exchange;
+import org.apache.qpid.server.queue.AMQQueue;
+import org.apache.qpid.server.registry.ApplicationRegistry;
+import org.apache.qpid.server.virtualhost.VirtualHost;
+import org.apache.qpid.tools.messagestore.MessageStoreTool;
+
+import java.util.LinkedList;
+import java.util.StringTokenizer;
+
+public class Select extends AbstractCommand
+{
+
+ public Select(MessageStoreTool tool)
+ {
+ super(tool);
+ }
+
+ public String help()
+ {
+ return "Perform a selection.";
+ }
+
+ public String usage()
+ {
+ return "select virtualhost <name> |exchange <name> |queue <name> | msgs id=<msgids eg. 1,2,4-10>";
+ }
+
+ public String getCommand()
+ {
+ return "select";
+ }
+
+ public void execute(String... args)
+ {
+ assert args.length > 2;
+ assert args[0].equals("select");
+
+ if (args.length < 3)
+ {
+ if (args[1].equals("show"))
+ {
+ doSelect(args[1], null);
+ }
+ else
+ {
+ _console.print("select : unknown command:");
+ _console.println(help());
+ }
+ }
+ else
+ {
+ if (args[1].equals("virtualhost")
+ || args[1].equals("vhost")
+ || args[1].equals("exchange")
+ || args[1].equals("queue")
+ || args[1].equals("msg")
+ )
+ {
+ doSelect(args[1], args[2]);
+ }
+ else
+ {
+ _console.println(help());
+ }
+ }
+ }
+
+ private void doSelect(String type, String item)
+ {
+ if (type.equals("virtualhost"))
+ {
+
+ VirtualHost vhost = ApplicationRegistry.getInstance()
+ .getVirtualHostRegistry().getVirtualHost(item);
+
+ if (vhost == null)
+ {
+ _console.println("Virtualhost '" + item + "' not found.");
+ }
+ else
+ {
+ _tool.getState().setVhost(vhost);
+ }
+ }
+
+ if (type.equals("exchange"))
+ {
+
+ VirtualHost vhost = _tool.getState().getVhost();
+
+ if (vhost == null)
+ {
+ _console.println("No Virtualhost open. Open a Virtualhost first.");
+ return;
+ }
+
+
+ Exchange exchange = vhost.getExchangeRegistry().getExchange(new AMQShortString(item));
+
+ if (exchange == null)
+ {
+ _console.println("Exchange '" + item + "' not found.");
+ }
+ else
+ {
+ _tool.getState().setExchange(exchange);
+ }
+
+ if (_tool.getState().getQueue() != null)
+ {
+ if (!exchange.isBound(_tool.getState().getQueue()))
+ {
+ _tool.getState().setQueue(null);
+ }
+ }
+ }
+
+ if (type.equals("queue"))
+ {
+ VirtualHost vhost = _tool.getState().getVhost();
+
+ if (vhost == null)
+ {
+ _console.println("No Virtualhost open. Open a Virtualhost first.");
+ return;
+ }
+
+ AMQQueue queue = vhost.getQueueRegistry().getQueue(new AMQShortString(item));
+
+ if (queue == null)
+ {
+ _console.println("Queue '" + item + "' not found.");
+ }
+ else
+ {
+ _tool.getState().setQueue(queue);
+
+ if (_tool.getState().getExchange() == null)
+ {
+ for (AMQShortString exchangeName : vhost.getExchangeRegistry().getExchangeNames())
+ {
+ Exchange exchange = vhost.getExchangeRegistry().getExchange(exchangeName);
+ if (exchange.isBound(queue))
+ {
+ _tool.getState().setExchange(exchange);
+ break;
+ }
+ }
+ }
+
+ //remove the message selection
+ _tool.getState().setMessages((java.util.List<Long>) null);
+ }
+ }
+
+ if (type.equals("msg"))
+ {
+ if (item.startsWith("id="))
+ {
+ StringTokenizer tok = new StringTokenizer(item.substring(item.indexOf("=") + 1), ",");
+
+ java.util.List<Long> msgids = null;
+
+ if (tok.hasMoreTokens())
+ {
+ msgids = new LinkedList<Long>();
+ }
+
+ while (tok.hasMoreTokens())
+ {
+ String next = tok.nextToken();
+ if (next.contains("-"))
+ {
+ Long start = Long.parseLong(next.substring(0, next.indexOf("-")));
+ Long end = Long.parseLong(next.substring(next.indexOf("-") + 1));
+
+ if (end >= start)
+ {
+ for (long l = start; l <= end; l++)
+ {
+ msgids.add(l);
+ }
+ }
+ }
+ else
+ {
+ msgids.add(Long.parseLong(next));
+ }
+ }
+
+ _tool.getState().setMessages(msgids);
+ }
+
+ }
+
+ if (type.equals("show"))
+ {
+ _console.println(_tool.getState().toString());
+ if (_tool.getState().getMessages() != null)
+ {
+ _console.print("Msgs:");
+ for (Long l : _tool.getState().getMessages())
+ {
+ _console.print(" " + l);
+ }
+ _console.println("");
+ }
+ }
+ }
+}
diff --git a/java/broker/src/main/java/org/apache/qpid/tools/messagestore/commands/Show.java b/java/broker/src/main/java/org/apache/qpid/tools/messagestore/commands/Show.java
new file mode 100644
index 0000000000..5988cdabfc
--- /dev/null
+++ b/java/broker/src/main/java/org/apache/qpid/tools/messagestore/commands/Show.java
@@ -0,0 +1,513 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT 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.tools.messagestore.commands;
+
+import org.apache.qpid.AMQException;
+import org.apache.qpid.framing.AMQShortString;
+import org.apache.qpid.framing.BasicContentHeaderProperties;
+import org.apache.qpid.framing.FieldTable;
+import org.apache.qpid.framing.abstraction.MessagePublishInfo;
+import org.apache.qpid.server.queue.AMQMessage;
+import org.apache.qpid.server.queue.AMQQueue;
+import org.apache.qpid.tools.messagestore.MessageStoreTool;
+import org.apache.qpid.tools.utils.Console;
+
+import java.util.LinkedList;
+import java.util.List;
+import java.util.StringTokenizer;
+
+public class Show extends AbstractCommand
+{
+ protected boolean _amqHeaders = false;
+ protected boolean _routing = false;
+ protected boolean _msgHeaders = false;
+
+ public Show(MessageStoreTool tool)
+ {
+ super(tool);
+ }
+
+ public String help()
+ {
+ return "Shows the messages headers.";
+ }
+
+ public String usage()
+ {
+ return getCommand() + " [show=[all],[msgheaders],[amqheaders],[routing]] [id=<msgid e.g. 1,2,4-10>]";
+ }
+
+ public String getCommand()
+ {
+ return "show";
+ }
+
+ public void execute(String... args)
+ {
+ assert args.length > 0;
+ assert args[0].equals(getCommand());
+
+ if (args.length < 2)
+ {
+ parseArgs("all");
+ }
+ else
+ {
+ parseArgs(args);
+ }
+
+ performShow();
+ }
+
+ protected void parseArgs(String... args)
+ {
+ List<Long> msgids = null;
+
+ if (args.length >= 2)
+ {
+ for (String arg : args)
+ {
+ if (arg.startsWith("show="))
+ {
+ _msgHeaders = arg.contains("msgheaders") || arg.contains("all");
+ _amqHeaders = arg.contains("amqheaders") || arg.contains("all");
+ _routing = arg.contains("routing") || arg.contains("all");
+ }
+
+ if (arg.startsWith("id="))
+ {
+ _tool.getState().setMessages(msgids);
+ }
+ }//for args
+ }// if args > 2
+ }
+
+ protected void performShow()
+ {
+ if (_tool.getState().getVhost() == null)
+ {
+ _console.println("No Virtualhost selected. 'DuSelect' a Virtualhost first.");
+ return;
+ }
+
+ AMQQueue _queue = _tool.getState().getQueue();
+
+ List<Long> msgids = _tool.getState().getMessages();
+
+ if (_queue != null)
+ {
+ List<AMQMessage> messages = _queue.getMessagesOnTheQueue();
+ if (messages == null || messages.size() == 0)
+ {
+ _console.println("No messages on queue");
+ return;
+ }
+
+ List<List> data = createMessageData(msgids, messages, _amqHeaders, _routing, _msgHeaders);
+ if (data != null)
+ {
+ _console.printMap(null, data);
+ }
+ else
+ {
+ String message = "No data to display.";
+ if (msgids != null)
+ {
+ message += " Is message selection correct? " + _tool.getState().printMessages();
+ }
+ _console.println(message);
+ }
+
+ }
+ else
+ {
+ _console.println("No Queue specified to show.");
+ }
+ }
+
+ /**
+ * Create the list data for display from the messages.
+ *
+ * @param msgids The list of message ids to display
+ * @param messages A list of messages to format and display.
+ * @param showHeaders should the header info be shown
+ * @param showRouting show the routing info be shown
+ * @param showMessageHeaders show the msg headers be shown
+ * @return the formated data lists for printing
+ */
+ protected List<List> createMessageData(List<Long> msgids, List<AMQMessage> messages, boolean showHeaders, boolean showRouting,
+ boolean showMessageHeaders)
+ {
+
+ // Currenly exposed message properties
+// //Printing the content Body
+// msg.getContentBodyIterator();
+// //Print the Headers
+// ((BasicContentHeaderProperties)msg.getContentHeaderBody().properties).getAppId();
+// ((BasicContentHeaderProperties)msg.getContentHeaderBody().properties).getAppIdAsString();
+// ((BasicContentHeaderProperties)msg.getContentHeaderBody().properties).getClusterId();
+// ((BasicContentHeaderProperties)msg.getContentHeaderBody().properties).getContentType();
+// ((BasicContentHeaderProperties)msg.getContentHeaderBody().properties).getCorrelationId();
+// ((BasicContentHeaderProperties)msg.getContentHeaderBody().properties).getDeliveryMode();
+// ((BasicContentHeaderProperties)msg.getContentHeaderBody().properties).getEncoding();
+// ((BasicContentHeaderProperties)msg.getContentHeaderBody().properties).getExpiration();
+// ((BasicContentHeaderProperties)msg.getContentHeaderBody().properties).getHeaders();
+// ((BasicContentHeaderProperties)msg.getContentHeaderBody().properties).getMessageId();
+// ((BasicContentHeaderProperties)msg.getContentHeaderBody().properties).getPriority();
+// ((BasicContentHeaderProperties)msg.getContentHeaderBody().properties).getPropertyFlags();
+// ((BasicContentHeaderProperties)msg.getContentHeaderBody().properties).getReplyTo();
+// ((BasicContentHeaderProperties)msg.getContentHeaderBody().properties).getTimestamp();
+// ((BasicContentHeaderProperties)msg.getContentHeaderBody().properties).getType();
+// ((BasicContentHeaderProperties)msg.getContentHeaderBody().properties).getUserId();
+//
+// //Print out all the property names
+// ((BasicContentHeaderProperties)msg.getContentHeaderBody().properties).getHeaders().getPropertyNames();
+//
+// msg.getMessageId();
+// msg.getSize();
+// msg.getArrivalTime();
+
+// msg.getDeliveredSubscription();
+// msg.getDeliveredToConsumer();
+// msg.getMessageHandle();
+// msg.getMessageId();
+// msg.getMessagePublishInfo();
+// msg.getPublisher();
+
+// msg.getStoreContext();
+// msg.isAllContentReceived();
+// msg.isPersistent();
+// msg.isRedelivered();
+// msg.isRejectedBy();
+// msg.isTaken();
+
+ //Header setup
+
+ List<List> data = new LinkedList<List>();
+
+ List<String> id = new LinkedList<String>();
+ data.add(id);
+ id.add(Columns.ID.name());
+ id.add(Console.ROW_DIVIDER);
+
+ List<String> exchange = new LinkedList<String>();
+ List<String> routingkey = new LinkedList<String>();
+ List<String> immediate = new LinkedList<String>();
+ List<String> mandatory = new LinkedList<String>();
+ if (showRouting)
+ {
+ data.add(exchange);
+ exchange.add(Columns.Exchange.name());
+ exchange.add(Console.ROW_DIVIDER);
+
+ data.add(routingkey);
+ routingkey.add(Columns.RoutingKey.name());
+ routingkey.add(Console.ROW_DIVIDER);
+
+ data.add(immediate);
+ immediate.add(Columns.isImmediate.name());
+ immediate.add(Console.ROW_DIVIDER);
+
+ data.add(mandatory);
+ mandatory.add(Columns.isMandatory.name());
+ mandatory.add(Console.ROW_DIVIDER);
+ }
+
+ List<String> size = new LinkedList<String>();
+ List<String> appid = new LinkedList<String>();
+ List<String> clusterid = new LinkedList<String>();
+ List<String> contenttype = new LinkedList<String>();
+ List<String> correlationid = new LinkedList<String>();
+ List<String> deliverymode = new LinkedList<String>();
+ List<String> encoding = new LinkedList<String>();
+ List<String> arrival = new LinkedList<String>();
+ List<String> expiration = new LinkedList<String>();
+ List<String> priority = new LinkedList<String>();
+ List<String> propertyflag = new LinkedList<String>();
+ List<String> replyto = new LinkedList<String>();
+ List<String> timestamp = new LinkedList<String>();
+ List<String> type = new LinkedList<String>();
+ List<String> userid = new LinkedList<String>();
+ List<String> ispersitent = new LinkedList<String>();
+ List<String> isredelivered = new LinkedList<String>();
+ List<String> isdelivered = new LinkedList<String>();
+
+ data.add(size);
+ size.add(Columns.Size.name());
+ size.add(Console.ROW_DIVIDER);
+
+ if (showHeaders)
+ {
+ data.add(ispersitent);
+ ispersitent.add(Columns.isPersistent.name());
+ ispersitent.add(Console.ROW_DIVIDER);
+
+ data.add(isredelivered);
+ isredelivered.add(Columns.isRedelivered.name());
+ isredelivered.add(Console.ROW_DIVIDER);
+
+ data.add(isdelivered);
+ isdelivered.add(Columns.isDelivered.name());
+ isdelivered.add(Console.ROW_DIVIDER);
+
+ data.add(appid);
+ appid.add(Columns.App_ID.name());
+ appid.add(Console.ROW_DIVIDER);
+
+ data.add(clusterid);
+ clusterid.add(Columns.Cluster_ID.name());
+ clusterid.add(Console.ROW_DIVIDER);
+
+ data.add(contenttype);
+ contenttype.add(Columns.Content_Type.name());
+ contenttype.add(Console.ROW_DIVIDER);
+
+ data.add(correlationid);
+ correlationid.add(Columns.Correlation_ID.name());
+ correlationid.add(Console.ROW_DIVIDER);
+
+ data.add(deliverymode);
+ deliverymode.add(Columns.Delivery_Mode.name());
+ deliverymode.add(Console.ROW_DIVIDER);
+
+ data.add(encoding);
+ encoding.add(Columns.Encoding.name());
+ encoding.add(Console.ROW_DIVIDER);
+
+ data.add(arrival);
+ expiration.add(Columns.Arrival.name());
+ expiration.add(Console.ROW_DIVIDER);
+
+ data.add(expiration);
+ expiration.add(Columns.Expiration.name());
+ expiration.add(Console.ROW_DIVIDER);
+
+ data.add(priority);
+ priority.add(Columns.Priority.name());
+ priority.add(Console.ROW_DIVIDER);
+
+ data.add(propertyflag);
+ propertyflag.add(Columns.Property_Flag.name());
+ propertyflag.add(Console.ROW_DIVIDER);
+
+ data.add(replyto);
+ replyto.add(Columns.ReplyTo.name());
+ replyto.add(Console.ROW_DIVIDER);
+
+ data.add(timestamp);
+ timestamp.add(Columns.Timestamp.name());
+ timestamp.add(Console.ROW_DIVIDER);
+
+ data.add(type);
+ type.add(Columns.Type.name());
+ type.add(Console.ROW_DIVIDER);
+
+ data.add(userid);
+ userid.add(Columns.UserID.name());
+ userid.add(Console.ROW_DIVIDER);
+ }
+
+ List<String> msgHeaders = new LinkedList<String>();
+ if (showMessageHeaders)
+ {
+ data.add(msgHeaders);
+ msgHeaders.add(Columns.MsgHeaders.name());
+ msgHeaders.add(Console.ROW_DIVIDER);
+ }
+
+ //Add create the table of data
+ for (AMQMessage msg : messages)
+ {
+ if (!includeMsg(msg, msgids))
+ {
+ continue;
+ }
+
+ id.add(msg.getMessageId().toString());
+
+ size.add("" + msg.getSize());
+
+ arrival.add("" + msg.getArrivalTime());
+
+ try
+ {
+ ispersitent.add(msg.isPersistent() ? "true" : "false");
+ }
+ catch (AMQException e)
+ {
+ ispersitent.add("n/a");
+ }
+
+ isredelivered.add(msg.isRedelivered() ? "true" : "false");
+
+ isdelivered.add(msg.getDeliveredToConsumer() ? "true" : "false");
+
+// msg.getMessageHandle();
+
+ BasicContentHeaderProperties headers = null;
+
+ try
+ {
+ headers = ((BasicContentHeaderProperties) msg.getContentHeaderBody().properties);
+ }
+ catch (AMQException e)
+ {
+ //ignore
+// commandError("Unable to read properties for message: " + e.getMessage(), null);
+ }
+
+ if (headers != null)
+ {
+ String appidS = headers.getAppIdAsString();
+ appid.add(appidS == null ? "null" : appidS);
+
+ String clusterS = headers.getClusterIdAsString();
+ clusterid.add(clusterS == null ? "null" : clusterS);
+
+ String contentS = headers.getContentTypeAsString();
+ contenttype.add(contentS == null ? "null" : contentS);
+
+ String correlationS = headers.getCorrelationIdAsString();
+ correlationid.add(correlationS == null ? "null" : correlationS);
+
+ deliverymode.add("" + headers.getDeliveryMode());
+
+ AMQShortString encodeSS = headers.getEncoding();
+ encoding.add(encodeSS == null ? "null" : encodeSS.toString());
+
+ expiration.add("" + headers.getExpiration());
+
+ FieldTable headerFT = headers.getHeaders();
+ msgHeaders.add(headerFT == null ? "none" : "" + headerFT.toString());
+
+ priority.add("" + headers.getPriority());
+ propertyflag.add("" + headers.getPropertyFlags());
+
+ AMQShortString replytoSS = headers.getReplyTo();
+ replyto.add(replytoSS == null ? "null" : replytoSS.toString());
+
+ timestamp.add("" + headers.getTimestamp());
+
+ AMQShortString typeSS = headers.getType();
+ type.add(typeSS == null ? "null" : typeSS.toString());
+
+ AMQShortString useridSS = headers.getUserId();
+ userid.add(useridSS == null ? "null" : useridSS.toString());
+
+ MessagePublishInfo info = null;
+ try
+ {
+ info = msg.getMessagePublishInfo();
+ }
+ catch (AMQException e)
+ {
+ //ignore
+ }
+
+ if (info != null)
+ {
+ AMQShortString exchangeSS = info.getExchange();
+ exchange.add(exchangeSS == null ? "null" : exchangeSS.toString());
+
+ AMQShortString routingkeySS = info.getRoutingKey();
+ routingkey.add(routingkeySS == null ? "null" : routingkeySS.toString());
+
+ immediate.add(info.isImmediate() ? "true" : "false");
+ mandatory.add(info.isMandatory() ? "true" : "false");
+ }
+
+// msg.getPublisher(); -- only used in clustering
+// msg.getStoreContext();
+// msg.isAllContentReceived();
+
+ }// if headers!=null
+
+// need to access internal map and do lookups.
+// msg.isTaken();
+// msg.getDeliveredSubscription();
+// msg.isRejectedBy();
+
+ }
+
+ // if id only had the header and the divider in it then we have no data to display
+ if (id.size() == 2)
+ {
+ return null;
+ }
+ return data;
+ }
+
+ protected boolean includeMsg(AMQMessage msg, List<Long> msgids)
+ {
+ if (msgids == null)
+ {
+ return true;
+ }
+
+ Long msgid = msg.getMessageId();
+
+ boolean found = false;
+
+ if (msgids != null)
+ {
+ //check msgid is in msgids
+ for (Long l : msgids)
+ {
+ if (l.equals(msgid))
+ {
+ found = true;
+ break;
+ }
+ }
+ }
+ return found;
+ }
+
+ public enum Columns
+ {
+ ID,
+ Size,
+ Exchange,
+ RoutingKey,
+ isImmediate,
+ isMandatory,
+ isPersistent,
+ isRedelivered,
+ isDelivered,
+ App_ID,
+ Cluster_ID,
+ Content_Type,
+ Correlation_ID,
+ Delivery_Mode,
+ Encoding,
+ Arrival,
+ Expiration,
+ Priority,
+ Property_Flag,
+ ReplyTo,
+ Timestamp,
+ Type,
+ UserID,
+ MsgHeaders
+ }
+}
+
+
diff --git a/java/broker/src/main/java/org/apache/qpid/server/security/Passwd.java b/java/broker/src/main/java/org/apache/qpid/tools/security/Passwd.java
index f9e093dba7..c27c52eb8e 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/security/Passwd.java
+++ b/java/broker/src/main/java/org/apache/qpid/tools/security/Passwd.java
@@ -18,7 +18,7 @@
*
*
*/
-package org.apache.qpid.server.security;
+package org.apache.qpid.tools.security;
import org.apache.commons.codec.binary.Base64;
diff --git a/java/broker/src/main/java/org/apache/qpid/tools/utils/CommandParser.java b/java/broker/src/main/java/org/apache/qpid/tools/utils/CommandParser.java
new file mode 100644
index 0000000000..986fea32cc
--- /dev/null
+++ b/java/broker/src/main/java/org/apache/qpid/tools/utils/CommandParser.java
@@ -0,0 +1,51 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ *
+ */
+package org.apache.qpid.tools.utils;
+
+public interface CommandParser
+{
+ /**
+ * If there is more than one command received on the last parse request.
+ *
+ * Subsequent calls to parse will utilise this input rather than reading new data from the input source
+ * @return boolean
+ */
+ boolean more();
+
+ /**
+ * True if the currently parsed command has been requested as a background operation
+ *
+ * @return boolean
+ */
+ boolean isBackground();
+
+ /**
+ * Parses user commands, and groups tokens in the
+ * String[] format that all Java main's love.
+ *
+ * If more than one command is provided in one input line then the more() method will return true.
+ * A subsequent call to parse() will continue to parse that input line before reading new input.
+ *
+ * @return <code>input</code> split in args[] format; null if eof.
+ * @throws java.io.IOException if there is a problem reading from the input stream
+ */
+ String[] parse() throws java.io.IOException;
+}
diff --git a/java/broker/src/main/java/org/apache/qpid/tools/utils/Console.java b/java/broker/src/main/java/org/apache/qpid/tools/utils/Console.java
new file mode 100644
index 0000000000..cf457d1ea5
--- /dev/null
+++ b/java/broker/src/main/java/org/apache/qpid/tools/utils/Console.java
@@ -0,0 +1,90 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ *
+ */
+package org.apache.qpid.tools.utils;
+
+import java.util.List;
+
+public interface Console
+{
+ public enum CellFormat
+ {
+ CENTRED, LEFT, RIGHT
+ }
+
+ public static String ROW_DIVIDER = "*divider";
+
+ public void print(String... message);
+
+ public void println(String... message);
+
+ public String readln();
+
+ /**
+ * Reads and parses the command line.
+ *
+ *
+ * @return The next command or null
+ */
+ public String[] readCommand();
+
+ public CommandParser getCommandParser();
+
+ public void setCommandParser(CommandParser parser);
+
+ /**
+ *
+ * Prints the list of String nicely.
+ *
+ * +-------------+
+ * | Heading |
+ * +-------------+
+ * | Item 1 |
+ * | Item 2 |
+ * | Item 3 |
+ * +-------------+
+ *
+ * @param hasTitle should list[0] be used as a heading
+ * @param list The list of Strings to display
+ */
+ public void displayList(boolean hasTitle, String... list);
+
+ /**
+ *
+ * Prints the list of String nicely.
+ *
+ * +----------------------------+
+ * | Heading |
+ * +----------------------------+
+ * | title | title | ..
+ * +----------------------------+
+ * | Item 2 | value 2 | ..
+ * +----------------------------+ (*divider)
+ * | Item 3 | value 2 | ..
+ * +----------------------------+
+ *
+ * @param title The title to display if any
+ * @param entries the entries to display in a map.
+ */
+ void printMap(String title, List<List> entries);
+
+
+ public void close();
+}
diff --git a/java/broker/src/main/java/org/apache/qpid/tools/utils/SimpleCommandParser.java b/java/broker/src/main/java/org/apache/qpid/tools/utils/SimpleCommandParser.java
new file mode 100644
index 0000000000..09444ccdd7
--- /dev/null
+++ b/java/broker/src/main/java/org/apache/qpid/tools/utils/SimpleCommandParser.java
@@ -0,0 +1,121 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT 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.tools.utils;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.util.StringTokenizer;
+
+public class SimpleCommandParser implements CommandParser
+{
+ private static final String COMMAND_SEPERATOR = ";";
+
+ /** Input source of commands */
+ protected BufferedReader _reader;
+
+ /** The next list of commands from the command line */
+ private StringBuilder _nextCommand = null;
+
+ public SimpleCommandParser(BufferedReader reader)
+ {
+ _reader = reader;
+ }
+
+ public boolean more()
+ {
+ return _nextCommand != null;
+ }
+
+ public boolean isBackground()
+ {
+ return false;
+ }
+
+ public String[] parse() throws IOException
+ {
+ String[] commands = null;
+
+ String input = null;
+
+ if (_nextCommand == null)
+ {
+ input = _reader.readLine();
+ }
+ else
+ {
+ input = _nextCommand.toString();
+ _nextCommand = null;
+ }
+
+ if (input == null)
+ {
+ return null;
+ }
+
+ StringTokenizer tok = new StringTokenizer(input, " ");
+
+ int tokenCount = tok.countTokens();
+ int index = 0;
+
+ if (tokenCount > 0)
+ {
+ commands = new String[tokenCount];
+ boolean commandComplete = false;
+
+ while (tok.hasMoreTokens())
+ {
+ String next = tok.nextToken();
+
+ if (next.equals(COMMAND_SEPERATOR))
+ {
+ commandComplete = true;
+ _nextCommand = new StringBuilder();
+ continue;
+ }
+
+ if (commandComplete)
+ {
+ _nextCommand.append(next);
+ _nextCommand.append(" ");
+ }
+ else
+ {
+ commands[index] = next;
+ index++;
+ }
+ }
+
+ }
+
+ //Reduce the String[] if not all the tokens were used in this command.
+ // i.e. there is more than one command on the line.
+ if (index != tokenCount)
+ {
+ String[] shortCommands = new String[index];
+ System.arraycopy(commands, 0, shortCommands, 0, index);
+ return shortCommands;
+ }
+ else
+ {
+ return commands;
+ }
+ }
+}
diff --git a/java/broker/src/main/java/org/apache/qpid/tools/utils/SimpleConsole.java b/java/broker/src/main/java/org/apache/qpid/tools/utils/SimpleConsole.java
new file mode 100644
index 0000000000..ec080a4611
--- /dev/null
+++ b/java/broker/src/main/java/org/apache/qpid/tools/utils/SimpleConsole.java
@@ -0,0 +1,363 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT 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.tools.utils;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.BufferedReader;
+import java.io.BufferedWriter;
+import java.io.IOException;
+import java.util.LinkedList;
+import java.util.List;
+
+public class SimpleConsole implements Console
+{
+ /** SLF4J Logger. */
+ private static Logger _devlog = LoggerFactory.getLogger(SimpleConsole.class);
+
+ /** Console Writer. */
+ protected static BufferedWriter _consoleWriter;
+
+ /** Console Reader. */
+ protected static BufferedReader _consoleReader;
+
+ /** Parser for command-line input. */
+ protected CommandParser _parser;
+
+ public SimpleConsole(BufferedWriter writer, BufferedReader reader)
+ {
+ _consoleWriter = writer;
+ _consoleReader = reader;
+ _parser = new SimpleCommandParser(_consoleReader);
+ }
+
+ public void print(String... message)
+ {
+ try
+ {
+ for (String s : message)
+ {
+ _consoleWriter.write(s);
+ }
+ _consoleWriter.flush();
+ }
+ catch (IOException e)
+ {
+ _devlog.error(e.getMessage() + ": Occured whilst trying to write:" + message);
+ }
+
+ }
+
+ public void println(String... message)
+ {
+ print(message);
+ print(System.getProperty("line.separator"));
+ }
+
+
+ public String readln()
+ {
+ try
+ {
+ return _consoleReader.readLine();
+ }
+ catch (IOException e)
+ {
+ _devlog.debug("Unable to read input due to:" + e.getMessage());
+ return null;
+ }
+ }
+
+ public String[] readCommand()
+ {
+ try
+ {
+ return _parser.parse();
+ }
+ catch (IOException e)
+ {
+ _devlog.error("Error reading command:" + e.getMessage());
+ return new String[0];
+ }
+ }
+
+ public CommandParser getCommandParser()
+ {
+ return _parser;
+ }
+
+ public void setCommandParser(CommandParser parser)
+ {
+ _parser = parser;
+ }
+
+ public void displayList(boolean hasTitle, String... list)
+ {
+ java.util.List<java.util.List> data = new LinkedList<List>();
+
+ java.util.List<String> values = new LinkedList<String>();
+
+ data.add(values);
+
+ for (String value : list)
+ {
+ values.add(value);
+ }
+
+ if (hasTitle)
+ {
+ values.add(1, "*divider");
+ }
+
+ printMap(null, data);
+ }
+
+ /**
+ *
+ * Prints the list of String nicely.
+ *
+ * +----------------------------+
+ * | Heading |
+ * +----------------------------+
+ * | title | title | ..
+ * +----------------------------+
+ * | Item 2 | value 2 | ..
+ * | Item 3 | value 2 | ..
+ * +----------------------------+
+ *
+ * @param title The title to display if any
+ * @param entries the entries to display in a map.
+ */
+ public void printMap(String title, java.util.List<java.util.List> entries)
+ {
+ try
+ {
+ int columns = entries.size();
+
+ int[] columnWidth = new int[columns];
+
+ // calculate row count
+ int rowMax = 0;
+
+ //the longest item
+ int itemMax = 0;
+
+ for (int i = 0; i < columns; i++)
+ {
+ int columnIRowMax = entries.get(i).size();
+
+ if (columnIRowMax > rowMax)
+ {
+ rowMax = columnIRowMax;
+ }
+ for (Object values : entries.get(i))
+ {
+ if (values.toString().equals(Console.ROW_DIVIDER))
+ {
+ continue;
+ }
+
+ int itemLength = values.toString().length();
+
+ //note for single width
+ if (itemLength > itemMax)
+ {
+ itemMax = itemLength;
+ }
+
+ //note for mulit width
+ if (itemLength > columnWidth[i])
+ {
+ columnWidth[i] = itemLength;
+ }
+
+ }
+ }
+
+ int tableWidth = 0;
+
+
+ for (int i = 0; i < columns; i++)
+ {
+ // plus 2 for the space padding
+ columnWidth[i] += 2;
+ }
+ for (int size : columnWidth)
+ {
+ tableWidth += size;
+ }
+ tableWidth += (columns - 1);
+
+ if (title != null)
+ {
+ if (title.length() > tableWidth)
+ {
+ tableWidth = title.length();
+ }
+
+ printCellRow("+", "-", tableWidth);
+
+ printCell(CellFormat.CENTRED, "|", tableWidth, " " + title + " ", 0);
+ _consoleWriter.newLine();
+
+ }
+
+ //put top line | or bottom of title
+ printCellRow("+", "-", tableWidth);
+
+ //print the table data
+ int row = 0;
+
+ for (; row < rowMax; row++)
+ {
+ for (int i = 0; i < columns; i++)
+ {
+ java.util.List columnData = entries.get(i);
+
+ String value;
+ // does this column have a value for this row
+ if (columnData.size() > row)
+ {
+ value = " " + columnData.get(row).toString() + " ";
+ }
+ else
+ {
+ value = " ";
+ }
+
+ if (i == 0 && value.equals(" " + Console.ROW_DIVIDER + " "))
+ {
+ printCellRow("+", "-", tableWidth);
+ //move on to the next row
+ break;
+ }
+ else
+ {
+ printCell(CellFormat.LEFT, "|", columnWidth[i], value, i);
+ }
+
+ // if it is the last row then do a new line.
+ if (i == columns - 1)
+ {
+ _consoleWriter.newLine();
+ }
+ }
+ }
+
+ printCellRow("+", "-", tableWidth);
+
+ }
+ catch (IOException e)
+ {
+ _devlog.error(e.getMessage() + ": Occured whilst trying to write.");
+ }
+ }
+
+ public void close()
+ {
+
+ try
+ {
+ _consoleReader.close();
+ }
+ catch (IOException e)
+ {
+ _devlog.error(e.getMessage() + ": Occured whilst trying to close reader.");
+ }
+
+ try
+ {
+
+ _consoleWriter.close();
+ }
+ catch (IOException e)
+ {
+ _devlog.error(e.getMessage() + ": Occured whilst trying to close writer.");
+ }
+
+ }
+
+ private void printCell(CellFormat format, String edge, int cellWidth, String cell, int column) throws IOException
+ {
+ int pad = cellWidth - cell.length();
+
+ if (column == 0)
+ {
+ _consoleWriter.write(edge);
+ }
+
+ switch (format)
+ {
+ case CENTRED:
+ printPad(" ", pad / 2);
+ break;
+ case RIGHT:
+ printPad(" ", pad);
+ break;
+ }
+
+ _consoleWriter.write(cell);
+
+
+ switch (format)
+ {
+ case CENTRED:
+ // if pad isn't even put the extra one on the right
+ if (pad % 2 == 0)
+ {
+ printPad(" ", pad / 2);
+ }
+ else
+ {
+ printPad(" ", (pad / 2) + 1);
+ }
+ break;
+ case LEFT:
+ printPad(" ", pad);
+ break;
+ }
+
+
+ _consoleWriter.write(edge);
+
+ }
+
+ private void printCellRow(String edge, String mid, int cellWidth) throws IOException
+ {
+ _consoleWriter.write(edge);
+
+ printPad(mid, cellWidth);
+
+ _consoleWriter.write(edge);
+ _consoleWriter.newLine();
+ }
+
+ private void printPad(String padChar, int count) throws IOException
+ {
+ for (int i = 0; i < count; i++)
+ {
+ _consoleWriter.write(padChar);
+ }
+ }
+
+
+}
diff --git a/java/broker/src/main/java/org/apache/qpid/tools/utils/utils/CommandParser.java b/java/broker/src/main/java/org/apache/qpid/tools/utils/utils/CommandParser.java
new file mode 100644
index 0000000000..6a95529059
--- /dev/null
+++ b/java/broker/src/main/java/org/apache/qpid/tools/utils/utils/CommandParser.java
@@ -0,0 +1,51 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ *
+ */
+package com.redhat.etp.qpid.utils;
+
+public interface CommandParser
+{
+ /**
+ * If there is more than one command received on the last parse request.
+ *
+ * Subsequent calls to parse will utilise this input rather than reading new data from the input source
+ * @return boolean
+ */
+ boolean more();
+
+ /**
+ * True if the currently parsed command has been requested as a background operation
+ *
+ * @return boolean
+ */
+ boolean isBackground();
+
+ /**
+ * Parses user commands, and groups tokens in the
+ * String[] format that all Java main's love.
+ *
+ * If more than one command is provided in one input line then the more() method will return true.
+ * A subsequent call to parse() will continue to parse that input line before reading new input.
+ *
+ * @return <code>input</code> split in args[] format; null if eof.
+ * @throws java.io.IOException if there is a problem reading from the input stream
+ */
+ String[] parse() throws java.io.IOException;
+}
diff --git a/java/broker/src/main/java/org/apache/qpid/tools/utils/utils/Console.java b/java/broker/src/main/java/org/apache/qpid/tools/utils/utils/Console.java
new file mode 100644
index 0000000000..892a48254c
--- /dev/null
+++ b/java/broker/src/main/java/org/apache/qpid/tools/utils/utils/Console.java
@@ -0,0 +1,75 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT 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 com.redhat.etp.qpid;
+
+import java.util.List;
+
+public interface Console
+{
+ public enum CellFormat
+ {
+ CENTRED, LEFT, RIGHT
+ }
+
+ public static String ROW_DIVIDER = "*divider";
+
+ public void print(String... message);
+
+ public void println(String... message);
+
+ public String[] readln();
+
+ /**
+ *
+ * Prints the list of String nicely.
+ *
+ * +-------------+
+ * | Heading |
+ * +-------------+
+ * | Item 1 |
+ * | Item 2 |
+ * | Item 3 |
+ * +-------------+
+ *
+ * @param hasTitle should list[0] be used as a heading
+ * @param list The list of Strings to display
+ */
+ public void displayList(boolean hasTitle, String... list);
+
+ /**
+ *
+ * Prints the list of String nicely.
+ *
+ * +----------------------------+
+ * | Heading |
+ * +----------------------------+
+ * | title | title | ..
+ * +----------------------------+
+ * | Item 2 | value 2 | ..
+ * +----------------------------+ (*divider)
+ * | Item 3 | value 2 | ..
+ * +----------------------------+
+ *
+ * @param title The title to display if any
+ * @param entries the entries to display in a map.
+ */
+ void printMap(String title, List<List> entries);
+}
diff --git a/java/broker/src/main/java/org/apache/qpid/tools/utils/utils/RSHCommandParser.java b/java/broker/src/main/java/org/apache/qpid/tools/utils/utils/RSHCommandParser.java
new file mode 100644
index 0000000000..ea4045c917
--- /dev/null
+++ b/java/broker/src/main/java/org/apache/qpid/tools/utils/utils/RSHCommandParser.java
@@ -0,0 +1,352 @@
+/*
+ * The Java Shell: jsh core -- RELEASE: alpha3
+ * (C)1999 Osvaldo Pinali Doederlein.
+ *
+ * LICENSE
+ * =======
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * CHANGES
+ * =======
+ * 1.0.2 - Added support for non-quoted '\' escape char (Not interpreted by the shell)
+ * 1.0.1 - Added support for arguments in aliases
+ * 1.0.0 - Initial release; split from Shell and enhanced a lot.
+ *
+ * LINKS
+ * =====
+ * Contact: mailto@osvaldo.visionnaire.com.br, mailto@g.collin@appliweb.net
+ * Site #1: http://www.geocities.com/ResearchTriangle/Node/2005/
+ * Site #2: http://www.appliweb.net/jsh
+ */
+
+package com.redhat.etp.qpid.utils;
+
+import java.io.BufferedReader;
+import java.util.Vector;
+
+/**
+ * The Java Shell.
+ * <p>
+ * Provides an environment for launching and controlling Java apps.
+ * <p>
+ * TODO: - Support for applets!
+ * - Support for variable replacement
+ *
+ * @author Osvaldo Pinali Doederlein.
+ */
+public class RSHCommandParser implements CommandParser
+{
+ /** Where commands come from. */
+ protected BufferedReader reader;
+ /** Continuation for command line. */
+ protected String contLine = null;
+ /** Run next command in background? */
+ protected boolean background;
+ protected String[] env; // Commands passed in args.
+
+ public RSHCommandParser(BufferedReader reader)
+ {
+ this(reader, null);
+ }
+
+ public RSHCommandParser(BufferedReader reader, String env[])
+ {
+ this.reader = reader;
+ this.env = env;
+ if (env == null)
+ {
+ this.env = new String[0];
+ }
+ }
+
+
+ public boolean more()
+ {
+ return contLine != null;
+ }
+
+ public boolean isBackground()
+ {
+ return background;
+ }
+
+ /**
+ * Solves and expands aliases in an argument array.
+ * This expansion affects only the first (if any) argument; the
+ * typical thing to do, as we don't want to expand parameters.
+ * We recursively parse the result to be sure we expand everything.
+ * For example, an alias can be expanded to further aliases, or it can contains args.
+ *
+ * @param args Raw arguments.
+ * @return <code>args</code> resolved and expanded.
+ */
+ public static String[] expand(String[] args)
+ {
+ if (args.length > 0)
+ {
+ String expanded = args[0];//Alias.resolve(args[0]);
+
+ // Try to expand recursively the command line
+ if (expanded != args[0])
+ {
+ RSHCommandParser recurse = new RSHCommandParser(new BufferedReader(
+ new java.io.StringReader(expanded)));
+
+ try
+ {
+ String cmdLine[] = recurse.parse();
+ cmdLine = recurse.expand(cmdLine);
+
+ // do we need to handle new arguments and insert them in the command array ?
+ if (cmdLine.length > 1)
+ {
+ String[] newArgs = new String[cmdLine.length + args.length - 1];
+ System.arraycopy(cmdLine, 0, newArgs, 0, cmdLine.length);
+
+ if (args.length > 1)
+ {
+ System.arraycopy(args, 1, newArgs, cmdLine.length, args.length - 1);
+ }
+
+ args = newArgs;
+ }
+ else if (cmdLine.length == 1)
+ {
+ args[0] = cmdLine[0];
+ }
+ }
+ catch (java.io.IOException e)
+ {
+ }
+ }
+ }
+
+ return args;
+ }
+
+ public String[] parse() throws java.io.IOException
+ {
+ final int READ = 0, QUOTE = 1, SKIP = 2, ESCAPE = 3, NONQUOTEDESCAPE = 4, VARIABLE = 5;
+ final int EOF = 0xFFFF;
+ int mode = SKIP;
+ Vector<String> args = new Vector<String>();
+ StringBuffer current = new StringBuffer();
+ StringBuffer varName = null;
+ background = false;
+ String line;
+
+ if (contLine == null)
+ {
+ line = reader.readLine();
+ }
+ else
+ {
+ line = contLine;
+ contLine = null;
+ }
+
+ if (line == null)
+ {
+ reader = null;
+ return null;
+ }
+
+ for (int pos = 0; pos < line.length(); ++pos)
+ {
+ char c = line.charAt(pos);
+
+ switch (mode)
+ {
+ case SKIP:
+ switch (c)
+ {
+ case' ':
+ case'\t':
+ break;
+ case'\"':
+ mode = QUOTE;
+ break;
+ case'&':
+ background = true;
+ case';':
+ contLine = line.substring(pos + 1);
+ pos = line.length();
+ break;
+ default:
+ mode = READ;
+ --pos;
+ }
+ break;
+
+ case READ:
+ switch (c)
+ {
+ case'\"':
+ mode = QUOTE;
+ break;
+ case';':
+ case'&':
+ --pos;
+ case' ':
+ case'\t':
+ mode = SKIP;
+ break;
+ case'\\':
+ mode = NONQUOTEDESCAPE;
+ break;
+ case'$':
+ mode = VARIABLE;
+ varName = new StringBuffer();
+ break;
+ default:
+ current.append(c);
+ }
+ if ((mode != READ) && (mode != NONQUOTEDESCAPE))
+ {
+ args.addElement(current.toString());
+ current = new StringBuffer();
+ }
+ break;
+
+ case QUOTE:
+ switch (c)
+ {
+ case'\"':
+ mode = READ;
+ break;
+ case'\\':
+ mode = ESCAPE;
+ break;
+ default:
+ current.append(c);
+ }
+ break;
+
+ case ESCAPE:
+ switch (c)
+ {
+ case'n':
+ c = '\n';
+ break;
+ case'r':
+ c = '\r';
+ break;
+ case't':
+ c = '\t';
+ break;
+ case'b':
+ c = '\b';
+ break;
+ case'f':
+ c = '\f';
+ break;
+ default:
+ current.append('\\');
+ break;
+ }
+ mode = QUOTE;
+ current.append(c);
+ break;
+ case NONQUOTEDESCAPE:
+ switch (c)
+ {
+ case';':
+ mode = READ;
+ current.append(c);
+ break;
+ default: // This is not a escaped char.
+ mode = READ;
+ current.append('\\');
+ current.append(c);
+ break;
+ }
+ break;
+ case VARIABLE:
+ switch (c)
+ {
+ case'$':
+ {
+// String val = Set.get(new String(varName));
+// if (val != null)
+// {
+// current.append(val);
+// }
+ mode = READ;
+ break;
+ }
+ case'@':
+ {
+ StringBuffer val = new StringBuffer();
+ int i;
+ for (i = 0; i < env.length; i++)
+ {
+ val.append(env[i]);
+ val.append(' ');
+ }
+ current.append(val);
+ mode = READ;
+ break;
+ }
+ case'0':
+ case'1':
+ case'2':
+ case'3':
+ case'4':
+ case'5':
+ case'6':
+ case'7':
+ case'8':
+ case'9':
+ {
+ if (varName.length() == 0)
+ {
+ int value = Integer.parseInt(new String(new char[]{c}));
+ if (env.length > value)
+ {
+ current.append(env[value]);
+ }
+ mode = READ;
+ break;
+ }
+ // else fall back
+ }
+ default:
+ varName.append(c);
+ break;
+ }
+ break;
+ }
+ }
+
+ if (current.length() > 0)
+ {
+ args.addElement(current.toString());
+ }
+ return expand(toArray(args));
+ }
+
+ private String[] toArray(Vector strings)
+ {
+ String[] arr = new String[strings.size()];
+
+ for (int i = 0; i < strings.size(); ++i)
+ {
+ arr[i] = (String) strings.elementAt(i);
+ }
+
+ return arr;
+ }
+
+}
diff --git a/java/broker/src/main/java/org/apache/qpid/tools/utils/utils/SimpleCommandParser.java b/java/broker/src/main/java/org/apache/qpid/tools/utils/utils/SimpleCommandParser.java
new file mode 100644
index 0000000000..98e816554e
--- /dev/null
+++ b/java/broker/src/main/java/org/apache/qpid/tools/utils/utils/SimpleCommandParser.java
@@ -0,0 +1,116 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT 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 com.redhat.etp.qpid.utils;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.util.StringTokenizer;
+
+public class SimpleCommandParser implements CommandParser
+{
+ private static final String COMMAND_SEPERATOR = ";";
+
+ /** Input source of commands */
+ protected BufferedReader _reader;
+
+ /** The next list of commands from the command line */
+ private StringBuilder _nextCommand = null;
+
+ public SimpleCommandParser(BufferedReader reader)
+ {
+ _reader = reader;
+ }
+
+ public boolean more()
+ {
+ return _nextCommand != null;
+ }
+
+ public boolean isBackground()
+ {
+ return false;
+ }
+
+ public String[] parse() throws IOException
+ {
+ String[] commands = null;
+
+ String input = null;
+
+ if (_nextCommand == null)
+ {
+ input = _reader.readLine();
+ }
+ else
+ {
+ input = _nextCommand.toString();
+ _nextCommand = null;
+ }
+
+ StringTokenizer tok = new StringTokenizer(input, " ");
+
+ int tokenCount = tok.countTokens();
+ int index = 0;
+
+ if (tokenCount > 0)
+ {
+ commands = new String[tokenCount];
+ boolean commandComplete = false;
+
+ while (tok.hasMoreTokens())
+ {
+ String next = tok.nextToken();
+
+ if (next.equals(COMMAND_SEPERATOR))
+ {
+ commandComplete = true;
+ _nextCommand = new StringBuilder();
+ continue;
+ }
+
+ if (commandComplete)
+ {
+ _nextCommand.append(next);
+ _nextCommand.append(" ");
+ }
+ else
+ {
+ commands[index] = next;
+ index++;
+ }
+ }
+
+ }
+
+ //Reduce the String[] if not all the tokens were used in this command.
+ // i.e. there is more than one command on the line.
+ if (index != tokenCount)
+ {
+ String[] shortCommands = new String[index];
+ System.arraycopy(commands, 0, shortCommands, 0, index);
+ return shortCommands;
+ }
+ else
+ {
+ return commands;
+ }
+ }
+}
diff --git a/java/broker/src/test/java/org/apache/qpid/server/exchange/ExchangeMBeanTest.java b/java/broker/src/test/java/org/apache/qpid/server/exchange/ExchangeMBeanTest.java
index 9653155a51..3bca0a4545 100644
--- a/java/broker/src/test/java/org/apache/qpid/server/exchange/ExchangeMBeanTest.java
+++ b/java/broker/src/test/java/org/apache/qpid/server/exchange/ExchangeMBeanTest.java
@@ -1,18 +1,21 @@
/*
*
- * Copyright (c) 2006 The Apache Software Foundation
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
*
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
+ * http://www.apache.org/licenses/LICENSE-2.0
*
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT 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.exchange;
diff --git a/java/broker/src/test/java/org/apache/qpid/server/protocol/TestMinaProtocolSession.java b/java/broker/src/test/java/org/apache/qpid/server/protocol/TestMinaProtocolSession.java
index 89b0e068d9..0c0d8f471e 100644
--- a/java/broker/src/test/java/org/apache/qpid/server/protocol/TestMinaProtocolSession.java
+++ b/java/broker/src/test/java/org/apache/qpid/server/protocol/TestMinaProtocolSession.java
@@ -1,18 +1,21 @@
/*
*
- * Copyright (c) 2006 The Apache Software Foundation
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
*
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
+ * http://www.apache.org/licenses/LICENSE-2.0
*
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT 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;
diff --git a/java/broker/src/test/java/org/apache/qpid/server/queue/AMQQueueAlertTest.java b/java/broker/src/test/java/org/apache/qpid/server/queue/AMQQueueAlertTest.java
index a7e5c0d1d0..94d67848c6 100644
--- a/java/broker/src/test/java/org/apache/qpid/server/queue/AMQQueueAlertTest.java
+++ b/java/broker/src/test/java/org/apache/qpid/server/queue/AMQQueueAlertTest.java
@@ -1,18 +1,21 @@
/*
*
- * Copyright (c) 2006 The Apache Software Foundation
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
*
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
+ * http://www.apache.org/licenses/LICENSE-2.0
*
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT 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;
diff --git a/java/broker/src/test/java/org/apache/qpid/server/queue/AMQQueueMBeanTest.java b/java/broker/src/test/java/org/apache/qpid/server/queue/AMQQueueMBeanTest.java
index acd5e0772f..76b67314e6 100644
--- a/java/broker/src/test/java/org/apache/qpid/server/queue/AMQQueueMBeanTest.java
+++ b/java/broker/src/test/java/org/apache/qpid/server/queue/AMQQueueMBeanTest.java
@@ -1,18 +1,21 @@
/*
*
- * Copyright (c) 2006 The Apache Software Foundation
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
*
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
+ * http://www.apache.org/licenses/LICENSE-2.0
*
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT 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;
diff --git a/java/client/example/src/main/java/org/apache/qpid/example/publisher/MonitorMessageDispatcher.java b/java/client/example/src/main/java/org/apache/qpid/example/publisher/MonitorMessageDispatcher.java
index 8784d340da..b6544db995 100644
--- a/java/client/example/src/main/java/org/apache/qpid/example/publisher/MonitorMessageDispatcher.java
+++ b/java/client/example/src/main/java/org/apache/qpid/example/publisher/MonitorMessageDispatcher.java
@@ -18,18 +18,18 @@
*/
package org.apache.qpid.example.publisher;
-import org.apache.log4j.Logger;
import org.apache.log4j.BasicConfigurator;
+import org.apache.log4j.Logger;
-import javax.jms.*;
-
-import java.util.Properties;
+import javax.jms.DeliveryMode;
+import javax.jms.JMSException;
/**
- * Class that sends heartbeat messages to allow monitoring of message consumption
- * Sends regular (currently 20 seconds apart) heartbeat message
+ * Class that sends heartbeat messages to allow monitoring of message consumption Sends regular (currently 20 seconds
+ * apart) heartbeat message
*/
-public class MonitorMessageDispatcher {
+public class MonitorMessageDispatcher
+{
private static final Logger _logger = Logger.getLogger(MonitorMessageDispatcher.class);
@@ -39,17 +39,18 @@ public class MonitorMessageDispatcher {
/**
* Easy entry point for running a message dispatcher for monitoring consumption
+ *
* @param args
*/
public static void main(String[] args)
{
-
//Switch on logging appropriately for your app
BasicConfigurator.configure();
try
{
- while(true)
+ int i =0;
+ while (i < 1000)
{
try
{
@@ -62,9 +63,10 @@ public class MonitorMessageDispatcher {
}
//sleep for twenty seconds and then publish again - change if appropriate
- Thread.sleep(20000);
+ //Thread.sleep(1000);
+ i++ ;
}
- catch(UndeliveredMessageException a)
+ catch (UndeliveredMessageException a)
{
//trigger application specific failure handling here
_logger.error("Problem delivering monitor message");
@@ -72,7 +74,7 @@ public class MonitorMessageDispatcher {
}
}
}
- catch(Exception e)
+ catch (Exception e)
{
_logger.error("Error trying to dispatch AMS monitor message: " + e);
System.exit(1);
@@ -81,7 +83,7 @@ public class MonitorMessageDispatcher {
{
if (getMonitorPublisher() != null)
{
- getMonitorPublisher().cleanup();
+ getMonitorPublisher().cleanup();
}
}
@@ -90,19 +92,24 @@ public class MonitorMessageDispatcher {
/**
* Publish heartbeat message
+ *
* @throws JMSException
* @throws UndeliveredMessageException
*/
public static void publish() throws JMSException, UndeliveredMessageException
{
//Send the message generated from the payload using the _publisher
- getMonitorPublisher().sendImmediateMessage
- (FileMessageFactory.createSimpleEventMessage(getMonitorPublisher().getSession(),"monitor:" +System.currentTimeMillis()));
+// getMonitorPublisher().sendImmediateMessage
+// (FileMessageFactory.createSimpleEventMessage(getMonitorPublisher().getSession(),"monitor:" +System.currentTimeMillis()));
+
+ getMonitorPublisher().sendMessage
+ (getMonitorPublisher()._session,
+ FileMessageFactory.createSimpleEventMessage(getMonitorPublisher().getSession(), "monitor:" + System.currentTimeMillis()),
+ DeliveryMode.PERSISTENT, false, true);
+
}
- /**
- * Cleanup publishers
- */
+ /** Cleanup publishers */
public static void cleanup()
{
if (getMonitorPublisher() != null)
@@ -119,16 +126,16 @@ public class MonitorMessageDispatcher {
//Returns a _publisher for the monitor queue
private static MonitorPublisher getMonitorPublisher()
{
- if (_monitorPublisher != null)
- {
- return _monitorPublisher;
- }
+ if (_monitorPublisher != null)
+ {
+ return _monitorPublisher;
+ }
- //Create a _publisher using failover details and constant for monitor queue
- _monitorPublisher = new MonitorPublisher();
+ //Create a _publisher using failover details and constant for monitor queue
+ _monitorPublisher = new MonitorPublisher();
- _monitorPublisher.setName(MonitorMessageDispatcher.DEFAULT_MONITOR_PUB_NAME);
- return _monitorPublisher;
+ _monitorPublisher.setName(MonitorMessageDispatcher.DEFAULT_MONITOR_PUB_NAME);
+ return _monitorPublisher;
}
}
diff --git a/java/client/example/src/main/java/org/apache/qpid/example/publisher/MonitorPublisher.java b/java/client/example/src/main/java/org/apache/qpid/example/publisher/MonitorPublisher.java
index 233c3fea0a..a67b602e58 100644
--- a/java/client/example/src/main/java/org/apache/qpid/example/publisher/MonitorPublisher.java
+++ b/java/client/example/src/main/java/org/apache/qpid/example/publisher/MonitorPublisher.java
@@ -18,15 +18,17 @@
*/
package org.apache.qpid.example.publisher;
-import javax.jms.Message;
+import org.apache.log4j.Logger;
+import org.apache.qpid.client.BasicMessageProducer;
+
import javax.jms.DeliveryMode;
import javax.jms.JMSException;
-import org.apache.qpid.client.BasicMessageProducer;
-import org.apache.log4j.Logger;
+import javax.jms.Message;
+import javax.jms.Session;
/**
- * Subclass of Publisher which uses QPID functionality to send a heartbeat message
- * Note immediate flag not available via JMS MessageProducer
+ * Subclass of Publisher which uses QPID functionality to send a heartbeat message Note immediate flag not available via
+ * JMS MessageProducer
*/
public class MonitorPublisher extends Publisher
{
@@ -40,14 +42,45 @@ public class MonitorPublisher extends Publisher
super();
}
- /*
- * Publishes a non-persistent message using transacted session
- */
+ /*
+ * Publishes a message using given details
+ */
+ public boolean sendMessage(Session session, Message message, int deliveryMode,
+ boolean immediate, boolean commit) throws UndeliveredMessageException
+ {
+ try
+ {
+ _producer = (BasicMessageProducer) session.createProducer(_destination);
+
+ _producer.send(message, deliveryMode, immediate);
+
+ if (commit)
+ {
+ //commit the message send and close the transaction
+ _session.commit();
+ }
+
+ }
+ catch (JMSException e)
+ {
+ //Have to assume our commit failed but do not rollback here as channel closed
+ _log.error(e);
+ e.printStackTrace();
+ throw new UndeliveredMessageException("Cannot deliver immediate message", e);
+ }
+
+ _log.info(_name + " finished sending message: " + message);
+ return true;
+ }
+
+ /*
+ * Publishes a non-persistent message using transacted session
+ */
public boolean sendImmediateMessage(Message message) throws UndeliveredMessageException
{
try
{
- _producer = (BasicMessageProducer)_session.createProducer(_destination);
+ _producer = (BasicMessageProducer) _session.createProducer(_destination);
//Send message via our producer which is not persistent and is immediate
//NB: not available via jms interface MessageProducer
@@ -62,7 +95,7 @@ public class MonitorPublisher extends Publisher
//Have to assume our commit failed but do not rollback here as channel closed
_log.error(e);
e.printStackTrace();
- throw new UndeliveredMessageException("Cannot deliver immediate message",e);
+ throw new UndeliveredMessageException("Cannot deliver immediate message", e);
}
_log.info(_name + " finished sending message: " + message);
diff --git a/java/client/example/src/main/java/org/apache/qpid/example/pubsub/Client.java b/java/client/example/src/main/java/org/apache/qpid/example/pubsub/Client.java
new file mode 100644
index 0000000000..e32ee0ba73
--- /dev/null
+++ b/java/client/example/src/main/java/org/apache/qpid/example/pubsub/Client.java
@@ -0,0 +1,72 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT 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.example.pubsub;
+
+import javax.jms.Connection;
+import javax.jms.Destination;
+import javax.jms.JMSException;
+import javax.jms.Session;
+import javax.naming.NamingException;
+
+/**
+ * An abstract base class that wraps up the creation of a JMS client utilising JNDI
+ */
+public abstract class Client
+{
+ protected ConnectionSetup _setup;
+
+ protected Connection _connection;
+ protected Destination _destination;
+ protected Session _session;
+
+ public Client(String destination)
+ {
+ if (destination == null)
+ {
+ destination = ConnectionSetup.TOPIC_JNDI_NAME;
+ }
+
+ try
+ {
+ _setup = new ConnectionSetup();
+ }
+ catch (NamingException e)
+ {
+ //ignore
+ }
+
+ if (_setup != null)
+ {
+ try
+ {
+ _connection = _setup.getConnectionFactory().createConnection();
+ _destination = _setup.getDestination(destination);
+ }
+ catch (JMSException e)
+ {
+ System.err.println(e.getMessage());
+ }
+ }
+ }
+
+ public abstract void start();
+
+} \ No newline at end of file
diff --git a/java/client/example/src/main/java/org/apache/qpid/example/pubsub/ConnectionSetup.java b/java/client/example/src/main/java/org/apache/qpid/example/pubsub/ConnectionSetup.java
new file mode 100644
index 0000000000..c4edd9034f
--- /dev/null
+++ b/java/client/example/src/main/java/org/apache/qpid/example/pubsub/ConnectionSetup.java
@@ -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.
+ *
+ *
+ */
+package org.apache.qpid.example.pubsub;
+
+import javax.jms.ConnectionFactory;
+import javax.jms.Destination;
+import javax.naming.Context;
+import javax.naming.InitialContext;
+import javax.naming.NamingException;
+import java.util.Properties;
+
+/**
+ * This ConnectionSetup is a wrapper around JNDI it creates a number of entries.
+ *
+ * It is equivalent to a PropertyFile of value:
+ *
+ * connectionfactory.local=amqp://guest:guest@clientid/test?brokerlist='localhost'
+ * connectionfactory.vm=amqp://guest:guest@clientid/test?brokerlist='vm://:1'
+ *
+ * queue.queue=example.MyQueue
+ * topic.topic=example.hierarical.topic
+ *
+ */
+public class ConnectionSetup
+{
+ final static String INITIAL_CONTEXT_FACTORY = "org.apache.qpid.jndi.PropertiesFileInitialContextFactory";
+
+ final static String CONNECTION_JNDI_NAME = "local";
+ final static String CONNECTION_NAME = "amqp://guest:guest@clientid/test?brokerlist='localhost'";
+
+ public static final String QUEUE_JNDI_NAME = "queue";
+ final static String QUEUE_NAME = "example.MyQueue";
+
+ public static final String TOPIC_JNDI_NAME = "topic";
+ final static String TOPIC_NAME = "example.hierarical.topic";
+
+ private Context _ctx;
+
+ public ConnectionSetup() throws NamingException
+ {
+
+ // Set the properties ...
+ Properties properties = new Properties();
+ properties.put(Context.INITIAL_CONTEXT_FACTORY, INITIAL_CONTEXT_FACTORY);
+ properties.put("connectionfactory." + CONNECTION_JNDI_NAME, CONNECTION_NAME);
+ properties.put("connectionfactory." + "vm", "amqp://guest:guest@clientid/test?brokerlist='vm://:1'");
+
+ properties.put("queue." + QUEUE_JNDI_NAME, QUEUE_NAME);
+ properties.put("topic." + TOPIC_JNDI_NAME, TOPIC_NAME);
+ // Create the initial context
+ _ctx = new InitialContext(properties);
+
+ }
+
+ public ConnectionSetup(Properties properties) throws NamingException
+ {
+ _ctx = new InitialContext(properties);
+ }
+
+ public ConnectionFactory getConnectionFactory()
+ {
+
+ // Perform the lookups
+ try
+ {
+ return (ConnectionFactory) _ctx.lookup(CONNECTION_JNDI_NAME);
+ }
+ catch (NamingException e)
+ {
+ //ignore
+ }
+ return null;
+ }
+
+ public Destination getDestination(String jndiName)
+ {
+ // Perform the lookups
+ try
+ {
+ return (Destination) _ctx.lookup(jndiName);
+ }
+ catch (ClassCastException cce)
+ {
+ //ignore
+ }
+ catch (NamingException ne)
+ {
+ //ignore
+ }
+ return null;
+ }
+
+
+ public void close()
+ {
+ try
+ {
+ _ctx.close();
+ }
+ catch (NamingException e)
+ {
+ //ignore
+ }
+ }
+}
diff --git a/java/client/example/src/main/java/org/apache/qpid/example/pubsub/Publisher.java b/java/client/example/src/main/java/org/apache/qpid/example/pubsub/Publisher.java
new file mode 100644
index 0000000000..dd936e429f
--- /dev/null
+++ b/java/client/example/src/main/java/org/apache/qpid/example/pubsub/Publisher.java
@@ -0,0 +1,81 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT 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.example.pubsub;
+
+import javax.jms.JMSException;
+import javax.jms.MessageProducer;
+import javax.jms.Session;
+
+/**
+ * A simple Publisher example.
+ *
+ * The class can take two arguments.
+ * java Publisher <destination> <msgCount>
+ * Where:
+ * destination is either 'topic' or 'queue' (Default: topic)
+ * msgCount is the number of messages to send (Default : 100)
+ *
+ */
+public class Publisher extends Client
+{
+ int _msgCount;
+
+ public Publisher(String destination, int msgCount)
+ {
+ super(destination);
+ _msgCount = msgCount;
+ }
+
+ public void start()
+ {
+ try
+ {
+ _session = _connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
+
+ MessageProducer _producer = _session.createProducer(_destination);
+
+ for (int msgCount = 0; msgCount < _msgCount; msgCount++)
+ {
+ _producer.send(_session.createTextMessage("msg:" + msgCount));
+ System.out.println("Sent:" + msgCount);
+ }
+
+ System.out.println("Done.");
+ _connection.close();
+ }
+ catch (JMSException e)
+ {
+ e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
+ }
+ }
+
+
+ public static void main(String[] args)
+ {
+
+ String destination = args.length > 2 ? args[1] : null;
+
+ int msgCount = args.length > 2 ? Integer.parseInt(args[2]) : 100;
+
+ new Publisher(destination, msgCount).start();
+ }
+
+}
diff --git a/java/client/example/src/main/java/org/apache/qpid/example/pubsub/Subscriber.java b/java/client/example/src/main/java/org/apache/qpid/example/pubsub/Subscriber.java
new file mode 100644
index 0000000000..f2d736701f
--- /dev/null
+++ b/java/client/example/src/main/java/org/apache/qpid/example/pubsub/Subscriber.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.example.pubsub;
+
+import javax.jms.JMSException;
+import javax.jms.Message;
+import javax.jms.MessageListener;
+import javax.jms.Session;
+import javax.jms.TextMessage;
+import javax.jms.Topic;
+import java.util.concurrent.CountDownLatch;
+
+
+/**
+ * Simple client that listens for the specified number of msgs on the given Destinaton
+ *
+ * The class can take two arguments.
+ * java Subscriber <destination> <msgCount>
+ * Where:
+ * destination is either 'topic' or 'queue' (Default: topic)
+ * msgCount is the number of messages to send (Default : 100)
+ */
+public class Subscriber extends Client implements MessageListener
+{
+
+ CountDownLatch _count;
+
+ public Subscriber(String destination, int msgCount)
+ {
+ super(destination);
+ _count = new CountDownLatch(msgCount);
+ }
+
+
+ public void start()
+ {
+ try
+ {
+ _session = _connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
+
+ _session.createDurableSubscriber((Topic) _setup.getDestination(ConnectionSetup.TOPIC_JNDI_NAME),
+ "exampleClient").setMessageListener(this);
+ _connection.start();
+ _count.await();
+
+ System.out.println("Done");
+
+ _connection.close();
+ }
+ catch (JMSException e)
+ {
+ e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
+ }
+ catch (InterruptedException e)
+ {
+ e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
+ }
+ }
+
+ public static void main(String[] args)
+ {
+ String destination = args.length > 2 ? args[1] : null;
+ int msgCount = args.length > 2 ? Integer.parseInt(args[2]) : 100;
+
+ new Subscriber(destination, msgCount).start();
+ }
+
+ public void onMessage(Message message)
+ {
+ try
+ {
+ _count.countDown();
+ System.out.println("Received msg:" + ((TextMessage) message).getText());
+ }
+ catch (JMSException e)
+ {
+ e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
+ }
+ }
+}
diff --git a/java/client/pom.xml b/java/client/pom.xml
index c36c54a10f..b51e540c2d 100644
--- a/java/client/pom.xml
+++ b/java/client/pom.xml
@@ -123,6 +123,50 @@
<build>
<plugins>
+
+ <plugin>
+ <artifactId>minijar-maven-plugin</artifactId>
+ <groupId>org.codehaus.mojo</groupId>
+ <executions>
+ <execution>
+ <phase>package</phase>
+ <goals>
+ <goal>ueberjar</goal>
+ </goals>
+ <configuration>
+ <stripUnusedClasses>false</stripUnusedClasses>
+ <name>[artifactId]-[version]-single.jar</name>
+ <classifier>single</classifier>
+ <attach>true</attach>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+
+ <plugin>
+ <groupId>org.codehaus.mojo</groupId>
+ <artifactId>build-helper-maven-plugin</artifactId>
+ <executions>
+ <execution>
+ <id>attach-artifacts</id>
+ <phase>package</phase>
+ <goals>
+ <goal>attach-artifact</goal>
+ </goals>
+ <configuration>
+ <artifacts>
+ <artifact>
+ <file>target/${artifactId}-${version}-single.jar</file>
+ <type>jar</type>
+ <classifier>single</classifier>
+ </artifact>
+ </artifacts>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+
+
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-antrun-plugin</artifactId>
diff --git a/java/client/src/main/java/org/apache/qpid/client/AMQConnection.java b/java/client/src/main/java/org/apache/qpid/client/AMQConnection.java
index d59412fdba..ddce0db7ff 100644
--- a/java/client/src/main/java/org/apache/qpid/client/AMQConnection.java
+++ b/java/client/src/main/java/org/apache/qpid/client/AMQConnection.java
@@ -46,7 +46,6 @@ import org.apache.qpid.jms.ConnectionURL;
import org.apache.qpid.jms.FailoverPolicy;
import org.apache.qpid.protocol.AMQConstant;
import org.apache.qpid.url.URLSyntaxException;
-
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -68,7 +67,6 @@ import javax.naming.NamingException;
import javax.naming.Reference;
import javax.naming.Referenceable;
import javax.naming.StringRefAddr;
-
import java.io.IOException;
import java.net.ConnectException;
import java.nio.channels.UnresolvedAddressException;
@@ -1148,7 +1146,7 @@ public class AMQConnection extends Closeable implements Connection, QueueConnect
}
else
{
- _logger.info("Not a hard-error connection not closing.");
+ _logger.info("Not a hard-error connection not closing: " + cause.getMessage());
}
}
diff --git a/java/client/src/main/java/org/apache/qpid/client/AMQConnectionURL.java b/java/client/src/main/java/org/apache/qpid/client/AMQConnectionURL.java
index b3fbd1f510..24f5ead2d0 100644
--- a/java/client/src/main/java/org/apache/qpid/client/AMQConnectionURL.java
+++ b/java/client/src/main/java/org/apache/qpid/client/AMQConnectionURL.java
@@ -20,6 +20,14 @@
*/
package org.apache.qpid.client;
+import org.apache.qpid.framing.AMQShortString;
+import org.apache.qpid.jms.BrokerDetails;
+import org.apache.qpid.jms.ConnectionURL;
+import org.apache.qpid.url.URLHelper;
+import org.apache.qpid.url.URLSyntaxException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
import java.net.URI;
import java.net.URISyntaxException;
import java.util.HashMap;
@@ -27,14 +35,10 @@ import java.util.LinkedList;
import java.util.List;
import java.util.StringTokenizer;
-import org.apache.qpid.framing.AMQShortString;
-import org.apache.qpid.jms.BrokerDetails;
-import org.apache.qpid.jms.ConnectionURL;
-import org.apache.qpid.url.URLHelper;
-import org.apache.qpid.url.URLSyntaxException;
-
public class AMQConnectionURL implements ConnectionURL
{
+ private static final Logger _logger = LoggerFactory.getLogger(AMQConnectionURL.class);
+
private String _url;
private String _failoverMethod;
private HashMap<String, String> _failoverOptions;
@@ -162,7 +166,7 @@ public class AMQConnectionURL implements ConnectionURL
if ((slash != 0) && (fullURL.charAt(slash - 1) == ':'))
{
throw URLHelper.parseError(slash - 2, fullURL.indexOf('?') - slash + 2,
- "Virtual host looks like a windows path, forward slash not allowed in URL", fullURL);
+ "Virtual host looks like a windows path, forward slash not allowed in URL", fullURL);
}
else
{
@@ -182,7 +186,7 @@ public class AMQConnectionURL implements ConnectionURL
if (colonIndex == -1)
{
throw URLHelper.parseError(AMQ_PROTOCOL.length() + 3, userinfo.length(),
- "Null password in user information not allowed.", _url);
+ "Null password in user information not allowed.", _url);
}
else
{
@@ -387,7 +391,14 @@ public class AMQConnectionURL implements ConnectionURL
if (_password != null)
{
sb.append(':');
- sb.append(_password);
+ if (_logger.isDebugEnabled())
+ {
+ sb.append(_password);
+ }
+ else
+ {
+ sb.append("********");
+ }
}
sb.append('@');
@@ -432,7 +443,7 @@ public class AMQConnectionURL implements ConnectionURL
public static void main(String[] args) throws URLSyntaxException
{
String url2 =
- "amqp://ritchiem:bob@temp?brokerlist='tcp://localhost:5672;jcp://fancyserver:3000/',failover='roundrobin'";
+ "amqp://ritchiem:bob@temp?brokerlist='tcp://localhost:5672;jcp://fancyserver:3000/',failover='roundrobin'";
// "amqp://user:pass@clientid/virtualhost?brokerlist='tcp://host:1?option1=\'value\',option2=\'value\';vm://:3?option1=\'value\'',failover='method?option1=\'value\',option2='value''";
ConnectionURL connectionurl2 = new AMQConnectionURL(url2);
diff --git a/java/client/src/main/java/org/apache/qpid/client/AMQSession.java b/java/client/src/main/java/org/apache/qpid/client/AMQSession.java
index 879578bd6c..8f0ad3947a 100644
--- a/java/client/src/main/java/org/apache/qpid/client/AMQSession.java
+++ b/java/client/src/main/java/org/apache/qpid/client/AMQSession.java
@@ -2319,6 +2319,16 @@ public class AMQSession extends Closeable implements Session, QueueSession, Topi
}
}
+ public void declareAndBind(AMQDestination amqd)
+ throws
+ AMQException
+ {
+ AMQProtocolHandler protocolHandler = getProtocolHandler();
+ declareExchange(amqd, protocolHandler, false);
+ AMQShortString queueName = declareQueue(amqd, protocolHandler);
+ bindQueue(queueName, amqd.getRoutingKey(), new FieldTable(), amqd.getExchangeName());
+ }
+
/**
* Callers must hold the failover mutex before calling this method.
*
diff --git a/java/client/src/main/java/org/apache/qpid/client/handler/ExchangeBoundOkMethodHandler.java b/java/client/src/main/java/org/apache/qpid/client/handler/ExchangeBoundOkMethodHandler.java
index 8f9a84a3a6..862a9be8d4 100644
--- a/java/client/src/main/java/org/apache/qpid/client/handler/ExchangeBoundOkMethodHandler.java
+++ b/java/client/src/main/java/org/apache/qpid/client/handler/ExchangeBoundOkMethodHandler.java
@@ -1,18 +1,21 @@
/*
*
- * Copyright (c) 2006 The Apache Software Foundation
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
*
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
+ * http://www.apache.org/licenses/LICENSE-2.0
*
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
*
*/
package org.apache.qpid.client.handler;
diff --git a/java/client/src/main/java/org/apache/qpid/client/handler/QueueDeleteOkMethodHandler.java b/java/client/src/main/java/org/apache/qpid/client/handler/QueueDeleteOkMethodHandler.java
index 81228b4cdc..65060d44d2 100644
--- a/java/client/src/main/java/org/apache/qpid/client/handler/QueueDeleteOkMethodHandler.java
+++ b/java/client/src/main/java/org/apache/qpid/client/handler/QueueDeleteOkMethodHandler.java
@@ -1,18 +1,21 @@
/*
*
- * Copyright (c) 2006 The Apache Software Foundation
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
*
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
+ * http://www.apache.org/licenses/LICENSE-2.0
*
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
*
*/
package org.apache.qpid.client.handler;
diff --git a/java/client/src/test/java/org/apache/qpid/test/unit/client/channelclose/CloseWithBlockingReceiveTest.java b/java/client/src/test/java/org/apache/qpid/test/unit/client/channelclose/CloseWithBlockingReceiveTest.java
index d19a6095d5..9600d1e9d3 100644
--- a/java/client/src/test/java/org/apache/qpid/test/unit/client/channelclose/CloseWithBlockingReceiveTest.java
+++ b/java/client/src/test/java/org/apache/qpid/test/unit/client/channelclose/CloseWithBlockingReceiveTest.java
@@ -1,18 +1,21 @@
/*
*
- * Copyright (c) 2006 The Apache Software Foundation
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
*
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
+ * http://www.apache.org/licenses/LICENSE-2.0
*
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
*
*/
package org.apache.qpid.test.unit.client.channelclose;
diff --git a/java/client/src/test/java/org/apache/qpid/test/unit/client/forwardall/CombinedTest.java b/java/client/src/test/java/org/apache/qpid/test/unit/client/forwardall/CombinedTest.java
index 9c354ee260..9cde24dd92 100644
--- a/java/client/src/test/java/org/apache/qpid/test/unit/client/forwardall/CombinedTest.java
+++ b/java/client/src/test/java/org/apache/qpid/test/unit/client/forwardall/CombinedTest.java
@@ -21,9 +21,7 @@
package org.apache.qpid.test.unit.client.forwardall;
import junit.framework.TestCase;
-
import org.apache.qpid.testutil.VMBrokerSetup;
-
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -34,6 +32,7 @@ import org.slf4j.LoggerFactory;
public class CombinedTest extends TestCase
{
private static final Logger _logger = LoggerFactory.getLogger(CombinedTest.class);
+ private int run = 0;
protected void setUp() throws Exception
{
@@ -48,14 +47,18 @@ public class CombinedTest extends TestCase
public void testForwardAll() throws Exception
{
- int services = 2;
- ServiceCreator.start("vm://:1", services);
+ while (run < 10)
+ {
+ int services = 2;
+ ServiceCreator.start("vm://:1", services);
+
+ _logger.info("Starting " + ++run + " client...");
- _logger.info("Starting client...");
+ new Client("vm://:1", services).shutdownWhenComplete();
- new Client("vm://:1", services).shutdownWhenComplete();
- _logger.info("Completed successfully!");
+ _logger.info("Completed " + run + " successfully!");
+ }
}
public static junit.framework.Test suite()
diff --git a/java/client/src/test/java/org/apache/qpid/test/unit/transacted/CommitRollbackTest.java b/java/client/src/test/java/org/apache/qpid/test/unit/transacted/CommitRollbackTest.java
index df2a38d0fc..1a45773907 100644
--- a/java/client/src/test/java/org/apache/qpid/test/unit/transacted/CommitRollbackTest.java
+++ b/java/client/src/test/java/org/apache/qpid/test/unit/transacted/CommitRollbackTest.java
@@ -21,12 +21,10 @@
package org.apache.qpid.test.unit.transacted;
import junit.framework.TestCase;
-
import org.apache.qpid.AMQException;
import org.apache.qpid.client.AMQConnection;
import org.apache.qpid.client.transport.TransportConnection;
import org.apache.qpid.url.URLSyntaxException;
-
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -57,6 +55,9 @@ public class CommitRollbackTest extends TestCase
private static final Logger _logger = LoggerFactory.getLogger(CommitRollbackTest.class);
private static final String BROKER = "vm://:1";
+ private boolean _gotone = false;
+ private boolean _gottwo = false;
+ private boolean _gottwoRedelivered = false;
protected void setUp() throws Exception
{
@@ -340,57 +341,98 @@ public class CommitRollbackTest extends TestCase
*
* @throws Exception On error
*/
- /*public void testSend2ThenRollback() throws Exception
+ public void testSend2ThenRollback() throws Exception
{
- assertTrue("session is not transacted", _session.getTransacted());
- assertTrue("session is not transacted", _pubSession.getTransacted());
+ int run = 0;
+ while (run < 10)
+ {
+ run++;
+ _logger.info("Run:" + run);
+ assertTrue("session is not transacted", _session.getTransacted());
+ assertTrue("session is not transacted", _pubSession.getTransacted());
- _logger.info("sending two test messages");
- _publisher.send(_pubSession.createTextMessage("1"));
- _publisher.send(_pubSession.createTextMessage("2"));
- _pubSession.commit();
+ _logger.info("sending two test messages");
+ _publisher.send(_pubSession.createTextMessage("1"));
+ _publisher.send(_pubSession.createTextMessage("2"));
+ _pubSession.commit();
- _logger.info("getting test message");
- assertEquals("1", ((TextMessage) _consumer.receive(1000)).getText());
+ _logger.info("getting test message");
+ assertEquals("1", ((TextMessage) _consumer.receive(1000)).getText());
- _logger.info("rolling back");
- _session.rollback();
+ _logger.info("rolling back");
+ _session.rollback();
- _logger.info("receiving result");
- Message result = _consumer.receive(1000);
+ _logger.info("receiving result");
+ Message result = _consumer.receive(1000);
- assertNotNull("test message was consumed and rolled back, but is gone", result);
+ assertNotNull("test message was consumed and rolled back, but is gone", result);
+ // Message Order is:
- if (((TextMessage) result).getText().equals("2"))
- {
- assertTrue("Messasge is marked as redelivered", !result.getJMSRedelivered());
+ // Send 1 , 2
+ // Retrieve 1 and then rollback
+ // Receieve 1 (redelivered) , 2 (may or may not be redelivered??)
- result = _consumer.receive(1000);
- assertEquals("1", ((TextMessage) result).getText());
- assertTrue("Messasge is not marked as redelivered", result.getJMSRedelivered());
+ verifyMessages(result);
+
+ // Occassionally get message 2 first!
+// assertEquals("Should get message one first", "1", ((TextMessage) result).getText());
+// assertTrue("Message is not marked as redelivered", result.getJMSRedelivered());
+//
+// result = _consumer.receive(1000);
+// assertEquals("Second message should be message 2", "2", ((TextMessage) result).getText());
+// assertTrue("Message is not marked as redelivered", result.getJMSRedelivered());
+//
+// result = _consumer.receive(1000);
+// assertNull("There should be no more messages", result);
+
+ _session.commit();
}
- else
+ }
+
+ private void verifyMessages(Message result) throws JMSException
+ {
+
+ if (result == null)
{
- assertEquals("1", ((TextMessage) result).getText());
- assertTrue("Messasge is not marked as redelivered", result.getJMSRedelivered());
- result = _consumer.receive(1000);
- assertNotNull("test message was consumed and rolled back, but is gone", result);
- assertEquals("2", ((TextMessage) result).getText());
- assertTrue("Messasge is not marked as redelivered", result.getJMSRedelivered());
+ assertTrue("Didn't receive redelivered message one", _gotone);
+ assertTrue("Didn't receive message two at all", _gottwo | _gottwoRedelivered);
+ _gotone = false;
+ _gottwo = false;
+ _gottwoRedelivered = false;
+ return;
}
- result = _consumer.receive(1000);
+ if (((TextMessage) result).getText().equals("1"))
+ {
+ _logger.info("Got 1 redelivered");
+ assertTrue("Message is not marked as redelivered", result.getJMSRedelivered());
+ assertFalse("Already received message one", _gotone);
+ _gotone = true;
- if (result != null)
+ }
+ else
{
assertEquals("2", ((TextMessage) result).getText());
- assertTrue("Messasge is not marked as redelivered", result.getJMSRedelivered());
- result = _consumer.receive(1000);
+
+ if (result.getJMSRedelivered())
+ {
+ _logger.info("Got 2 redelivered, message was prefetched");
+ assertFalse("Already received message redelivered two", _gottwoRedelivered);
+
+ _gottwoRedelivered = true;
+ }
+ else
+ {
+ _logger.warn("Got 2, message prefetched wasn't cleared or messages was in transit when rollback occured");
+ assertFalse("Already received message two", _gottwo);
+
+ _gottwo = true;
+ }
}
- assertNull("test message should be null", result);
- }*/
+ verifyMessages(_consumer.receive(1000));
+ }
public void testSend2ThenCloseAfter1andTryAgain() throws Exception
{
@@ -417,12 +459,12 @@ public class CommitRollbackTest extends TestCase
_logger.info("receiving result");
- // NOTE: Both msg 1 & 2 will be marked as redelivered as they have both will have been rejected.
- // Only the occasion where it is not rejected will it mean it hasn't arrived at the client yet.
+// NOTE: Both msg 1 & 2 will be marked as redelivered as they have both will have been rejected.
+// Only the occasion where it is not rejected will it mean it hasn't arrived at the client yet.
result = _consumer.receive(1000);
assertNotNull("test message was consumed and rolled back, but is gone", result);
- // The first message back will be either 1 or 2 being redelivered
+// The first message back will be either 1 or 2 being redelivered
if (result.getJMSRedelivered())
{
assertTrue("Messasge is not marked as redelivered" + result, result.getJMSRedelivered());
diff --git a/java/cluster/src/main/java/org/apache/qpid/server/cluster/SimpleBodySendable.java b/java/cluster/src/main/java/org/apache/qpid/server/cluster/SimpleBodySendable.java
index f7c40c60b3..bd3757bf97 100644
--- a/java/cluster/src/main/java/org/apache/qpid/server/cluster/SimpleBodySendable.java
+++ b/java/cluster/src/main/java/org/apache/qpid/server/cluster/SimpleBodySendable.java
@@ -1,18 +1,21 @@
/*
*
- * Copyright (c) 2006 The Apache Software Foundation
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
*
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
+ * http://www.apache.org/licenses/LICENSE-2.0
*
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT 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.cluster;
diff --git a/java/common/pom.xml b/java/common/pom.xml
index 92177b2418..77065345d6 100644
--- a/java/common/pom.xml
+++ b/java/common/pom.xml
@@ -100,22 +100,34 @@
</executions>
</plugin>
-
+
</plugins>
</build>
<dependencies>
- <dependency>
+ <dependency>
+ <groupId>commons-configuration</groupId>
+ <artifactId>commons-configuration</artifactId>
+ </dependency>
+
+ <dependency>
+ <groupId>commons-cli</groupId>
+ <artifactId>commons-cli</artifactId>
+ </dependency>
+
+
+
+ <dependency>
<groupId>org.slf4j</groupId>
- <artifactId>slf4j-api</artifactId>
+ <artifactId>slf4j-api</artifactId>
<version>1.4.0</version>
</dependency>
- <dependency>
- <groupId>org.slf4j</groupId>
- <artifactId>slf4j-log4j12</artifactId>
- <version>1.4.0</version>
+ <dependency>
+ <groupId>org.slf4j</groupId>
+ <artifactId>slf4j-log4j12</artifactId>
+ <version>1.4.0</version>
<scope>test</scope>
</dependency>
diff --git a/java/common/src/main/java/org/apache/qpid/framing/AMQShortString.java b/java/common/src/main/java/org/apache/qpid/framing/AMQShortString.java
index 05e9473463..df99f6589d 100644
--- a/java/common/src/main/java/org/apache/qpid/framing/AMQShortString.java
+++ b/java/common/src/main/java/org/apache/qpid/framing/AMQShortString.java
@@ -26,6 +26,10 @@ import org.apache.mina.common.ByteBuffer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import java.util.Map;
+import java.util.WeakHashMap;
+import java.lang.ref.WeakReference;
+
/**
* A short string is a representation of an AMQ Short String
* Short strings differ from the Java String class by being limited to on ASCII characters (0-127)
@@ -34,6 +38,19 @@ import org.slf4j.LoggerFactory;
*/
public final class AMQShortString implements CharSequence, Comparable<AMQShortString>
{
+
+ private static final ThreadLocal<Map<AMQShortString, WeakReference<AMQShortString>>> _localInternMap =
+ new ThreadLocal<Map<AMQShortString, WeakReference<AMQShortString>>>()
+ {
+ protected Map<AMQShortString, WeakReference<AMQShortString>> initialValue()
+ {
+ return new WeakHashMap<AMQShortString, WeakReference<AMQShortString>>();
+ };
+ };
+
+ private static final Map<AMQShortString, WeakReference<AMQShortString>> _globalInternMap =
+ new WeakHashMap<AMQShortString, WeakReference<AMQShortString>>();
+
private static final Logger _logger = LoggerFactory.getLogger(AMQShortString.class);
private final ByteBuffer _data;
@@ -376,4 +393,43 @@ public final class AMQShortString implements CharSequence, Comparable<AMQShortSt
return (length() == name.length()) ? 0 : -1;
}
}
+
+
+ public AMQShortString intern()
+ {
+
+ hashCode();
+
+ Map<AMQShortString, WeakReference<AMQShortString>> localMap =
+ _localInternMap.get();
+
+ WeakReference<AMQShortString> ref = localMap.get(this);
+ AMQShortString internString;
+
+ if(ref != null)
+ {
+ internString = ref.get();
+ if(internString != null)
+ {
+ return internString;
+ }
+ }
+
+
+ synchronized(_globalInternMap)
+ {
+
+ ref = _globalInternMap.get(this);
+ if((ref == null) || ((internString = ref.get()) == null))
+ {
+ internString = new AMQShortString(getBytes());
+ ref = new WeakReference(internString);
+ _globalInternMap.put(internString, ref);
+ }
+
+ }
+ localMap.put(internString, ref);
+ return internString;
+
+ }
}
diff --git a/java/common/src/main/java/org/apache/qpid/framing/abstraction/MessagePublishInfoConverter.java b/java/common/src/main/java/org/apache/qpid/framing/abstraction/MessagePublishInfoConverter.java
index c9e15f18e3..42e2f7ad97 100644
--- a/java/common/src/main/java/org/apache/qpid/framing/abstraction/MessagePublishInfoConverter.java
+++ b/java/common/src/main/java/org/apache/qpid/framing/abstraction/MessagePublishInfoConverter.java
@@ -1,18 +1,21 @@
/*
*
- * Copyright (c) 2006 The Apache Software Foundation
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
*
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
+ * http://www.apache.org/licenses/LICENSE-2.0
*
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
*
*/
diff --git a/java/common/src/main/java/org/apache/qpid/framing/abstraction/ProtocolVersionMethodConverter.java b/java/common/src/main/java/org/apache/qpid/framing/abstraction/ProtocolVersionMethodConverter.java
index 52e82cdf07..99588a0908 100644
--- a/java/common/src/main/java/org/apache/qpid/framing/abstraction/ProtocolVersionMethodConverter.java
+++ b/java/common/src/main/java/org/apache/qpid/framing/abstraction/ProtocolVersionMethodConverter.java
@@ -1,18 +1,21 @@
/*
*
- * Copyright (c) 2006 The Apache Software Foundation
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
*
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
+ * http://www.apache.org/licenses/LICENSE-2.0
*
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
*
*/
diff --git a/java/common/src/main/java/org/apache/qpid/util/CommandLineParser.java b/java/common/src/main/java/org/apache/qpid/util/CommandLineParser.java
index 9bb4a6635f..64e61fe5ff 100644
--- a/java/common/src/main/java/org/apache/qpid/util/CommandLineParser.java
+++ b/java/common/src/main/java/org/apache/qpid/util/CommandLineParser.java
@@ -483,9 +483,9 @@ public class CommandLineParser
}
/**
- * If a command line has been parsed, calling this method sets all of its parsed options as system properties.
+ * If a command line has been parsed, calling this method sets all of its parsed options into the specified properties.
*/
- public void addCommandLineToSysProperties()
+ public void addCommandLineToProperties(Properties properties)
{
if (parsedProperties != null)
{
@@ -494,7 +494,7 @@ public class CommandLineParser
String name = (String) propKey;
String value = parsedProperties.getProperty(name);
- System.setProperty(name, value);
+ properties.setProperty(name, value);
}
}
}
@@ -607,7 +607,9 @@ public class CommandLineParser
* instrucitons and calling System.exit on errors. Extracts all trailing name=value pairs from the command line,
* and sets them all as system properties and also returns a map of properties containing them.
*
- * @param args The command line.
+ * @param args The command line.
+ * @param commandLine The command line parser.
+ * @param properties The properties object to inject all parsed properties into (optional may be <tt>null</tt>).
*
* @return A set of properties containing all name=value pairs from the command line.
*
@@ -619,7 +621,7 @@ public class CommandLineParser
* @todo Allow the Properties to add trailing options to be specified as an argument rather than hard coding
* system properties. Again, gives the caller the option to decide.
*/
- public static Properties processCommandLine(String[] args, CommandLineParser commandLine)
+ public static Properties processCommandLine(String[] args, CommandLineParser commandLine, Properties properties)
{
// Capture the command line arguments or display errors and correct usage and then exit.
Properties options = null;
@@ -630,7 +632,7 @@ public class CommandLineParser
// Add all the trailing command line options (name=value pairs) to system properties. They may be picked up
// from there.
- commandLine.addCommandLineToSysProperties();
+ commandLine.addCommandLineToProperties(properties);
}
catch (IllegalArgumentException e)
{
diff --git a/java/distribution/pom.xml b/java/distribution/pom.xml
index 8774b04c18..7899ef8912 100644
--- a/java/distribution/pom.xml
+++ b/java/distribution/pom.xml
@@ -39,8 +39,11 @@
<java.source.version>1.5</java.source.version>
<qpid.version>${pom.version}</qpid.version>
<qpid.targetDir>${project.build.directory}</qpid.targetDir>
+
+ <!-- This is an assembly/distribution pom so no test code exists -->
+ <maven.test.skip>true</maven.test.skip>
</properties>
-
+
<repositories>
<repository>
<id>repo1.maven.org</id>
@@ -131,6 +134,8 @@
</executions>
</plugin>
</plugins>
+
+ <defaultGoal>assembly:assembly</defaultGoal>
</build>
<profiles>
diff --git a/java/distribution/src/main/assembly/bin-test.xml b/java/distribution/src/main/assembly/bin-test.xml
index a9e769e312..04d83916e4 100644
--- a/java/distribution/src/main/assembly/bin-test.xml
+++ b/java/distribution/src/main/assembly/bin-test.xml
@@ -27,38 +27,32 @@
</formats>
<fileSets>
+ <!-- Include the currently hardwired Apache Legal bits -->
<fileSet>
- <directory>src/main/release</directory>
+ <directory>../resources</directory>
<outputDirectory>qpid-${qpid.version}</outputDirectory>
<includes>
<include>DISCLAIMER</include>
- <include>LICENSE.txt</include>
- <include>NOTICE.txt</include>
- <include>README.txt</include>
+ <include>LICENSE</include>
+ <include>NOTICE</include>
+ <include>README</include>
</includes>
+ <fileMode>0444</fileMode>
</fileSet>
+
+ <!-- Include any release information -->
<fileSet>
- <directory>..</directory>
+ <directory>src/main/release</directory>
<outputDirectory>qpid-${qpid.version}</outputDirectory>
- <includes>
- <include>*.txt</include>
- </includes>
- </fileSet>
- <fileSet>
- <directory>src/main/release/etc</directory>
- <outputDirectory>qpid-${qpid.version}/etc</outputDirectory>
- <includes>
- <include>logging.properties</include>
- <include>log4j.properties</include>
- </includes>
</fileSet>
+
+ <!-- Include any release information -->
<fileSet>
- <directory>src/main/release/docs</directory>
- <outputDirectory>qpid-${qpid.version}/docs</outputDirectory>
- <includes>
- <include>RELEASE_NOTES.txt</include>
- </includes>
+ <directory>../release-docs</directory>
+ <outputDirectory>qpid-${qpid.version}</outputDirectory>
</fileSet>
+
+ <!-- Include the classpath jar qpid-incubating.jar -->
<fileSet>
<directory>target</directory>
<outputDirectory>qpid-${qpid.version}/lib</outputDirectory>
@@ -66,107 +60,40 @@
<include>qpid-incubating.jar</include>
</includes>
</fileSet>
- </fileSets>
- <files>
- <!-- due to a bug in the assembly plugin (MASSEMBLY-153) you have
- to use decimal numbers to specify fileMode -->
- <file>
- <source>../common/etc/qpid-run.conf</source>
- <outputDirectory>qpid-${qpid.version}/etc</outputDirectory>
- <destName>qpid-run.conf</destName>
- <fileMode>420</fileMode>
- </file>
- <file>
- <source>../broker/etc/config.xml</source>
- <outputDirectory>qpid-${qpid.version}/etc</outputDirectory>
- <destName>config.xml</destName>
- <fileMode>420</fileMode>
- </file>
- <file>
- <source>../broker/etc/log4j.xml</source>
- <outputDirectory>qpid-${qpid.version}/etc</outputDirectory>
- <destName>log4j.xml</destName>
- <fileMode>420</fileMode>
- </file>
- <file>
- <source>../broker/etc/passwd</source>
- <outputDirectory>qpid-${qpid.version}/etc</outputDirectory>
- <destName>passwd</destName>
- <fileMode>420</fileMode>
- </file>
- <file>
- <source>../broker/etc/qpid-server.conf</source>
+
+ <!-- Include etc -->
+ <fileSet>
+ <directory>../common/etc</directory>
<outputDirectory>qpid-${qpid.version}/etc</outputDirectory>
- <destName>qpid-server.conf</destName>
- <fileMode>420</fileMode>
- </file>
- <file>
- <source>../broker/etc/virtualhosts.xml</source>
+ <fileMode>0640</fileMode>
+ </fileSet>
+ <fileSet>
+ <directory>../broker/etc</directory>
<outputDirectory>qpid-${qpid.version}/etc</outputDirectory>
- <destName>virtualhosts.xml</destName>
- <fileMode>420</fileMode>
- </file>
- <file>
- <source>../broker/bin/qpid.start</source>
- <outputDirectory>qpid-${qpid.version}/bin</outputDirectory>
- <destName>qpid.start</destName>
- <fileMode>493</fileMode>
- </file>
- <file>
- <source>../broker/bin/qpid.stop</source>
- <outputDirectory>qpid-${qpid.version}/bin</outputDirectory>
- <destName>qpid.stop</destName>
- <fileMode>493</fileMode>
- </file>
- <file>
- <source>../broker/bin/qpid.stopall</source>
- <outputDirectory>qpid-${qpid.version}/bin</outputDirectory>
- <destName>qpid.stopall</destName>
- <fileMode>493</fileMode>
- </file>
- <file>
- <source>../common/bin/qpid-run</source>
- <outputDirectory>qpid-${qpid.version}/bin</outputDirectory>
- <destName>qpid-run</destName>
- <fileMode>493</fileMode>
- </file>
- <file>
- <source>../broker/bin/qpid-server</source>
- <outputDirectory>qpid-${qpid.version}/bin</outputDirectory>
- <destName>qpid-server</destName>
- <fileMode>493</fileMode>
- </file>
- <file>
- <source>../broker/bin/qpid-server.bat</source>
- <outputDirectory>qpid-${qpid.version}/bin</outputDirectory>
- <destName>qpid-server.bat</destName>
- <fileMode>493</fileMode>
- </file>
- <file>
- <source>../broker/bin/run.bat</source>
- <outputDirectory>qpid-${qpid.version}/bin</outputDirectory>
- <destName>run.bat</destName>
- <fileMode>493</fileMode>
- </file>
- <file>
- <source>../broker/bin/run.sh</source>
+ <fileMode>0640</fileMode>
+ </fileSet>
+
+ <!-- Include bin scripts-->
+ <fileSet>
+ <directory>../broker/bin</directory>
<outputDirectory>qpid-${qpid.version}/bin</outputDirectory>
- <destName>run.sh</destName>
- <fileMode>493</fileMode>
- </file>
- <file>
- <source>../broker/bin/runAll</source>
+ <fileMode>0750</fileMode>
+ </fileSet>
+ <fileSet>
+ <directory>../common/bin</directory>
<outputDirectory>qpid-${qpid.version}/bin</outputDirectory>
- <destName>runAll</destName>
- <fileMode>493</fileMode>
- </file>
- </files>
+ <fileMode>0750</fileMode>
+ </fileSet>
+ </fileSets>
+
<dependencySets>
<dependencySet>
<outputDirectory>qpid-${qpid.version}/lib</outputDirectory>
<unpack>false</unpack>
<excludes>
+ <!-- Exclude the jar output of this build process -->
<exclude>org.apache.qpid:qpid-distribution</exclude>
+ <!-- Exclude the Console dependancies -->
<exclude>org.apache.qpid.management:org.apache.qpid.management.ui</exclude>
<exclude>org.eclipse.core:org.eclipse.core.commands</exclude>
<exclude>org.eclipse.core:org.eclipse.core.contenttype</exclude>
diff --git a/java/distribution/src/main/assembly/bin.xml b/java/distribution/src/main/assembly/bin.xml
index 0461f0f643..3620659e48 100644
--- a/java/distribution/src/main/assembly/bin.xml
+++ b/java/distribution/src/main/assembly/bin.xml
@@ -27,38 +27,38 @@
</formats>
<fileSets>
+ <!-- Include the currently hardwired Apache Legal bits -->
<fileSet>
- <directory>src/main/release</directory>
+ <directory>../resources</directory>
<outputDirectory>qpid-${qpid.version}</outputDirectory>
<includes>
<include>DISCLAIMER</include>
- <include>LICENSE.txt</include>
- <include>NOTICE.txt</include>
- <include>README.txt</include>
+ <include>LICENSE</include>
+ <include>NOTICE</include>
+ <include>README</include>
</includes>
+ <fileMode>0444</fileMode>
</fileSet>
+
+ <!-- Include any release information -->
<fileSet>
- <directory>..</directory>
+ <directory>src/main/release</directory>
<outputDirectory>qpid-${qpid.version}</outputDirectory>
- <includes>
- <include>*.txt</include>
- </includes>
</fileSet>
+
+ <!-- Include any release information -->
<fileSet>
- <directory>src/main/release/etc</directory>
- <outputDirectory>qpid-${qpid.version}/etc</outputDirectory>
- <includes>
- <include>logging.properties</include>
- <include>log4j.properties</include>
- </includes>
+ <directory>..//release-docs</directory>
+ <outputDirectory>qpid-${qpid.version}</outputDirectory>
</fileSet>
+
+ <!-- Include any release information -->
<fileSet>
- <directory>src/main/release/docs</directory>
- <outputDirectory>qpid-${qpid.version}/docs</outputDirectory>
- <includes>
- <include>RELEASE_NOTES.txt</include>
- </includes>
+ <directory>../release-docs</directory>
+ <outputDirectory>qpid-${qpid.version}</outputDirectory>
</fileSet>
+
+ <!-- Include the classpath jar qpid-incubating.jar -->
<fileSet>
<directory>target</directory>
<outputDirectory>qpid-${qpid.version}/lib</outputDirectory>
@@ -66,131 +66,41 @@
<include>qpid-incubating.jar</include>
</includes>
</fileSet>
- </fileSets>
- <files>
- <!-- due to a bug in the assembly 2.1 plugin (MASSEMBLY-153) you have
- to use octal numbers to specify fileMode note not valid in 2.2 assembly plugin -->
- <file>
- <source>../common/etc/qpid-run.conf</source>
- <outputDirectory>qpid-${qpid.version}/etc</outputDirectory>
- <destName>qpid-run.conf</destName>
- <fileMode>420</fileMode>
- </file>
- <file>
- <source>../broker/etc/config.xml</source>
- <outputDirectory>qpid-${qpid.version}/etc</outputDirectory>
- <destName>config.xml</destName>
- <fileMode>420</fileMode>
- </file>
- <file>
- <source>../broker/etc/jmxremote.access</source>
- <outputDirectory>qpid-${qpid.version}/etc</outputDirectory>
- <destName>jmxremote.access</destName>
- <fileMode>420</fileMode>
- </file>
- <file>
- <source>../broker/etc/transient_config.xml</source>
- <outputDirectory>qpid-${qpid.version}/etc</outputDirectory>
- <destName>transient_config.xml</destName>
- <fileMode>420</fileMode>
- </file>
- <file>
- <source>../broker/etc/persistent_config.xml</source>
- <outputDirectory>qpid-${qpid.version}/etc</outputDirectory>
- <destName>persistent_config.xml</destName>
- <fileMode>420</fileMode>
- </file>
- <file>
- <source>../broker/etc/log4j.xml</source>
- <outputDirectory>qpid-${qpid.version}/etc</outputDirectory>
- <destName>log4j.xml</destName>
- <fileMode>420</fileMode>
- </file>
- <file>
- <source>../broker/etc/passwd</source>
- <outputDirectory>qpid-${qpid.version}/etc</outputDirectory>
- <destName>passwd</destName>
- <fileMode>420</fileMode>
- </file>
- <file>
- <source>../broker/etc/passwdVhost</source>
- <outputDirectory>qpid-${qpid.version}/etc</outputDirectory>
- <destName>passwdVhost</destName>
- <fileMode>420</fileMode>
- </file>
- <file>
- <source>../broker/etc/qpid-server.conf</source>
+
+ <!-- Include etc -->
+ <fileSet>
+ <directory>../common/etc</directory>
<outputDirectory>qpid-${qpid.version}/etc</outputDirectory>
- <destName>qpid-server.conf</destName>
- <fileMode>420</fileMode>
- </file>
- <file>
- <source>../broker/etc/virtualhosts.xml</source>
+ <fileMode>0640</fileMode>
+ </fileSet>
+ <fileSet>
+ <directory>../broker/etc</directory>
<outputDirectory>qpid-${qpid.version}/etc</outputDirectory>
- <destName>virtualhosts.xml</destName>
- <fileMode>420</fileMode>
- </file>
- <file>
- <source>../broker/bin/qpid.start</source>
- <outputDirectory>qpid-${qpid.version}/bin</outputDirectory>
- <destName>qpid.start</destName>
- <fileMode>493</fileMode>
- </file>
- <file>
- <source>../broker/bin/qpid.stop</source>
- <outputDirectory>qpid-${qpid.version}/bin</outputDirectory>
- <destName>qpid.stop</destName>
- <fileMode>493</fileMode>
- </file>
- <file>
- <source>../broker/bin/qpid.stopall</source>
- <outputDirectory>qpid-${qpid.version}/bin</outputDirectory>
- <destName>qpid.stopall</destName>
- <fileMode>493</fileMode>
- </file>
- <file>
- <source>../common/bin/qpid-run</source>
- <outputDirectory>qpid-${qpid.version}/bin</outputDirectory>
- <destName>qpid-run</destName>
- <fileMode>493</fileMode>
- </file>
- <file>
- <source>../broker/bin/qpid-server</source>
- <outputDirectory>qpid-${qpid.version}/bin</outputDirectory>
- <destName>qpid-server</destName>
- <fileMode>493</fileMode>
- </file>
- <file>
- <source>../broker/bin/qpid-server.bat</source>
- <outputDirectory>qpid-${qpid.version}/bin</outputDirectory>
- <destName>qpid-server.bat</destName>
- <fileMode>493</fileMode>
- </file>
- <file>
- <source>../broker/bin/run.bat</source>
- <outputDirectory>qpid-${qpid.version}/bin</outputDirectory>
- <destName>run.bat</destName>
- <fileMode>493</fileMode>
- </file>
- <file>
- <source>../broker/bin/run.sh</source>
+ <fileMode>0640</fileMode>
+ </fileSet>
+
+ <!-- Include bin scripts-->
+ <fileSet>
+ <directory>../broker/bin</directory>
<outputDirectory>qpid-${qpid.version}/bin</outputDirectory>
- <destName>run.sh</destName>
- <fileMode>493</fileMode>
- </file>
- <file>
- <source>../broker/bin/runAll</source>
+ <fileMode>0750</fileMode>
+ </fileSet>
+ <fileSet>
+ <directory>../common/bin</directory>
<outputDirectory>qpid-${qpid.version}/bin</outputDirectory>
- <destName>runAll</destName>
- <fileMode>493</fileMode>
- </file>
- </files>
+ <fileMode>0750</fileMode>
+ </fileSet>
+
+ </fileSets>
+
<dependencySets>
<dependencySet>
<outputDirectory>qpid-${qpid.version}/lib</outputDirectory>
<unpack>false</unpack>
<excludes>
+ <!-- Exclude the jar output of this build process -->
<exclude>org.apache.qpid:qpid-distribution</exclude>
+ <!-- Exclude the Console dependancies -->
<exclude>org.apache.qpid.management:org.apache.qpid.management.ui</exclude>
<exclude>org.eclipse.core:org.eclipse.core.commands</exclude>
<exclude>org.eclipse.core:org.eclipse.core.contenttype</exclude>
diff --git a/java/distribution/src/main/assembly/management-eclipse-plugin-unix.xml b/java/distribution/src/main/assembly/management-eclipse-plugin-unix.xml
index 1318248b2a..02ede019e5 100644
--- a/java/distribution/src/main/assembly/management-eclipse-plugin-unix.xml
+++ b/java/distribution/src/main/assembly/management-eclipse-plugin-unix.xml
@@ -38,13 +38,21 @@
</moduleSets>
-->
<fileSets>
+
+
+ <!-- Include the currently hardwired Apache Legal bits -->
<fileSet>
- <directory>src/main/release</directory>
- <outputDirectory>qpidmc</outputDirectory>
+ <directory>../resources</directory>
+ <outputDirectory>qpid-${qpid.version}</outputDirectory>
<includes>
- <include>DISCLAIMER</include>
+ <include>DISCLAIMER</include>
+ <include>LICENSE</include>
+ <include>NOTICE</include>
+ <include>README</include>
</includes>
+ <fileMode>0444</fileMode>
</fileSet>
+
<fileSet>
<directory>..</directory>
<outputDirectory>qpidmc</outputDirectory>
@@ -52,20 +60,23 @@
<include>*.txt</include>
</includes>
</fileSet>
+
<fileSet>
- <directory>src/main/release/docs</directory>
- <outputDirectory>qpidmc/docs</outputDirectory>
- <includes>
- <include>RELEASE_NOTES.txt</include>
- </includes>
+ <directory>src/main/release</directory>
+ <outputDirectory>qpidmc</outputDirectory>
</fileSet>
+
+ <!-- Include any release information -->
+ <fileSet>
+ <directory>../release-docs</directory>
+ <outputDirectory>qpidmc</outputDirectory>
+ </fileSet>
+
<fileSet>
<directory>../management/eclipse-plugin/src/main/resources/unix/configuration</directory>
<outputDirectory>qpidmc/configuration</outputDirectory>
- <includes>
- <include>**</include>
- </includes>
</fileSet>
+
<fileSet>
<directory>../management/eclipse-plugin/src/main/resources</directory>
<outputDirectory>qpidmc</outputDirectory>
@@ -73,6 +84,7 @@
<include>license.eclipse.txt</include>
</includes>
</fileSet>
+
<fileSet>
<directory>../management/eclipse-plugin</directory>
<outputDirectory>qpidmc</outputDirectory>
@@ -80,13 +92,14 @@
<include>README.txt</include>
</includes>
</fileSet>
+
<fileSet>
<directory>../management/eclipse-plugin/bin</directory>
<outputDirectory>qpidmc/bin</outputDirectory>
<includes>
<include>qpidmc*.sh</include>
</includes>
- <fileMode>777</fileMode>
+ <fileMode>0777</fileMode>
</fileSet>
</fileSets>
@@ -100,7 +113,7 @@
</includes>
<scope>runtime</scope>
</dependencySet>
-
+
<dependencySet>
<outputDirectory>qpidmc/eclipse/plugins</outputDirectory>
<outputFileNameMapping>${artifactId}_${version}.${extension}</outputFileNameMapping>
diff --git a/java/distribution/src/main/assembly/management-eclipse-plugin.xml b/java/distribution/src/main/assembly/management-eclipse-plugin.xml
index 826128b42f..05df2c030b 100644
--- a/java/distribution/src/main/assembly/management-eclipse-plugin.xml
+++ b/java/distribution/src/main/assembly/management-eclipse-plugin.xml
@@ -24,55 +24,55 @@
<formats>
<format>zip</format>
</formats>
-<!--
- <moduleSets>
- <moduleSet>
- <includes>
- <include>org.apache.qpid.management:org.apache.qpid.management.ui</include>
- </includes>
- <binaries>
- <includeDependencies>true</includeDependencies>
- <unpack>false</unpack>
- </binaries>
- </moduleSet>
- </moduleSets>
- -->
+
<fileSets>
+
+ <!-- Include the currently hardwired Apache Legal bits -->
<fileSet>
- <directory>src/main/release</directory>
+ <directory>../resources</directory>
<outputDirectory>qpidmc</outputDirectory>
<includes>
- <include>DISCLAIMER</include>
+ <include>DISCLAIMER</include>
+ <include>LICENSE</include>
+ <include>NOTICE</include>
+ <include>README</include>
</includes>
+ <fileMode>0444</fileMode>
</fileSet>
+
<fileSet>
- <directory>..</directory>
+ <directory>src/main/release</directory>
+ <outputDirectory>qpidmc</outputDirectory>
+ </fileSet>
+
+ <!-- Include any release information -->
+ <fileSet>
+ <directory>../release-docs</directory>
<outputDirectory>qpidmc</outputDirectory>
- <includes>
- <include>*.txt</include>
- </includes>
</fileSet>
+
+
<fileSet>
- <directory>src/main/release/docs</directory>
- <outputDirectory>qpidmc/docs</outputDirectory>
+ <directory>..</directory>
+ <outputDirectory>qpidmc</outputDirectory>
<includes>
- <include>RELEASE_NOTES.txt</include>
+ <include>*.txt</include>
</includes>
</fileSet>
+
<fileSet>
<directory>../management/eclipse-plugin/src/main/resources/win32/configuration</directory>
<outputDirectory>qpidmc/configuration</outputDirectory>
- <includes>
- <include>**</include>
- </includes>
</fileSet>
+
<fileSet>
<directory>../management/eclipse-plugin/src/main/resources</directory>
<outputDirectory>qpidmc/eclipse</outputDirectory>
<includes>
<include>*.*</include>
- </includes>
+ </includes>
</fileSet>
+
<fileSet>
<directory>../management/eclipse-plugin</directory>
<outputDirectory>qpidmc</outputDirectory>
@@ -80,14 +80,20 @@
<include>README.txt</include>
</includes>
</fileSet>
+
<fileSet>
<directory>../management/eclipse-plugin/bin</directory>
<outputDirectory>qpidmc/bin</outputDirectory>
- <includes>
- <include>**</include>
- </includes>
- <fileMode>777</fileMode>
+ <excludes>
+ <!-- Exclude the Unix scripts -->
+ <exclude>qpidmc*.sh</exclude>
+ </excludes>
+ <fileMode>0777</fileMode>
</fileSet>
+
+ <!-- Required to make eclipse load the JMXRemote SASL pluging -->
+ <!-- This should be removed as JMXRemote SASL module is not ASF license friendly -->
+ <!-- However management console doesn't seem to work without it -->
<fileSet>
<directory>../management/eclipse-plugin/src/main/resources/sasl</directory>
<outputDirectory>qpidmc/eclipse/plugins/jmxremote.sasl_1.0.1/META-INF</outputDirectory>
@@ -107,7 +113,7 @@
<exclude>org.apache.qpid:qpid-common</exclude>
<exclude>org.apache.qpid:qpid-broker</exclude>
<exclude>org.apache.qpid:qpid-client</exclude>
- <exclude>commons-cli:commons-cli</exclude>
+ <exclude>commons-cli:commons-cli</exclude>
<exclude>commons-configuration:commons-configuration</exclude>
<exclude>commons-lang:commons-lang</exclude>
<exclude>org.apache.mina:mina-filter-ssl</exclude>
diff --git a/java/distribution/src/main/assembly/src.xml b/java/distribution/src/main/assembly/src.xml
index 8aa6183b4d..efdc4d98f4 100644
--- a/java/distribution/src/main/assembly/src.xml
+++ b/java/distribution/src/main/assembly/src.xml
@@ -27,24 +27,31 @@
</formats>
<fileSets>
- <fileSet>
- <directory>src/main/release</directory>
+ <fileSet>
+ <directory>../resources</directory>
<outputDirectory>qpid-${qpid.version}-src</outputDirectory>
<includes>
- <include>DISCLAIMER</include>
- <include>LICENSE.txt</include>
- <include>licenses/*.*</include>
- <include>NOTICE.txt</include>
- <include>README.txt</include>
- <include>BUILDING.txt</include>
+ <include>DISCLAIMER</include>
+ <include>LICENSE</include>
+ <include>NOTICE</include>
+ <include>README</include>
</includes>
</fileSet>
+
+ <fileSet>
+ <directory>src/main/release</directory>
+ <outputDirectory>qpid-${qpid.version}-src</outputDirectory>
+ </fileSet>
+
+ <!-- Include any release information -->
+ <fileSet>
+ <directory>../release-docs</directory>
+ <outputDirectory>qpid-${qpid.version}-src</outputDirectory>
+ </fileSet>
+
<fileSet>
<directory>..</directory>
<outputDirectory>qpid-${qpid.version}-src/java</outputDirectory>
- <includes>
- <include>**/*</include>
- </includes>
<excludes>
<exclude>build.xml</exclude>
<exclude>distribution/build.xml</exclude>
@@ -71,24 +78,29 @@
<exclude>**/eclipse-plugin/src/main/resources/**</exclude>
</excludes>
</fileSet>
+
<fileSet>
<directory>../../gentools</directory>
<outputDirectory>qpid-${qpid.version}-src/gentools</outputDirectory>
- <includes>
- <include>**/*</include>
- </includes>
<excludes>
<exclude>**/build</exclude>
<exclude>**/build/**/*</exclude>
<exclude>**/*.class</exclude>
</excludes>
</fileSet>
+
<fileSet>
<directory>../../specs</directory>
<outputDirectory>qpid-${qpid.version}-src/specs</outputDirectory>
<includes>
- <include>**/*</include>
+ <include>amqp.0-8.xml</include>
+ <include>cluster.0-8.xml</include>
</includes>
+ </fileSet>
+
+ <fileSet>
+ <directory>../../python</directory>
+ <outputDirectory>qpid-${qpid.version}-src/python</outputDirectory>
</fileSet>
</fileSets>
</assembly>
diff --git a/java/distribution/src/main/release/DISCLAIMER b/java/distribution/src/main/release/DISCLAIMER
deleted file mode 100644
index c321113c9e..0000000000
--- a/java/distribution/src/main/release/DISCLAIMER
+++ /dev/null
@@ -1,5 +0,0 @@
-Apache Qpid is an effort undergoing incubation at the Apache Software Foundation (ASF), sponsored by the Apache Incubator PMC.
-
-Incubation is required of all newly accepted projects until a further review indicates that the infrastructure, communications, and decision making process have stabilized in a manner consistent with other successful ASF projects.
-
-While incubation status is not necessarily a reflection of the completeness or stability of the code, it does indicate that the project has yet to be fully endorsed by the ASF.
diff --git a/java/distribution/src/main/release/NOTICE.txt b/java/distribution/src/main/release/NOTICE.txt
deleted file mode 100644
index 82d3dbc632..0000000000
--- a/java/distribution/src/main/release/NOTICE.txt
+++ /dev/null
@@ -1,36 +0,0 @@
-=========================================================================
-== NOTICE file corresponding to the section 4 d of ==
-== the Apache License, Version 2.0, ==
-== in this case for the Apache Qpid distribution. ==
-=========================================================================
-
-This product includes software developed by the Apache Software Foundation
-(http://www.apache.org/).
-
-Please read the LICENSE.txt file present in the root directory of this
-distribution.
-
-
-Aside from contributions to the Apache Qpid project, this software also
-includes (binary only):
-
- - The SAXON XSLT Processor from Michael Kay distributed under the
- Mozilla Public License v1.0, which is available for download at
- http://saxon.sourceforge.net/
-
- - The JUnit regression testing framework written by Erich Gamma
- and Kent Beck and distributed under the Common Public License v1.0.
- JUnit is available for download at
- http://sourceforge.net/projects/junit/
-
- - The Simple Logging Facade For Java (slf4j), Copyright (c)
- 2004-2005 SLF4J.ORG, Copyright (c) 2004-2005 QOS.ch. slf4j is
- licensed under identical terms to the MIT/X11 license and
- available for download at http://www.slf4j.org/
-
- - Software from the Eclipse project. The binaries from this project are
- distributed under the Eclipse Public License and can be donwloaded
- from http://www.eclipse.org/
-
-
-
diff --git a/java/distribution/src/main/release/README.txt b/java/distribution/src/main/release/README.txt
deleted file mode 100644
index 14706170bc..0000000000
--- a/java/distribution/src/main/release/README.txt
+++ /dev/null
@@ -1,104 +0,0 @@
-
-Documentation
---------------
-All of our user documentation for the Qpid Java components can be accessed on our wiki at:
-
-http://cwiki.apache.org/confluence/display/qpid/Qpid+Java+Documentation
-
-This includes a Getting Started Guide and FAQ as well as detailed developer documentation.
-However, here's a VERY quick guide to running the installed Qpid broker, once you have installed it somewhere !
-
-
-Running the Broker
-------------------
-
-To run the broker, set the QPID_HOME environment variable to
-distribution directory and add $QPID_HOME/bin to your PATH. Then run
-the qpid-server shell script or qpid-server.bat batch file to start
-the broker. By default, the broker will use $QPID_HOME/etc to find
-the configuration files. You can supply a custom configuration using
-the -c argument.
-
-For example:
-
-qpid-server -c ~/etc/config.xml
-
-You can get a list of all command line arguments by using the -h argument.
-
-
-Developing
-----------
-
-In order to build Qpid you need Ant 1.6.5. Use ant -p to list the
-available targets. The default ant target, build, creates a working
-development-mode distribution in the build directory. To run the
-scripts in build/bin set QPID_HOME to the build directory and put
-${QPID_HOME}/bin on your PATH. The scripts in that directory include
-the standard ones in the distribution and a number of testing scripts.
-
-
-Running Tests
--------------
-
-The simplest test to ensure everything is working is the "service
-request reply" test. This involves one client that is known as a
-"service provider" and it listens on a well-known queue for
-requests. Another client, known as the "service requester" creates a
-private (temporary) response queue, creates a message with the private
-response queue set as the "reply to" field and then publishes the
-message to the well known service queue. The test allows you to time
-how long it takes to send messages and receive the response back. It
-also allows varying of the message size.
-
-You must start the service provider first:
-
-serviceProvidingClient.sh nop host:port
-
-where host:port is the host and port you are running the broker
-on.
-
-To run the service requester:
-
-serviceRequestingClient.sh nop host:post <count> <bytes>
-
-This requests <count> messages, each of size <bytes>. After
-receiving all the messages the client outputs the rate it achieved.
-
-A more realistic test is the "headers test", which tests the
-performance of routing messages based on message headers to a
-configurable number of clients (e.g. 50). A publisher sends 10000
-messages to each client and waits to receive a message from each
-client when it has received all the messages.
-
-You run the listener processes first:
-
-run_many.sh 10 header "headersListener.sh -host 10.0.0.1 -port 5672"
-
-In this command, the first argument means start 10 processes, the
-second is just a name use in the log files generated and the third
-argument is the command to run. In this case it runs another shell
-script but it could be anything.
-
-Then run the publisher process:
-
-headersPublisher.sh -host 10.0.0.1 -port 5672 10000 10
-
-The last two arguments are: the number of messages to send to each
-client, and the number of clients.
-
-Note that before starting the publisher you should wait about 30
-seconds to ensure all the clients are registered with the broker (you
-can see this from the broker output). Otherwise the numbers will be
-slightly skewed.
-
-A third useful test, which can easily be ported to other JMS
-implementations is the "topic test". It does the same as the headers
-test but using a standard topic (e.g. pub sub).
-
-To run the listeners:
-
-run_many.sh 10 topic "topicListener.sh -host 10.0.0.1 -port 5672"
-
-and to run the publisher:
-
-topicPublisher.sh -host 10.0.0.1 -port 5672 -clients 10 -messages 10000
diff --git a/java/etc/coding_standards.xml b/java/etc/coding_standards.xml
index 00b1a9516a..8f8b808884 100644
--- a/java/etc/coding_standards.xml
+++ b/java/etc/coding_standards.xml
@@ -1,8 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE module PUBLIC "-//Puppy Crawl//DTD Check Configuration 1.1//EN" "http://www.puppycrawl.com/dtds/configuration_1_1.dtd">
<module name="Checker">
+
<!-- Checks package.html defined for all packages. -->
- <module name="PackageHtml"/>
+ <!-- <module name="PackageHtml"/> -->
<module name="TreeWalker">
diff --git a/java/integrationtests/docs/RunningSustainedTests.txt b/java/integrationtests/docs/RunningSustainedTests.txt
index 2b37f4c5a7..db4405a32d 100644
--- a/java/integrationtests/docs/RunningSustainedTests.txt
+++ b/java/integrationtests/docs/RunningSustainedTests.txt
@@ -1,15 +1,17 @@
In addition to the integration tests the framework provided by this package also allows for
sustained tests to be run. Currently avaible tests:
-- org.apache.qpid.sustained.SustainedTestClient : Pub Sub test to determine steady state throughput.
+- org.apache.qpid.sustained.SustainedClientTestCase : Pub Sub test to determine steady state throughput.
Running Tests.
Run the tests as per the integration tests.
- - Start a broker
- - Start at least one Client [java org.apache.qpid.sustained.TestClient], ensuring unique naming
- - Start Test Controller [java org.apache.qpid.sustained.TestCoordinator]
- - Additional Test clients can be started:
- [java org.apache.qpid.sustained.TestClient -j org.apache.qpid.sustained.SustainedTestClient]
+- Start a broker
+- Start at least one test client [java org.apache.qpid.interop.TestClient], ensuring unique naming.
+
+- Start the test coordinator with the 'fanout' engine, on the sustained test case [java org.apache.qpid.test.framework.distributedtesting.Coordinator]
+
+- Additional Test clients can be started and joined into the running test: [java org.apache.qpid.interop.TestClient -j]
+
diff --git a/java/integrationtests/pom.xml b/java/integrationtests/pom.xml
index 9ccd153f54..89fd5ede28 100644
--- a/java/integrationtests/pom.xml
+++ b/java/integrationtests/pom.xml
@@ -40,12 +40,16 @@
<dependencies>
- <!-- These tests depend on the client API only. -->
<dependency>
<groupId>org.apache.qpid</groupId>
<artifactId>qpid-client</artifactId>
</dependency>
+ <dependency>
+ <groupId>org.apache.qpid</groupId>
+ <artifactId>qpid-systests</artifactId>
+ </dependency>
+
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
diff --git a/java/integrationtests/src/main/java/org/apache/qpid/interop/testclient/testcases/TestCase1DummyRun.java b/java/integrationtests/src/main/java/org/apache/qpid/interop/clienttestcases/TestCase1DummyRun.java
index 5f257c0b36..b119d13a3d 100644
--- a/java/integrationtests/src/main/java/org/apache/qpid/interop/testclient/testcases/TestCase1DummyRun.java
+++ b/java/integrationtests/src/main/java/org/apache/qpid/interop/clienttestcases/TestCase1DummyRun.java
@@ -18,11 +18,11 @@
* under the License.
*
*/
-package org.apache.qpid.interop.testclient.testcases;
+package org.apache.qpid.interop.clienttestcases;
import org.apache.log4j.Logger;
-import org.apache.qpid.interop.testclient.InteropClientTestCase;
+import org.apache.qpid.test.framework.distributedtesting.InteropClientTestCase;
import javax.jms.JMSException;
import javax.jms.Message;
@@ -43,8 +43,15 @@ import javax.jms.Session;
*/
public class TestCase1DummyRun implements InteropClientTestCase
{
+ /** Used for debugging. */
private static final Logger log = Logger.getLogger(TestCase1DummyRun.class);
+ /**
+ * Should provide the name of the test case that this class implements. The exact names are defined in the
+ * interop testing spec.
+ *
+ * @return The name of the test case that this implements.
+ */
public String getName()
{
log.debug("public String getName(): called");
@@ -52,6 +59,15 @@ public class TestCase1DummyRun implements InteropClientTestCase
return "TC1_DummyRun";
}
+ /**
+ * Determines whether the test invite that matched this test case is acceptable.
+ *
+ * @param inviteMessage The invitation to accept or reject.
+ *
+ * @return <tt>true</tt> to accept the invitation, <tt>false</tt> to reject it.
+ *
+ * @throws JMSException Any JMSException resulting from reading the message are allowed to fall through.
+ */
public boolean acceptInvite(Message inviteMessage) throws JMSException
{
log.debug("public boolean acceptInvite(Message inviteMessage): called");
@@ -60,6 +76,15 @@ public class TestCase1DummyRun implements InteropClientTestCase
return true;
}
+ /**
+ * Assigns the role to be played by this test case. The test parameters are fully specified in the
+ * assignment message. When this method return the test case will be ready to execute.
+ *
+ * @param role The role to be played; sender or receivers.
+ * @param assignRoleMessage The role assingment message, contains the full test parameters.
+ *
+ * @throws JMSException Any JMSException resulting from reading the message are allowed to fall through.
+ */
public void assignRole(Roles role, Message assignRoleMessage) throws JMSException
{
log.debug("public void assignRole(Roles role, Message assignRoleMessage): called");
@@ -67,6 +92,9 @@ public class TestCase1DummyRun implements InteropClientTestCase
// Do nothing, both roles are the same.
}
+ /**
+ * Performs the test case actions. Returning from here, indicates that the sending role has completed its test.
+ */
public void start()
{
log.debug("public void start(): called");
@@ -74,11 +102,15 @@ public class TestCase1DummyRun implements InteropClientTestCase
// Do nothing.
}
- public void terminate() throws JMSException
- {
- //todo
- }
-
+ /**
+ * Gets a report on the actions performed by the test case in its assigned role.
+ *
+ * @param session The session to create the report message in.
+ *
+ * @return The report message.
+ *
+ * @throws JMSException Any JMSExceptions resulting from creating the report are allowed to fall through.
+ */
public Message getReport(Session session) throws JMSException
{
log.debug("public Message getReport(Session session): called");
@@ -87,6 +119,11 @@ public class TestCase1DummyRun implements InteropClientTestCase
return session.createTextMessage("Dummy Run, Ok.");
}
+ /**
+ * Handles incoming test messages. Does nothing.
+ *
+ * @param message The incoming test message.
+ */
public void onMessage(Message message)
{
log.debug("public void onMessage(Message message = " + message + "): called");
diff --git a/java/integrationtests/src/main/java/org/apache/qpid/interop/testclient/testcases/TestCase2BasicP2P.java b/java/integrationtests/src/main/java/org/apache/qpid/interop/clienttestcases/TestCase2BasicP2P.java
index ff56ee9b93..080bd846ee 100644
--- a/java/integrationtests/src/main/java/org/apache/qpid/interop/testclient/testcases/TestCase2BasicP2P.java
+++ b/java/integrationtests/src/main/java/org/apache/qpid/interop/clienttestcases/TestCase2BasicP2P.java
@@ -18,14 +18,15 @@
* under the License.
*
*/
-package org.apache.qpid.interop.testclient.testcases;
-
-import javax.jms.*;
+package org.apache.qpid.interop.clienttestcases;
import org.apache.log4j.Logger;
-import org.apache.qpid.interop.testclient.InteropClientTestCase;
-import org.apache.qpid.interop.testclient.TestClient;
+import org.apache.qpid.test.framework.distributedtesting.InteropClientTestCase;
+import org.apache.qpid.test.framework.distributedtesting.TestClient;
+import org.apache.qpid.test.framework.TestUtils;
+
+import javax.jms.*;
/**
* Implements test case 2, basic P2P. Sends/received a specified number of messages to a specified route on the
@@ -54,9 +55,6 @@ public class TestCase2BasicP2P implements InteropClientTestCase
/** The number of test messages to send. */
private int numMessages;
- /** The routing key to send them to on the default direct exchange. */
- private Destination sendDestination;
-
/** The connection to send the test messages on. */
private Connection connection;
@@ -100,7 +98,7 @@ public class TestCase2BasicP2P implements InteropClientTestCase
* Assigns the role to be played by this test case. The test parameters are fully specified in the
* assignment message. When this method return the test case will be ready to execute.
*
- * @param role The role to be played; sender or receiver.
+ * @param role The role to be played; sender or receivers.
*
* @param assignRoleMessage The role assingment message, contains the full test parameters.
*
@@ -118,14 +116,12 @@ public class TestCase2BasicP2P implements InteropClientTestCase
this.role = role;
// Create a new connection to pass the test messages on.
- connection =
- TestClient.createConnection(TestClient.DEFAULT_CONNECTION_PROPS_RESOURCE, TestClient.brokerUrl,
- TestClient.virtualHost);
+ connection = TestUtils.createConnection(TestClient.testContextProperties);
session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
// Extract and retain the test parameters.
numMessages = assignRoleMessage.getIntProperty("P2P_NUM_MESSAGES");
- sendDestination = session.createQueue(assignRoleMessage.getStringProperty("P2P_QUEUE_AND_KEY_NAME"));
+ Destination sendDestination = session.createQueue(assignRoleMessage.getStringProperty("P2P_QUEUE_AND_KEY_NAME"));
log.debug("numMessages = " + numMessages);
log.debug("sendDestination = " + sendDestination);
@@ -138,7 +134,7 @@ public class TestCase2BasicP2P implements InteropClientTestCase
producer = session.createProducer(sendDestination);
break;
- // Otherwise the receiver role is being assigned, so set this up to listen for messages.
+ // Otherwise the receivers role is being assigned, so set this up to listen for messages.
case RECEIVER:
MessageConsumer consumer = session.createConsumer(sendDestination);
consumer.setMessageListener(this);
@@ -149,7 +145,9 @@ public class TestCase2BasicP2P implements InteropClientTestCase
}
/**
- * Performs the test case actions.
+ * Performs the test case actions. Returning from here, indicates that the sending role has completed its test.
+ *
+ * @throws JMSException Any JMSException resulting from reading the message are allowed to fall through.
*/
public void start() throws JMSException
{
@@ -170,11 +168,6 @@ public class TestCase2BasicP2P implements InteropClientTestCase
}
}
- public void terminate() throws JMSException
- {
- //todo
- }
-
/**
* Gets a report on the actions performed by the test case in its assigned role.
*
diff --git a/java/integrationtests/src/main/java/org/apache/qpid/interop/testclient/testcases/TestCase3BasicPubSub.java b/java/integrationtests/src/main/java/org/apache/qpid/interop/clienttestcases/TestCase3BasicPubSub.java
index 7b35142c82..a11d045e89 100644
--- a/java/integrationtests/src/main/java/org/apache/qpid/interop/testclient/testcases/TestCase3BasicPubSub.java
+++ b/java/integrationtests/src/main/java/org/apache/qpid/interop/clienttestcases/TestCase3BasicPubSub.java
@@ -18,18 +18,19 @@
* under the License.
*
*/
-
-package org.apache.qpid.interop.testclient.testcases;
-
-import javax.jms.*;
+package org.apache.qpid.interop.clienttestcases;
import org.apache.log4j.Logger;
-import org.apache.qpid.interop.testclient.InteropClientTestCase;
+import org.apache.qpid.test.framework.distributedtesting.InteropClientTestCase;
+import org.apache.qpid.test.framework.distributedtesting.TestClient;
+import org.apache.qpid.test.framework.TestUtils;
+
+import javax.jms.*;
/**
* Implements test case 3, basic pub/sub. Sends/received a specified number of messages to a specified route on the
- * default topic exchange, using the specified number of receiver connections. Produces reports on the actual number of
+ * default topic exchange, using the specified number of receivers connections. Produces reports on the actual number of
* messages sent/received.
*
* <p><table id="crc"><caption>CRC Card</caption>
@@ -55,12 +56,6 @@ public class TestCase3BasicPubSub implements InteropClientTestCase
/** The number of test messages to send. */
private int numMessages;
- /** The number of receiver connection to use. */
- private int numReceivers;
-
- /** The routing key to send them to on the default direct exchange. */
- private Destination sendDestination;
-
/** The connections to send/receive the test messages on. */
private Connection[] connection;
@@ -104,7 +99,7 @@ public class TestCase3BasicPubSub implements InteropClientTestCase
* Assigns the role to be played by this test case. The test parameters are fully specified in the
* assignment message. When this method return the test case will be ready to execute.
*
- * @param role The role to be played; sender or receiver.
+ * @param role The role to be played; sender or receivers.
*
* @param assignRoleMessage The role assingment message, contains the full test parameters.
*
@@ -123,7 +118,7 @@ public class TestCase3BasicPubSub implements InteropClientTestCase
// Extract and retain the test parameters.
numMessages = assignRoleMessage.getIntProperty("PUBSUB_NUM_MESSAGES");
- numReceivers = assignRoleMessage.getIntProperty("PUBSUB_NUM_RECEIVERS");
+ int numReceivers = assignRoleMessage.getIntProperty("PUBSUB_NUM_RECEIVERS");
String sendKey = assignRoleMessage.getStringProperty("PUBSUB_KEY");
log.debug("numMessages = " + numMessages);
@@ -139,29 +134,25 @@ public class TestCase3BasicPubSub implements InteropClientTestCase
connection = new Connection[1];
session = new Session[1];
- connection[0] =
- org.apache.qpid.interop.testclient.TestClient.createConnection(org.apache.qpid.interop.testclient.TestClient.DEFAULT_CONNECTION_PROPS_RESOURCE, org.apache.qpid.interop.testclient.TestClient.brokerUrl,
- org.apache.qpid.interop.testclient.TestClient.virtualHost);
+ connection[0] = TestUtils.createConnection(TestClient.testContextProperties);
session[0] = connection[0].createSession(false, Session.AUTO_ACKNOWLEDGE);
// Extract and retain the test parameters.
- sendDestination = session[0].createTopic(sendKey);
+ Destination sendDestination = session[0].createTopic(sendKey);
producer = session[0].createProducer(sendDestination);
break;
- // Otherwise the receiver role is being assigned, so set this up to listen for messages on the required number
- // of receiver connections.
+ // Otherwise the receivers role is being assigned, so set this up to listen for messages on the required number
+ // of receivers connections.
case RECEIVER:
- // Create the required number of receiver connections.
+ // Create the required number of receivers connections.
connection = new Connection[numReceivers];
session = new Session[numReceivers];
for (int i = 0; i < numReceivers; i++)
{
- connection[i] =
- org.apache.qpid.interop.testclient.TestClient.createConnection(org.apache.qpid.interop.testclient.TestClient.DEFAULT_CONNECTION_PROPS_RESOURCE, org.apache.qpid.interop.testclient.TestClient.brokerUrl,
- org.apache.qpid.interop.testclient.TestClient.virtualHost);
+ connection[i] = TestUtils.createConnection(TestClient.testContextProperties);
session[i] = connection[i].createSession(false, Session.AUTO_ACKNOWLEDGE);
sendDestination = session[i].createTopic(sendKey);
@@ -174,14 +165,16 @@ public class TestCase3BasicPubSub implements InteropClientTestCase
}
// Start all the connection dispatcher threads running.
- for (int i = 0; i < connection.length; i++)
+ for (Connection conn : connection)
{
- connection[i].start();
+ conn.start();
}
}
/**
- * Performs the test case actions.
+ * Performs the test case actions. Returning from here, indicates that the sending role has completed its test.
+ *
+ * @throws JMSException Any JMSException resulting from reading the message are allowed to fall through.
*/
public void start() throws JMSException
{
@@ -202,11 +195,6 @@ public class TestCase3BasicPubSub implements InteropClientTestCase
}
}
- public void terminate() throws JMSException, InterruptedException
- {
- //todo
- }
-
/**
* Gets a report on the actions performed by the test case in its assigned role.
*
@@ -221,9 +209,9 @@ public class TestCase3BasicPubSub implements InteropClientTestCase
log.debug("public Message getReport(Session session): called");
// Close the test connections.
- for (int i = 0; i < connection.length; i++)
+ for (Connection conn : connection)
{
- connection[i].close();
+ conn.close();
}
// Generate a report message containing the count of the number of messages passed.
diff --git a/java/integrationtests/src/main/java/org/apache/qpid/interop/coordinator/CoordinatingTestCase.java b/java/integrationtests/src/main/java/org/apache/qpid/interop/coordinator/CoordinatingTestCase.java
deleted file mode 100644
index d2042be741..0000000000
--- a/java/integrationtests/src/main/java/org/apache/qpid/interop/coordinator/CoordinatingTestCase.java
+++ /dev/null
@@ -1,263 +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.interop.coordinator;
-
-import junit.framework.TestCase;
-
-import org.apache.log4j.Logger;
-
-import org.apache.qpid.util.ConversationFactory;
-
-import javax.jms.*;
-
-import java.util.Map;
-
-/**
- * A CoordinatingTestCase is a JUnit test case extension that knows how to coordinate test clients that take part in a
- * test case as defined in the interop testing specification
- * (http://cwiki.apache.org/confluence/display/qpid/Interop+Testing+Specification).
- *
- * <p/>The real logic of the test cases built on top of this, is embeded in the comparison of the sender and receiver
- * reports. An example test method might look like:
- *
- * <p/><pre>
- * public void testExample()
- * {
- * Properties testConfig = new Properties();
- * testConfig.add("TEST_CASE", "example");
- * ...
- *
- * Report[] reports = sequenceTest(testConfig);
- *
- * // Compare sender and receiver reports.
- * if (report[0] ... report[1] ...)
- * {
- * Assert.fail("Sender and receiver reports did not match up.");
- * }
- * }
- *
- * </pre>
- *
- * <p><table id="crc"><caption>CRC Card</caption>
- * <tr><th> Responsibilities <th> Collaborations
- * <tr><td> Accept notification of test case participants. <td> {@link InvitingTestDecorator}
- * <tr><td> Accpet JMS Connection to carry out the coordination over.
- * <tr><td> Coordinate the test sequence amongst participants. <td> {@link ConversationFactory}
- * <tr><td> Supply test properties
- * </table>
- */
-public abstract class CoordinatingTestCase extends TestCase
-{
- /** Used for debugging. */
- private static final Logger log = Logger.getLogger(CoordinatingTestCase.class);
-
- /** Holds the contact details for the sending test client. */
- protected TestClientDetails sender;
-
- /** Holds the contact details for the receving test client. */
- protected TestClientDetails receiver;
-
- /** Holds the conversation factory over which to coordinate the test. */
- protected ConversationFactory conversationFactory;
-
- /**
- * Creates a new coordinating test case with the specified name.
- *
- * @param name The test case name.
- */
- public CoordinatingTestCase(String name)
- {
- super(name);
- }
-
- /**
- * Sets the sender test client to coordinate the test with.
- *
- * @param sender The contact details of the sending client in the test.
- */
- public void setSender(TestClientDetails sender)
- {
- log.debug("public void setSender(TestClientDetails sender = " + sender + "): called");
-
- this.sender = sender;
- }
-
- /**
- * Sets the receiving test client to coordinate the test with.
- *
- * @param receiver The contact details of the sending client in the test.
- */
- public void setReceiver(TestClientDetails receiver)
- {
- log.debug("public void setReceiver(TestClientDetails receiver = " + receiver + "): called");
-
- this.receiver = receiver;
- }
-
- /**
- * Supplies the sending test client.
- *
- * @return The sending test client.
- */
- public TestClientDetails getSender()
- {
- return sender;
- }
-
- /**
- * Supplies the receiving test client.
- *
- * @return The receiving test client.
- */
- public TestClientDetails getReceiver()
- {
- return receiver;
- }
-
- /**
- * Returns the name of the current test method of this test class, with the sending and receiving client names
- * appended on to it, so that the resulting name unqiuely identifies the test and the clients that participated
- * in it.
- *
- * @return The unique test and client name.
- */
- public String getName()
- {
- if ((sender == null) || (receiver == null))
- {
- return super.getName();
- }
- else
- {
- return super.getName() + "_sender_" + sender.clientName + "_receiver_" + receiver.clientName;
- }
- }
-
- /**
- * Should provide a translation from the junit method name of a test to its test case name as defined in the
- * interop testing specification. For example the method "testP2P" might map onto the interop test case name
- * "TC2_BasicP2P".
- *
- * @param methodName The name of the JUnit test method.
- *
- * @return The name of the corresponding interop test case.
- */
- public abstract String getTestCaseNameForTestMethod(String methodName);
-
- /**
- * Accepts the conversation factory over which to hold the test coordinating conversation.
- *
- * @param conversationFactory The conversation factory to coordinate the test over.
- */
- public void setConversationFactory(ConversationFactory conversationFactory)
- {
- this.conversationFactory = conversationFactory;
- }
-
- /**
- * Holds a test coordinating conversation with the test clients. This is the basic implementation of the inner
- * loop of Use Case 5. It consists of assigning the test roles, begining the test and gathering the test reports
- * from the participants.
- *
- * @param testProperties The test case definition.
- *
- * @return The test results from the senders and receivers.
- *
- * @throws JMSException All underlying JMSExceptions are allowed to fall through.
- */
- protected Message[] sequenceTest(Map<String, Object> testProperties) throws JMSException
- {
- log.debug("protected Message[] sequenceTest(Object... testProperties = " + testProperties + "): called");
-
- Session session = conversationFactory.getSession();
- Destination senderControlTopic = session.createTopic(sender.privateControlKey);
- Destination receiverControlTopic = session.createTopic(receiver.privateControlKey);
-
- ConversationFactory.Conversation senderConversation = conversationFactory.startConversation();
- ConversationFactory.Conversation receiverConversation = conversationFactory.startConversation();
-
- // Assign the sender role to the sending test client.
- Message assignSender = conversationFactory.getSession().createMessage();
- setPropertiesOnMessage(assignSender, testProperties);
- assignSender.setStringProperty("CONTROL_TYPE", "ASSIGN_ROLE");
- assignSender.setStringProperty("ROLE", "SENDER");
-
- senderConversation.send(senderControlTopic, assignSender);
-
- // Assign the receiver role the receiving client.
- Message assignReceiver = session.createMessage();
- setPropertiesOnMessage(assignReceiver, testProperties);
- assignReceiver.setStringProperty("CONTROL_TYPE", "ASSIGN_ROLE");
- assignReceiver.setStringProperty("ROLE", "RECEIVER");
-
- receiverConversation.send(receiverControlTopic, assignReceiver);
-
- // Wait for the senders and receivers to confirm their roles.
- senderConversation.receive();
- receiverConversation.receive();
-
- // Start the test.
- Message start = session.createMessage();
- start.setStringProperty("CONTROL_TYPE", "START");
-
- senderConversation.send(senderControlTopic, start);
-
- // Wait for the test sender to return its report.
- Message senderReport = senderConversation.receive();
-
- try
- {
- Thread.sleep(500);
- }
- catch (InterruptedException e)
- { }
-
- // Ask the receiver for its report.
- Message statusRequest = session.createMessage();
- statusRequest.setStringProperty("CONTROL_TYPE", "STATUS_REQUEST");
-
- receiverConversation.send(receiverControlTopic, statusRequest);
-
- // Wait for the receiver to send its report.
- Message receiverReport = receiverConversation.receive();
-
- return new Message[] { senderReport, receiverReport };
- }
-
- /**
- * Sets properties of different types on a JMS Message.
- *
- * @param message The message to set properties on.
- * @param properties The property name/value pairs to set.
- *
- * @throws JMSException All underlying JMSExceptions are allowed to fall through.
- */
- public void setPropertiesOnMessage(Message message, Map<String, Object> properties) throws JMSException
- {
- for (Map.Entry<String, Object> entry : properties.entrySet())
- {
- String name = entry.getKey();
- Object value = entry.getValue();
-
- message.setObjectProperty(name, value);
- }
- }
-}
diff --git a/java/integrationtests/src/main/java/org/apache/qpid/interop/coordinator/ListeningTestDecorator.java b/java/integrationtests/src/main/java/org/apache/qpid/interop/coordinator/ListeningTestDecorator.java
deleted file mode 100644
index 4312dfbcc6..0000000000
--- a/java/integrationtests/src/main/java/org/apache/qpid/interop/coordinator/ListeningTestDecorator.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.interop.coordinator;
-
-import junit.framework.Test;
-import junit.framework.TestResult;
-import org.apache.log4j.Logger;
-import org.apache.qpid.util.ConversationFactory;
-import uk.co.thebadgerset.junit.extensions.WrappedSuiteTestDecorator;
-
-import javax.jms.Connection;
-import javax.jms.Destination;
-import javax.jms.JMSException;
-import javax.jms.Message;
-import javax.jms.MessageListener;
-import java.util.Collection;
-import java.util.Iterator;
-import java.util.Set;
-
-/**
- * <p><table id="crc"><caption>CRC Card</caption> <tr><th> Responsibilities <th> Collaborations <tr><td> Broadcast test
- * invitations and collect enlists. <td> {@link ConversationFactory}. <tr><td> Output test failures for clients
- * unwilling to run the test case. <td> {@link Coordinator} <tr><td> Execute coordinated test cases. <td> {@link
- * CoordinatingTestCase} </table>
- */
-public class ListeningTestDecorator extends WrappedSuiteTestDecorator implements MessageListener
-{
- private static final Logger log = Logger.getLogger(ListeningTestDecorator.class);
-
- /** Holds the contact information for all test clients that are available and that may take part in the test. */
- Set<TestClientDetails> allClients;
-
- /** Holds the conversation helper for the control level conversation for coordinating the test through. */
- ConversationFactory conversationFactory;
-
- /** Holds the connection that the control conversation is held over. */
- Connection connection;
-
- /** Holds the underlying {@link CoordinatingTestCase}s that this decorator wraps. */
- WrappedSuiteTestDecorator testSuite;
-
- /** Hold the current running test case. */
- CoordinatingTestCase _currentTest = null;
-
- /**
- * Creates a wrapped suite test decorator from another one.
- *
- * @param suite The test suite.
- * @param availableClients The list of all clients that responded to the compulsory invite.
- * @param controlConversation The conversation helper for the control level, test coordination conversation.
- * @param controlConnection The connection that the coordination messages are sent over.
- */
- public ListeningTestDecorator(WrappedSuiteTestDecorator suite, Set<TestClientDetails> availableClients,
- ConversationFactory controlConversation, Connection controlConnection)
- {
- super(suite);
-
- log.debug("public InvitingTestDecorator(WrappedSuiteTestDecorator suite, Set<TestClientDetails> allClients = "
- + availableClients + ", ConversationHelper controlConversation = " + controlConversation + "): called");
-
- testSuite = suite;
- allClients = availableClients;
- conversationFactory = controlConversation;
- connection = controlConnection;
- }
-
- /**
- * Broadcasts a test invitation and accetps enlisting from participating clients. The wrapped test case is then
- * repeated for every combination of test clients (provided the wrapped test case extends {@link
- * CoordinatingTestCase}.
- *
- * <p/>Any JMSExceptions during the invite/enlist conversation will be allowed to fall through as runtime
- * exceptions, resulting in the non-completion of the test run.
- *
- * @param testResult The the results object to monitor the test results with.
- *
- * @todo Better error recovery for failure of the invite/enlist conversation could be added.
- */
- public void run(TestResult testResult)
- {
- log.debug("public void run(TestResult testResult): called");
-
- Collection<Test> tests = testSuite.getAllUnderlyingTests();
-
- for (Test test : tests)
- {
- CoordinatingTestCase coordTest = (CoordinatingTestCase) test;
-
- Set<TestClientDetails> enlists = signupClients(coordTest);
-
- if (enlists.size() == 0)
- {
- throw new RuntimeException("No clients to test with");
- }
-
- Iterator<TestClientDetails> clients = enlists.iterator();
- coordTest.setSender(clients.next());
-
- while (clients.hasNext())
- {
- // Set the sending and receiving client details on the test case.
- coordTest.setReceiver(clients.next());
- }
-
- // Pass down the connection to hold the coordination conversation over.
- coordTest.setConversationFactory(conversationFactory);
-
-
- if (coordTest instanceof ListeningCoordinatorTest)
- {
- _currentTest = coordTest;
- }
- // Execute the test case.
- coordTest.run(testResult);
-
- _currentTest = null;
- }
- }
-
- private Set<TestClientDetails> signupClients(CoordinatingTestCase coordTest)
- {
- // Broadcast the invitation to find out what clients are available to test.
- Set<TestClientDetails> enlists;
- try
- {
- Message invite = conversationFactory.getSession().createMessage();
- Destination controlTopic = conversationFactory.getSession().createTopic("iop.control");
- ConversationFactory.Conversation conversation = conversationFactory.startConversation();
-
- invite.setStringProperty("CONTROL_TYPE", "INVITE");
- invite.setStringProperty("TEST_NAME", coordTest.getTestCaseNameForTestMethod(coordTest.getName()));
-
- conversation.send(controlTopic, invite);
-
- // Wait for a short time, to give test clients an opportunity to reply to the invitation.
- Collection<Message> replies = conversation.receiveAll(allClients.size(), 5000);
-
- log.debug("Received " + replies.size() + " enlist replies");
-
- enlists = Coordinator.extractEnlists(replies);
-
- //Create topic to listen on for latejoiners
- Destination listenTopic = conversationFactory.getSession().createTopic("iop.control.test." + coordTest.getTestCaseNameForTestMethod(coordTest.getName()));
-
- //Listen for joiners
- conversationFactory.getSession().createConsumer(listenTopic).setMessageListener(this);
- log.debug("Created consumer on :" + listenTopic);
- }
- catch (JMSException e)
- {
- throw new RuntimeException("There was a JMSException during the invite/enlist conversation.", e);
- }
-
- return enlists;
- }
-
- /**
- * Prints a string summarizing this test decorator, mainly for debugging purposes.
- *
- * @return String representation for debugging purposes.
- */
- public String toString()
- {
- return "ListeningTestDecorator: [ testSuite = " + testSuite + " ]";
- }
-
-
- public void onMessage(Message message)
- {
- try
- {
- if (message.getStringProperty("CONTROL_TYPE").equals("LATEJOIN"))
- {
- ((ListeningCoordinatorTest) _currentTest).latejoin(message);
- }
- }
- catch (JMSException e)
- {
- log.debug("Unable to process message:" + message);
- }
- }
-}
diff --git a/java/integrationtests/src/main/java/org/apache/qpid/interop/old/Listener.java b/java/integrationtests/src/main/java/org/apache/qpid/interop/old/Listener.java
deleted file mode 100644
index 5545f8d2dc..0000000000
--- a/java/integrationtests/src/main/java/org/apache/qpid/interop/old/Listener.java
+++ /dev/null
@@ -1,291 +0,0 @@
-/*
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- *
- */
-package org.apache.qpid.interop.old;
-
-import java.util.Random;
-
-import javax.jms.*;
-
-import org.apache.log4j.Logger;
-import org.apache.log4j.NDC;
-
-import org.apache.qpid.AMQException;
-import org.apache.qpid.client.AMQConnection;
-import org.apache.qpid.client.AMQQueue;
-import org.apache.qpid.client.AMQSession;
-import org.apache.qpid.client.AMQTopic;
-import org.apache.qpid.exchange.ExchangeDefaults;
-import org.apache.qpid.url.URLSyntaxException;
-
-/**
- * Listener implements the listening end of the Qpid interop tests. It is capable of being run as a standalone listener
- * that responds to the test messages send by the publishing end of the tests implemented by {@link org.apache.qpid.interop.old.Publisher}.
- *
- * <p/><table id="crc"><caption>CRC Card</caption>
- * <tr><th> Responsibilities <th> Collaborations
- * <tr><td> Count messages received on a topic. <td> {@link org.apache.qpid.interop.old.Publisher}
- * <tr><td> Send reports on messages received, when requested to. <td> {@link org.apache.qpid.interop.old.Publisher}
- * <tr><td> Shutdown, when requested to. <td> {@link org.apache.qpid.interop.old.Publisher}
- * <tr><td>
- *
- * @todo This doesn't implement the interop test spec yet. Its a port of the old topic tests but has been adapted with
- * interop spec in mind.
- *
- * @todo I've added lots of field table types in the report message, just to check if the other end can decode them
- * correctly. Not really the right place to test this, so remove them from {@link #sendReport()} once a better
- * test exists.
- */
-public class Listener implements MessageListener
-{
- private static Logger log = Logger.getLogger(Listener.class);
-
- /** The default AMQ connection URL to use for tests. */
- public static final String DEFAULT_URI = "amqp://guest:guest@default/test?brokerlist='tcp://localhost:5672'";
-
- /** Holds the name of (routing key for) the topic to receive test messages on. */
- public static final String CONTROL_TOPIC = "topic_control";
-
- /** Holds the name of (routing key for) the queue to send reports to. */
- public static final String RESPONSE_QUEUE = "response";
-
- /** Holds the JMS Topic to receive test messages on. */
- private final Topic _topic;
-
- /** Holds the JMS Queue to send reports to. */
- private final Queue _response;
-
- /** Holds the connection to listen on. */
- private final Connection _connection;
-
- /** Holds the producer to send control messages on. */
- private final MessageProducer _controller;
-
- /** Holds the JMS session. */
- private final javax.jms.Session _session;
-
- /** Holds a flag to indicate that a timer has begun on the first message. Reset when report is sent. */
- private boolean init;
-
- /** Holds the count of messages received by this listener. */
- private int count;
-
- /** Used to hold the start time of the first message. */
- private long start;
-
- /**
- * Creates a topic listener using the specified broker URL.
- *
- * @param connectionUrl The broker URL to listen on.
- *
- * @throws AMQException If the broker connection cannot be established.
- * @throws URLSyntaxException If the broker URL syntax is not correct.
- * @throws JMSException Any underlying JMSException is allowed to fall through.
- */
- Listener(String connectionUrl) throws AMQException, JMSException, URLSyntaxException
- {
- log.debug("Listener(String connectionUrl = " + connectionUrl + "): called");
-
- // Create a connection to the broker.
- _connection = new AMQConnection(connectionUrl);
-
- // Establish a session on the broker.
- _session = _connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
-
- // Set up the destinations to listen for test and control messages on.
- _topic = _session.createTopic(CONTROL_TOPIC);
- _response = _session.createQueue(RESPONSE_QUEUE);
-
- // Set this listener up to listen for incoming messages on the test topic.
- _session.createConsumer(_topic).setMessageListener(this);
-
- // Set up this listener with a producer to send the reports on.
- _controller = _session.createProducer(_response);
-
- _connection.start();
- System.out.println("Waiting for messages...");
- }
-
- /**
- * Starts a test subscriber. The broker URL must be specified as the first command line argument.
- *
- * @param argv The command line arguments, ignored.
- *
- * @todo Add command line arguments to configure all aspects of the test.
- */
- public static void main(String[] argv)
- {
- try
- {
- new Listener(DEFAULT_URI);
- }
- catch (Exception e)
- {
- e.printStackTrace();
- }
- }
-
- /**
- * Handles all message received by this listener. Test messages are counted, report messages result in a report being sent and
- * shutdown messages result in this listener being terminated.
- *
- * @param message The received message.
- */
- public void onMessage(Message message)
- {
- log.debug("public void onMessage(Message message = " + message + "): called");
-
- // Take the start time of the first message if this is the first message.
- if (!init)
- {
- start = System.nanoTime() / 1000000;
- count = 0;
- init = true;
- }
-
- try
- {
- // Check if the message is a control message telling this listener to shut down.
- if (isShutdown(message))
- {
- log.debug("Got a shutdown message.");
- shutdown();
- }
- // Check if the message is a report request message asking this listener to respond with the message count.
- else if (isReport(message))
- {
- log.debug("Got a report request message.");
-
- // Send the message count report.
- sendReport();
-
- // Reset the initialization flag so that the next message is considered to be the first.
- init = false;
- }
- // Otherwise it is an ordinary test message, so increment the message count.
- else
- {
- count++;
- }
- }
- catch (JMSException e)
- {
- log.warn("There was a JMSException during onMessage.", e);
- }
- }
-
- /**
- * Checks a message to see if it is a termination request control message.
- *
- * @param m The message to check.
- *
- * @return <tt>true</tt> if it is a termination request control message, <tt>false</tt> otherwise.
- *
- * @throws JMSException Any underlying JMSException is allowed to fall through.
- */
- boolean isShutdown(Message m) throws JMSException
- {
- boolean result = checkTextField(m, "TYPE", "TERMINATION_REQUEST");
-
- return result;
- }
-
- /**
- * Checks a message to see if it is a report request control message.
- *
- * @param m The message to check.
- *
- * @return <tt>true</tt> if it is a report request control message, <tt>false</tt> otherwise.
- *
- * @throws JMSException Any underlying JMSException is allowed to fall through.
- */
- boolean isReport(Message m) throws JMSException
- {
- boolean result = checkTextField(m, "TYPE", "REPORT_REQUEST");
-
- return result;
- }
-
- /**
- * Checks whether or not a text field on a message has the specified value.
- *
- * @param m The message to check.
- * @param fieldName The name of the field to check.
- * @param value The expected value of the field to compare with.
- *
- * @return <tt>true</tt>If the specified field has the specified value, <tt>fals</tt> otherwise.
- *
- * @throws JMSException Any JMSExceptions are allowed to fall through.
- */
- private static boolean checkTextField(Message m, String fieldName, String value) throws JMSException
- {
- //log.debug("private static boolean checkTextField(Message m = " + m + ", String fieldName = " + fieldName
- // + ", String value = " + value + "): called");
-
- String comp = m.getStringProperty(fieldName);
- //log.debug("comp = " + comp);
-
- boolean result = (comp != null) && comp.equals(value);
- //log.debug("result = " + result);
-
- return result;
- }
-
- /**
- * Closes down the connection to the broker.
- *
- * @throws JMSException Any underlying JMSException is allowed to fall through.
- */
- private void shutdown() throws JMSException
- {
- _session.close();
- _connection.stop();
- _connection.close();
- }
-
- /**
- * Send the report message to the response queue.
- *
- * @throws JMSException Any underlying JMSException is allowed to fall through.
- */
- private void sendReport() throws JMSException
- {
- log.debug("private void report(): called");
-
- // Create the report message.
- long time = ((System.nanoTime() / 1000000) - start);
- String msg = "Received " + count + " in " + time + "ms";
- Message message = _session.createTextMessage(msg);
-
- // Shove some more field table types in the message just to see if the other end can handle it.
- message.setBooleanProperty("BOOLEAN", true);
- //message.setByteProperty("BYTE", (byte) 5);
- message.setDoubleProperty("DOUBLE", Math.PI);
- message.setFloatProperty("FLOAT", 1.0f);
- message.setIntProperty("INT", 1);
- message.setShortProperty("SHORT", (short) 1);
- message.setLongProperty("LONG", (long) 1827361278);
- message.setStringProperty("STRING", "hello");
-
- // Send the report message.
- _controller.send(message);
- log.debug("Sent report: " + msg);
- }
-}
diff --git a/java/integrationtests/src/main/java/org/apache/qpid/interop/old/Publisher.java b/java/integrationtests/src/main/java/org/apache/qpid/interop/old/Publisher.java
deleted file mode 100644
index f3a545f580..0000000000
--- a/java/integrationtests/src/main/java/org/apache/qpid/interop/old/Publisher.java
+++ /dev/null
@@ -1,244 +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.interop.old;
-
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.TimeUnit;
-
-import javax.jms.*;
-
-import org.apache.log4j.Logger;
-
-import org.apache.qpid.AMQException;
-import org.apache.qpid.client.AMQConnection;
-import org.apache.qpid.url.URLSyntaxException;
-
-/**
- * Publisher is the sending end of Qpid interop tests. It is capable of being run as a standalone publisher
- * that sends test messages to the listening end of the tests implemented by {@link org.apache.qpid.interop.old.Listener}.
- *
- * <p/><table id="crc"><caption>CRC Card</caption>
- * <tr><th> Responsibilities <th> Collaborations
- * <tr><td>
- *
- * @todo This doesn't implement the interop test spec yet. Its a port of the old topic tests but has been adapted with
- * interop spec in mind.
- *
- * @todo I've added lots of field table types in the report request message, just to check if the other end can decode
- * them correctly. Not really the right place to test this, so remove them from {@link #doTest()} once a better
- * test exists.
- */
-public class Publisher implements MessageListener
-{
- private static Logger log = Logger.getLogger(Publisher.class);
-
- /** The default AMQ connection URL to use for tests. */
- public static final String DEFAULT_URI = "amqp://guest:guest@default/test?brokerlist='tcp://localhost:5672'";
-
- /** Holds the default test timeout for broker communications before tests give up. */
- public static final int TIMEOUT = 3000;
-
- /** Holds the routing key for the topic to send test messages on. */
- public static final String CONTROL_TOPIC = "topic_control";
-
- /** Holds the routing key for the queue to receive reports on. */
- public static final String RESPONSE_QUEUE = "response";
-
- /** Holds the JMS Topic to send test messages on. */
- private final Topic _topic;
-
- /** Holds the JMS Queue to receive reports on. */
- private final Queue _response;
-
- /** Holds the number of messages to send in each test run. */
- private int numMessages;
-
- /** A monitor used to wait for all reports to arrive back from consumers on. */
- private CountDownLatch allReportsReceivedEvt;
-
- /** Holds the connection to listen on. */
- private Connection _connection;
-
- /** Holds the channel for all test messages.*/
- private Session _session;
-
- /** Holds the producer to send test messages on. */
- private MessageProducer publisher;
-
- /**
- * Creates a topic publisher that will send the specifed number of messages and expect the specifed number of report back from test
- * subscribers.
- *
- * @param connectionUri The broker URL.
- * @param numMessages The number of messages to send in each test.
- * @param numSubscribers The number of subscribes that are expected to reply with a report.
- */
- Publisher(String connectionUri, int numMessages, int numSubscribers)
- throws AMQException, JMSException, URLSyntaxException
- {
- log.debug("Publisher(String connectionUri = " + connectionUri + ", int numMessages = " + numMessages
- + ", int numSubscribers = " + numSubscribers + "): called");
-
- // Create a connection to the broker.
- _connection = new AMQConnection(connectionUri);
-
- // Establish a session on the broker.
- _session = _connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
-
- // Set up the destinations to send test messages and listen for reports on.
- _topic = _session.createTopic(CONTROL_TOPIC);
- _response = _session.createQueue(RESPONSE_QUEUE);
-
- // Set this listener up to listen for reports on the response queue.
- _session.createConsumer(_response).setMessageListener(this);
-
- // Set up this listener with a producer to send the test messages and report requests on.
- publisher = _session.createProducer(_topic);
-
- // Keep the test parameters.
- this.numMessages = numMessages;
-
- // Set up a countdown to count all subscribers sending their reports.
- allReportsReceivedEvt = new CountDownLatch(numSubscribers);
-
- _connection.start();
- System.out.println("Sending messages and waiting for reports...");
- }
-
- /**
- * Start a test publisher. The broker URL must be specified as the first command line argument.
- *
- * @param argv The command line arguments, ignored.
- *
- * @todo Add command line arguments to configure all aspects of the test.
- */
- public static void main(String[] argv)
- {
- try
- {
- // Create an instance of this publisher with the command line parameters.
- Publisher publisher = new Publisher(DEFAULT_URI, 1, 1);
-
- // Publish the test messages.
- publisher.doTest();
- }
- catch (Exception e)
- {
- e.printStackTrace();
- }
- }
-
- /**
- * Sends the test messages and waits for all subscribers to reply with a report.
- *
- * @throws JMSException Any underlying JMSException is allowed to fall through.
- */
- public void doTest() throws JMSException
- {
- log.debug("public void DoTest(): called");
-
- // Create a test message to send.
- Message testMessage = _session.createTextMessage("test");
-
- // Send the desired number of test messages.
- for (int i = 0; i < numMessages; i++)
- {
- publisher.send(testMessage);
- }
-
- log.debug("Sent " + numMessages + " test messages.");
-
- // Send the report request.
- Message reportRequestMessage = _session.createTextMessage("Report request message.");
- reportRequestMessage.setStringProperty("TYPE", "REPORT_REQUEST");
-
- reportRequestMessage.setBooleanProperty("BOOLEAN", false);
- //reportRequestMessage.Headers.SetByte("BYTE", 5);
- reportRequestMessage.setDoubleProperty("DOUBLE", 3.141);
- reportRequestMessage.setFloatProperty("FLOAT", 1.0f);
- reportRequestMessage.setIntProperty("INT", 1);
- reportRequestMessage.setLongProperty("LONG", 1);
- reportRequestMessage.setStringProperty("STRING", "hello");
- reportRequestMessage.setShortProperty("SHORT", (short) 2);
-
- publisher.send(reportRequestMessage);
-
- log.debug("Sent the report request message, waiting for all replies...");
-
- // Wait until all the reports come in.
- try
- {
- allReportsReceivedEvt.await(TIMEOUT, TimeUnit.MILLISECONDS);
- }
- catch (InterruptedException e)
- { }
-
- // Check if all reports were really received or if the timeout occurred.
- if (allReportsReceivedEvt.getCount() == 0)
- {
- log.debug("Got all reports.");
- }
- else
- {
- log.debug("Waiting for reports timed out, still waiting for " + allReportsReceivedEvt.getCount() + ".");
- }
-
- // Send the termination request.
- Message terminationRequestMessage = _session.createTextMessage("Termination request message.");
- terminationRequestMessage.setStringProperty("TYPE", "TERMINATION_REQUEST");
- publisher.send(terminationRequestMessage);
-
- log.debug("Sent the termination request message.");
-
- // Close all message producers and consumers and the connection to the broker.
- shutdown();
- }
-
- /**
- * Handles all report messages from subscribers. This decrements the count of subscribers that are still to reply, until this becomes
- * zero, at which time waiting threads are notified of this event.
- *
- * @param message The received report message.
- */
- public void onMessage(Message message)
- {
- log.debug("public void OnMessage(Message message = " + message + "): called");
-
- // Decrement the count of expected messages and release the wait monitor when this becomes zero.
- allReportsReceivedEvt.countDown();
-
- if (allReportsReceivedEvt.getCount() == 0)
- {
- log.debug("Got reports from all subscribers.");
- }
- }
-
- /**
- * Stops the message consumers and closes the connection.
- *
- * @throws JMSException Any underlying JMSException is allowed to fall through.
- */
- private void shutdown() throws JMSException
- {
- _session.close();
- _connection.close();
- }
-}
diff --git a/java/integrationtests/src/main/java/org/apache/qpid/interop/testcases/CircuitTestCase.java b/java/integrationtests/src/main/java/org/apache/qpid/interop/testcases/CircuitTestCase.java
new file mode 100644
index 0000000000..966a545e16
--- /dev/null
+++ b/java/integrationtests/src/main/java/org/apache/qpid/interop/testcases/CircuitTestCase.java
@@ -0,0 +1,101 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT 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.interop.testcases;
+
+import org.apache.log4j.Logger;
+
+import org.apache.qpid.test.framework.sequencers.TestCaseSequencer;
+import org.apache.qpid.test.framework.Circuit;
+import org.apache.qpid.test.framework.FrameworkBaseCase;
+import org.apache.qpid.test.framework.MessagingTestConfigProperties;
+
+import uk.co.thebadgerset.junit.extensions.util.ParsedProperties;
+import uk.co.thebadgerset.junit.extensions.util.TestContextProperties;
+
+/**
+ * CircuitTestCase runs a test over a {@link Circuit} controlled by the test parameters.
+ *
+ * <p/><table id="crc"><caption>CRC Card</caption>
+ * <tr><th> Responsibilities <th> Collaborations
+ * <tr><td>
+ * </table>
+ *
+ * @todo When working with test context properties, add overrides to defaults to the singleton instance, but when taking
+ * a starting point to add specific test case parameters to, take a copy. Use the copy with test case specifics
+ * to control the test.
+ */
+public class CircuitTestCase extends FrameworkBaseCase
+{
+ /** Used for debugging. */
+ private static final Logger log = Logger.getLogger(CircuitTestCase.class);
+
+ /**
+ * Creates a new test case with the specified name.
+ *
+ * @param name The test case name.
+ */
+ public CircuitTestCase(String name)
+ {
+ super(name);
+ }
+
+ /**
+ * Performs the a basic P2P test case.
+ *
+ * @throws Exception Any exceptions are allowed to fall through and fail the test.
+ */
+ public void testBasicP2P() throws Exception
+ {
+ log.debug("public void testBasicP2P(): called");
+
+ // Get the test parameters, any overrides on the command line will have been applied.
+ ParsedProperties testProps = TestContextProperties.getInstance(MessagingTestConfigProperties.defaults);
+
+ // Customize the test parameters.
+ testProps.setProperty("TEST_NAME", "DEFAULT_CIRCUIT_TEST");
+ testProps.setProperty(MessagingTestConfigProperties.SEND_DESTINATION_NAME_ROOT_PROPNAME, "testqueue");
+
+ // Get the test sequencer to create test circuits and run the standard test procedure through.
+ TestCaseSequencer sequencer = getTestSequencer();
+
+ // Send the test messages, and check that there were no errors doing so.
+ Circuit testCircuit = sequencer.createCircuit(testProps);
+ sequencer.sequenceTest(testCircuit, assertionList(testCircuit.getPublisher().noExceptionsAssertion()), testProps);
+
+ // Check that all of the message were sent.
+ // Check that the receiving end got the same number of messages as the publishing end.
+ }
+
+ /**
+ * Should provide a translation from the junit method name of a test to its test case name as known to the test
+ * clients that will run the test. The purpose of this is to convert the JUnit method name into the correct test
+ * case name to place into the test invite. For example the method "testP2P" might map onto the interop test case
+ * name "TC2_BasicP2P".
+ *
+ * @param methodName The name of the JUnit test method.
+ *
+ * @return The name of the corresponding interop test case.
+ */
+ public String getTestCaseNameForTestMethod(String methodName)
+ {
+ return "DEFAULT_CIRCUIT_TEST";
+ }
+}
diff --git a/java/integrationtests/src/main/java/org/apache/qpid/interop/coordinator/testcases/CoordinatingTestCase1DummyRun.java b/java/integrationtests/src/main/java/org/apache/qpid/interop/testcases/InteropTestCase1DummyRun.java
index e642ef792b..73e08b578e 100644
--- a/java/integrationtests/src/main/java/org/apache/qpid/interop/coordinator/testcases/CoordinatingTestCase1DummyRun.java
+++ b/java/integrationtests/src/main/java/org/apache/qpid/interop/testcases/InteropTestCase1DummyRun.java
@@ -18,56 +18,55 @@
* under the License.
*
*/
-
-package org.apache.qpid.interop.coordinator.testcases;
-
-import java.util.HashMap;
-import java.util.Map;
-
-import javax.jms.Message;
-
-import junit.framework.Assert;
+package org.apache.qpid.interop.testcases;
import org.apache.log4j.Logger;
-import org.apache.qpid.interop.coordinator.CoordinatingTestCase;
+import org.apache.qpid.test.framework.distributedtesting.DistributedTestCase;
+
+import java.util.Properties;
/**
+ * Coordinates test case 1, from the interop test specification. This test connects up the sender and receivers roles,
+ * and gets some dummy test reports from them, in order to check that the test framework itself is operational.
+ *
* <p><table id="crc"><caption>CRC Card</caption>
* <tr><th> Responsibilities <th> Collaborations
* <tr><td> Exercises the interop testing framework without actually sending any test messages.
- * <td> {@link org.apache.qpid.interop.coordinator.CoordinatingTestCase}
+ * <td> {@link org.apache.qpid.test.framework.distributedtesting.DistributedTestCase}
* </table>
*/
-public class CoordinatingTestCase1DummyRun extends CoordinatingTestCase
+public class InteropTestCase1DummyRun extends DistributedTestCase
{
/** Used for debugging. */
- private static final Logger log = Logger.getLogger(CoordinatingTestCase1DummyRun.class);
+ private static final Logger log = Logger.getLogger(InteropTestCase1DummyRun.class);
/**
* Creates a new coordinating test case with the specified name.
*
* @param name The test case name.
*/
- public CoordinatingTestCase1DummyRun(String name)
+ public InteropTestCase1DummyRun(String name)
{
super(name);
}
/**
* Performs the basic P2P test case, "Test Case 2" in the specification.
+ *
+ * @throws Exception Any exceptions are allowed to fall through and fail the test.
*/
public void testDummyRun() throws Exception
{
log.debug("public void testDummyRun(): called");
- Map<String, Object> testConfig = new HashMap<String, Object>();
+ Properties testConfig = new Properties();
testConfig.put("TEST_NAME", "TC1_DummyRun");
- Message[] reports = sequenceTest(testConfig);
+ /*Message[] reports =*/ getTestSequencer().sequenceTest(null, null, testConfig);
- // Compare sender and receiver reports.
- Assert.assertEquals("Expected to get 2 dummy reports.", 2, reports.length);
+ // Compare sender and receivers reports.
+ // Assert.assertEquals("Expected to get 2 dummy reports.", 2, reports.length);
}
/**
diff --git a/java/integrationtests/src/main/java/org/apache/qpid/interop/coordinator/testcases/CoordinatingTestCase2BasicP2P.java b/java/integrationtests/src/main/java/org/apache/qpid/interop/testcases/InteropTestCase2BasicP2P.java
index b1b2d9f847..f77bbf032f 100644
--- a/java/integrationtests/src/main/java/org/apache/qpid/interop/coordinator/testcases/CoordinatingTestCase2BasicP2P.java
+++ b/java/integrationtests/src/main/java/org/apache/qpid/interop/testcases/InteropTestCase2BasicP2P.java
@@ -18,61 +18,61 @@
* under the License.
*
*/
-
-package org.apache.qpid.interop.coordinator.testcases;
-
-import java.util.HashMap;
-import java.util.Map;
-
-import javax.jms.Message;
-
-import junit.framework.Assert;
+package org.apache.qpid.interop.testcases;
import org.apache.log4j.Logger;
-import org.apache.qpid.interop.coordinator.CoordinatingTestCase;
+import org.apache.qpid.test.framework.distributedtesting.DistributedTestCase;
+
+import java.util.Properties;
/**
+ * Implements test case 2, from the interop test specification. This test sets up the TC2_BasicP2P test for 50
+ * messages. It checks that the sender and receivers reports both indicate that all the test messages were transmitted
+ * successfully.
+ *
* <p><table id="crc"><caption>CRC Card</caption>
* <tr><th> Responsibilities <th> Collaborations
- * <tr><td> Setup p2p test parameters and compare with test output. <td> {@link CoordinatingTestCase}
+ * <tr><td> Setup p2p test parameters and compare with test output. <td> {@link DistributedTestCase}
* </table>
*/
-public class CoordinatingTestCase2BasicP2P extends CoordinatingTestCase
+public class InteropTestCase2BasicP2P extends DistributedTestCase
{
/** Used for debugging. */
- private static final Logger log = Logger.getLogger(CoordinatingTestCase2BasicP2P.class);
+ private static final Logger log = Logger.getLogger(InteropTestCase2BasicP2P.class);
/**
* Creates a new coordinating test case with the specified name.
*
* @param name The test case name.
*/
- public CoordinatingTestCase2BasicP2P(String name)
+ public InteropTestCase2BasicP2P(String name)
{
super(name);
}
/**
* Performs the basic P2P test case, "Test Case 2" in the specification.
+ *
+ * @throws Exception Any exceptions are allowed to fall through and fail the test.
*/
public void testBasicP2P() throws Exception
{
log.debug("public void testBasicP2P(): called");
- Map<String, Object> testConfig = new HashMap<String, Object>();
- testConfig.put("TEST_NAME", "TC2_BasicP2P");
- testConfig.put("P2P_QUEUE_AND_KEY_NAME", "tc2queue");
+ Properties testConfig = new Properties();
+ testConfig.setProperty("TEST_NAME", "TC2_BasicP2P");
+ testConfig.setProperty("P2P_QUEUE_AND_KEY_NAME", "tc2queue");
testConfig.put("P2P_NUM_MESSAGES", 50);
- Message[] reports = sequenceTest(testConfig);
+ /*Message[] reports =*/ getTestSequencer().sequenceTest(null, null, testConfig);
- // Compare sender and receiver reports.
- int messagesSent = reports[0].getIntProperty("MESSAGE_COUNT");
+ // Compare sender and receivers reports.
+ /*int messagesSent = reports[0].getIntProperty("MESSAGE_COUNT");
int messagesReceived = reports[1].getIntProperty("MESSAGE_COUNT");
Assert.assertEquals("The requested number of messages were not sent.", 50, messagesSent);
- Assert.assertEquals("Sender and receiver messages sent did not match up.", messagesSent, messagesReceived);
+ Assert.assertEquals("Sender and receivers messages sent did not match up.", messagesSent, messagesReceived);*/
}
/**
diff --git a/java/integrationtests/src/main/java/org/apache/qpid/interop/coordinator/testcases/CoordinatingTestCase3BasicPubSub.java b/java/integrationtests/src/main/java/org/apache/qpid/interop/testcases/InteropTestCase3BasicPubSub.java
index 702c240e9a..ad27ca63bd 100644
--- a/java/integrationtests/src/main/java/org/apache/qpid/interop/coordinator/testcases/CoordinatingTestCase3BasicPubSub.java
+++ b/java/integrationtests/src/main/java/org/apache/qpid/interop/testcases/InteropTestCase3BasicPubSub.java
@@ -18,63 +18,59 @@
* under the License.
*
*/
-
-package org.apache.qpid.interop.coordinator.testcases;
-
-import java.util.HashMap;
-import java.util.Map;
-
-import javax.jms.Message;
-
-import junit.framework.Assert;
+package org.apache.qpid.interop.testcases;
import org.apache.log4j.Logger;
-import org.apache.qpid.interop.coordinator.CoordinatingTestCase;
+import org.apache.qpid.test.framework.distributedtesting.DistributedTestCase;
+
+import java.util.Properties;
/**
* <p><table id="crc"><caption>CRC Card</caption>
* <tr><th> Responsibilities <th> Collaborations
- * <tr><td> Setup pub/sub test parameters and compare with test output. <td> {@link CoordinatingTestCase}
+ * <tr><td> Setup pub/sub test parameters and compare with test output. <td> {@link DistributedTestCase}
* </table>
*/
-public class CoordinatingTestCase3BasicPubSub extends CoordinatingTestCase
+public class InteropTestCase3BasicPubSub extends DistributedTestCase
{
/** Used for debugging. */
- private static final Logger log = Logger.getLogger(CoordinatingTestCase3BasicPubSub.class);
+ private static final Logger log = Logger.getLogger(InteropTestCase3BasicPubSub.class);
/**
* Creates a new coordinating test case with the specified name.
*
* @param name The test case name.
*/
- public CoordinatingTestCase3BasicPubSub(String name)
+ public InteropTestCase3BasicPubSub(String name)
{
super(name);
}
/**
* Performs the basic P2P test case, "Test Case 2" in the specification.
+ *
+ * @throws Exception Any exceptions are allowed to fall through and fail the test.
*/
public void testBasicPubSub() throws Exception
{
log.debug("public void testBasicPubSub(): called");
- Map<String, Object> testConfig = new HashMap<String, Object>();
+ Properties testConfig = new Properties();
testConfig.put("TEST_NAME", "TC3_BasicPubSub");
testConfig.put("PUBSUB_KEY", "tc3route");
testConfig.put("PUBSUB_NUM_MESSAGES", 10);
testConfig.put("PUBSUB_NUM_RECEIVERS", 5);
- Message[] reports = sequenceTest(testConfig);
+ /*Message[] reports =*/ getTestSequencer().sequenceTest(null, null, testConfig);
- // Compare sender and receiver reports.
- int messagesSent = reports[0].getIntProperty("MESSAGE_COUNT");
+ // Compare sender and receivers reports.
+ /*int messagesSent = reports[0].getIntProperty("MESSAGE_COUNT");
int messagesReceived = reports[1].getIntProperty("MESSAGE_COUNT");
Assert.assertEquals("The requested number of messages were not sent.", 10, messagesSent);
Assert.assertEquals("Received messages did not match up to num sent * num receivers.", messagesSent * 5,
- messagesReceived);
+ messagesReceived);*/
}
/**
diff --git a/java/integrationtests/src/main/java/org/apache/qpid/sustained/SustainedClientTestCase.java b/java/integrationtests/src/main/java/org/apache/qpid/sustained/SustainedClientTestCase.java
new file mode 100644
index 0000000000..65e05fab4b
--- /dev/null
+++ b/java/integrationtests/src/main/java/org/apache/qpid/sustained/SustainedClientTestCase.java
@@ -0,0 +1,905 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT 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.sustained;
+
+import org.apache.log4j.Logger;
+
+import org.apache.qpid.client.AMQNoConsumersException;
+import org.apache.qpid.client.AMQNoRouteException;
+import org.apache.qpid.test.framework.distributedtesting.TestClient;
+import org.apache.qpid.interop.clienttestcases.TestCase3BasicPubSub;
+import org.apache.qpid.test.framework.TestUtils;
+
+import javax.jms.Connection;
+import javax.jms.Destination;
+import javax.jms.ExceptionListener;
+import javax.jms.JMSException;
+import javax.jms.Message;
+import javax.jms.MessageConsumer;
+import javax.jms.MessageListener;
+import javax.jms.MessageProducer;
+import javax.jms.Session;
+import javax.jms.TextMessage;
+
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.concurrent.CountDownLatch;
+
+/**
+ * Implements test case 3, basic pub/sub. Sends/received a specified number of messages to a specified route on the
+ * default topic exchange, using the specified number of receivers connections. Produces reports on the actual number of
+ * messages sent/received.
+ *
+ * <p><table id="crc"><caption>CRC Card</caption>
+ * <tr><th> Responsibilities <th> Collaborations
+ * <tr><td> Supply the name of the test case that this implements.
+ * <tr><td> Accept/Reject invites based on test parameters.
+ * <tr><td> Adapt to assigned roles.
+ * <tr><td> Send required number of test messages using pub/sub. <tr><td> Generate test reports.
+ * </table>
+ */
+public class SustainedClientTestCase extends TestCase3BasicPubSub implements ExceptionListener
+{
+ /** Used for debugging. */
+ private static final Logger log = Logger.getLogger(SustainedClientTestCase.class);
+
+ /** Used to log to the console. */
+ private static final Logger console = Logger.getLogger("SustainedTest");
+
+ /** The role to be played by the test. */
+ private Roles role;
+
+ /** The number of receivers connection to use. */
+ private int numReceivers;
+
+ /** The routing key to send them to on the default direct exchange. */
+ private Destination sendDestination;
+
+ /** The routing key to send updates to on the default direct exchange. */
+ private Destination sendUpdateDestination;
+
+ /** The connections to send/receive the test messages on. */
+ private Connection[] connection;
+
+ /** The sessions to send/receive the test messages on. */
+ private Session[] session;
+
+ /** The producer to send the test messages with. */
+ MessageProducer producer;
+
+ /** Adapter that adjusts the send rate based on the updates from clients. */
+ SustainedRateAdapter _rateAdapter;
+
+ /** */
+ int _batchSize;
+
+ private static final long TEN_MILLI_SEC = 10000000;
+ private static final int DEBUG_LOG_UPATE_INTERVAL = 10;
+ private static final int LOG_UPATE_INTERVAL = 10;
+ private static final boolean SLEEP_PER_MESSAGE = Boolean.getBoolean("sleepPerMessage");
+
+ /**
+ * Should provide the name of the test case that this class implements. The exact names are defined in the interop
+ * testing spec.
+ *
+ * @return The name of the test case that this implements.
+ */
+ public String getName()
+ {
+ log.debug("public String getName(): called");
+
+ return "Perf_SustainedPubSub";
+ }
+
+ /**
+ * Assigns the role to be played by this test case. The test parameters are fully specified in the assignment
+ * message. When this method return the test case will be ready to execute.
+ *
+ * @param role The role to be played; sender or receivers.
+ * @param assignRoleMessage The role assingment message, contains the full test parameters.
+ *
+ * @throws JMSException Any JMSException resulting from reading the message are allowed to fall through.
+ */
+ public void assignRole(Roles role, Message assignRoleMessage) throws JMSException
+ {
+ log.debug("public void assignRole(Roles role = " + role + ", Message assignRoleMessage = " + assignRoleMessage
+ + "): called");
+
+ // Take note of the role to be played.
+ this.role = role;
+
+ // Extract and retain the test parameters.
+ numReceivers = assignRoleMessage.getIntProperty("SUSTAINED_NUM_RECEIVERS");
+ _batchSize = assignRoleMessage.getIntProperty("SUSTAINED_UPDATE_INTERVAL");
+ String sendKey = assignRoleMessage.getStringProperty("SUSTAINED_KEY");
+ String sendUpdateKey = assignRoleMessage.getStringProperty("SUSTAINED_UPDATE_KEY");
+ int ackMode = assignRoleMessage.getIntProperty("ACKNOWLEDGE_MODE");
+ String clientName = assignRoleMessage.getStringProperty("CLIENT_NAME");
+
+ if (log.isDebugEnabled())
+ {
+ log.debug("numReceivers = " + numReceivers);
+ log.debug("_batchSize = " + _batchSize);
+ log.debug("ackMode = " + ackMode);
+ log.debug("sendKey = " + sendKey);
+ log.debug("sendUpdateKey = " + sendUpdateKey);
+ log.debug("role = " + role);
+ }
+
+ switch (role)
+ {
+ // Check if the sender role is being assigned, and set up a single message producer if so.
+ case SENDER:
+ console.info("Creating Sender");
+ // Create a new connection to pass the test messages on.
+ connection = new Connection[1];
+ session = new Session[1];
+
+ connection[0] = TestUtils.createConnection(TestClient.testContextProperties);
+ session[0] = connection[0].createSession(false, ackMode);
+
+ // Extract and retain the test parameters.
+ sendDestination = session[0].createTopic(sendKey);
+
+ connection[0].setExceptionListener(this);
+
+ producer = session[0].createProducer(sendDestination);
+
+ sendUpdateDestination = session[0].createTopic(sendUpdateKey);
+ MessageConsumer updateConsumer = session[0].createConsumer(sendUpdateDestination);
+
+ _rateAdapter = new SustainedRateAdapter(this);
+ updateConsumer.setMessageListener(_rateAdapter);
+
+ break;
+
+ // Otherwise the receivers role is being assigned, so set this up to listen for messages on the required number
+ // of receivers connections.
+ case RECEIVER:
+ console.info("Creating Receiver");
+ // Create the required number of receivers connections.
+ connection = new Connection[numReceivers];
+ session = new Session[numReceivers];
+
+ for (int i = 0; i < numReceivers; i++)
+ {
+ connection[i] = TestUtils.createConnection(TestClient.testContextProperties);
+ session[i] = connection[i].createSession(false, ackMode);
+
+ sendDestination = session[i].createTopic(sendKey);
+
+ sendUpdateDestination = session[i].createTopic(sendUpdateKey);
+
+ MessageConsumer consumer = session[i].createConsumer(sendDestination);
+
+ consumer.setMessageListener(new SustainedListener(clientName + "-" + i, _batchSize, session[i],
+ sendUpdateDestination));
+ }
+
+ break;
+ }
+
+ // Start all the connection dispatcher threads running.
+ for (int i = 0; i < connection.length; i++)
+ {
+ connection[i].start();
+ }
+ }
+
+ /** Performs the test case actions. */
+ public void start() throws JMSException
+ {
+ log.debug("public void start(): called");
+
+ // Check that the sender role is being performed.
+ switch (role)
+ {
+ // Check if the sender role is being assigned, and set up a single message producer if so.
+ case SENDER:
+ _rateAdapter.run();
+ break;
+ case RECEIVER:
+
+ }
+
+ // return from here when you have finished the test.. this will signal the controller and
+ }
+
+ public void terminate() throws JMSException, InterruptedException
+ {
+ if (_rateAdapter != null)
+ {
+ _rateAdapter.stop();
+ }
+ }
+
+ /**
+ * Gets a report on the actions performed by the test case in its assigned role.
+ *
+ * @param session The session to create the report message in.
+ *
+ * @return The report message.
+ *
+ * @throws JMSException Any JMSExceptions resulting from creating the report are allowed to fall through.
+ */
+ public Message getReport(Session session) throws JMSException
+ {
+ log.debug("public Message getReport(Session session): called");
+
+ // Close the test connections.
+ for (int i = 0; i < connection.length; i++)
+ {
+ connection[i].close();
+ }
+
+ Message report = session.createMessage();
+ report.setStringProperty("CONTROL_TYPE", "REPORT");
+
+ return report;
+ }
+
+ public void onException(JMSException jmsException)
+ {
+ Exception linked = jmsException.getLinkedException();
+
+ if (linked != null)
+ {
+ if (log.isDebugEnabled())
+ {
+ log.debug("Linked Exception:" + linked);
+ }
+
+ if ((linked instanceof AMQNoRouteException) || (linked instanceof AMQNoConsumersException))
+ {
+ if (log.isDebugEnabled())
+ {
+ if (linked instanceof AMQNoConsumersException)
+ {
+ log.warn("No clients currently available for message:"
+ + ((AMQNoConsumersException) linked).getUndeliveredMessage());
+ }
+ else
+ {
+ log.warn("No route for message");
+ }
+ }
+
+ // Tell the rate adapter that there are no clients ready yet
+ _rateAdapter.NO_CLIENTS = true;
+ }
+ }
+ else
+ {
+ log.warn("Exception:" + linked);
+ }
+ }
+
+ /**
+ * Inner class that listens for messages and sends a report for the time taken between receiving the 'start' and
+ * 'end' messages.
+ */
+ class SustainedListener implements MessageListener
+ {
+ /** Number of messages received */
+ private long _received = 0;
+ /** The number of messages in the batch */
+ private int _batchSize = 0;
+ /** Record of the when the 'start' messagse was sen */
+ private Long _startTime;
+ /** Message producer to use to send reports */
+ MessageProducer _updater;
+ /** Session to create the report message on */
+ Session _session;
+ /** Record of the client ID used for this SustainedListnener */
+ String _client;
+
+ /**
+ * Main Constructor
+ *
+ * @param clientname The _client id used to identify this connection.
+ * @param batchSize The number of messages that are to be sent per batch. Note: This is not used to
+ * control the interval between sending reports.
+ * @param session The session used for communication.
+ * @param sendDestination The destination that update reports should be sent to.
+ *
+ * @throws JMSException My occur if creatingthe Producer fails
+ */
+ public SustainedListener(String clientname, int batchSize, Session session, Destination sendDestination)
+ throws JMSException
+ {
+ _batchSize = batchSize;
+ _client = clientname;
+ _session = session;
+ _updater = session.createProducer(sendDestination);
+ }
+
+ public void onMessage(Message message)
+ {
+ if (log.isTraceEnabled())
+ {
+ log.trace("Message " + _received + "received in listener");
+ }
+
+ if (message instanceof TextMessage)
+ {
+ try
+ {
+ _received++;
+ if (((TextMessage) message).getText().equals("start"))
+ {
+ log.debug("Starting Batch");
+ _startTime = System.nanoTime();
+ }
+ else if (((TextMessage) message).getText().equals("end"))
+ {
+ if (_startTime != null)
+ {
+ long currentTime = System.nanoTime();
+ sendStatus(currentTime - _startTime, _received, message.getIntProperty("BATCH"));
+ log.debug("End Batch");
+ }
+ }
+ }
+ catch (JMSException e)
+ {
+ // ignore error
+ }
+ }
+
+ }
+
+ /**
+ * sendStatus creates and sends the report back to the publisher
+ *
+ * @param time taken for the the last batch
+ * @param received Total number of messages received.
+ * @param batchNumber the batch number
+ * @throws JMSException if an error occurs during the send
+ */
+ private void sendStatus(long time, long received, int batchNumber) throws JMSException
+ {
+ Message updateMessage = _session.createTextMessage("update");
+ updateMessage.setStringProperty("CLIENT_ID", ":" + _client);
+ updateMessage.setStringProperty("CONTROL_TYPE", "UPDATE");
+ updateMessage.setLongProperty("RECEIVED", received);
+ updateMessage.setIntProperty("BATCH", batchNumber);
+ updateMessage.setLongProperty("DURATION", time);
+
+ if (log.isInfoEnabled())
+ {
+ log.info("**** SENDING [" + batchNumber + "]**** " + "CLIENT_ID:" + _client + " RECEIVED:" + received
+ + " BATCH:" + batchNumber + " DURATION:" + time);
+ }
+
+ // Output on the main console.info the details of this batch
+ if ((batchNumber % 10) == 0)
+ {
+ console.info("Sending Report [" + batchNumber + "] " + "CLIENT_ID:" + _client + " RECEIVED:" + received
+ + " BATCH:" + batchNumber + " DURATION:" + time);
+ }
+
+ _updater.send(updateMessage);
+ }
+ }
+
+ /**
+ * This class is used here to adjust the _delay value which in turn is used to control the number of messages/second
+ * that are sent through the test system.
+ *
+ * By keeping a record of the messages recevied and the average time taken to process the batch size can be
+ * calculated and so the delay can be adjusted to maintain that rate.
+ *
+ * Given that delays of < 10ms can be rounded up the delay is only used between messages if the _delay > 10ms * no
+ * messages in the batch. Otherwise the delay is used at the end of the batch.
+ */
+ class SustainedRateAdapter implements MessageListener, Runnable
+ {
+ private SustainedClientTestCase _client;
+ private long _batchVariance = Integer.getInteger("batchVariance", 3); // no. batches to allow drifting
+ private long _timeVariance = TEN_MILLI_SEC * 5; // no. nanos between send and report delay (10ms)
+ private volatile long _delay; // in nanos
+ private long _sent;
+ private Map<String, Long> _slowClients = new HashMap<String, Long>();
+ private static final long PAUSE_SLEEP = TEN_MILLI_SEC / 1000; // 10 ms
+ private static final long NO_CLIENT_SLEEP = 1000; // 1s
+ private volatile boolean NO_CLIENTS = true;
+ private int _delayShifting;
+ private final int REPORTS_WITHOUT_CHANGE = Integer.getInteger("stableReportCount", 5);
+ private boolean _warmedup = false;
+ private static final long EXPECTED_TIME_PER_BATCH = 100000L;
+ private int _warmUpBatches = Integer.getInteger("warmUpBatches", 10);
+
+ SustainedRateAdapter(SustainedClientTestCase client)
+ {
+ _client = client;
+ }
+
+ public void onMessage(Message message)
+ {
+ if (log.isDebugEnabled())
+ {
+ log.debug("SustainedRateAdapter onMessage(Message message = " + message + "): called");
+ }
+
+ try
+ {
+ String controlType = message.getStringProperty("CONTROL_TYPE");
+
+ // Check if the message is a test invite.
+ if ("UPDATE".equals(controlType))
+ {
+ NO_CLIENTS = false;
+ long duration = message.getLongProperty("DURATION");
+ long totalReceived = message.getLongProperty("RECEIVED");
+ String client = message.getStringProperty("CLIENT_ID");
+ int batchNumber = message.getIntProperty("BATCH");
+
+ if (log.isInfoEnabled() && ((batchNumber % DEBUG_LOG_UPATE_INTERVAL) == 0))
+ {
+ log.info("Update Report: CLIENT_ID:" + client + " RECEIVED:" + totalReceived + " Recevied BATCH:"
+ + batchNumber + " DURATION:" + duration);
+ }
+
+ recordSlow(client, totalReceived, batchNumber);
+
+ adjustDelay(client, batchNumber, duration);
+
+ // Warm up completes when:
+ // we haven't warmed up
+ // and the number of batches sent to each client is at least half of the required warmup batches
+ if (!_warmedup && (batchNumber >= _warmUpBatches))
+ {
+ _warmedup = true;
+ _warmup.countDown();
+
+ }
+ }
+ }
+ catch (JMSException e)
+ {
+ //
+ }
+ }
+
+ CountDownLatch _warmup = new CountDownLatch(1);
+
+ int _numBatches = 10000;
+
+ // long[] _timings = new long[_numBatches];
+ private boolean _running = true;
+
+ public void run()
+ {
+ console.info("Warming up");
+
+ doBatch(_warmUpBatches);
+
+ try
+ {
+ // wait for warmup to complete.
+ _warmup.await();
+
+ // set delay to the average length of the batches
+ _delay = _totalDuration / _warmUpBatches / delays.size();
+
+ console.info("Warmup complete delay set : " + _delay + " based on _totalDuration: " + _totalDuration
+ + " over no. batches: " + _warmUpBatches + " with client count: " + delays.size());
+
+ _totalDuration = 0L;
+ _totalReceived = 0L;
+ _sent = 0L;
+ }
+ catch (InterruptedException e)
+ {
+ //
+ }
+
+ doBatch(_numBatches);
+
+ }
+
+ private void doBatch(int batchSize) // long[] timings,
+ {
+ TextMessage testMessage = null;
+ try
+ {
+ testMessage = _client.session[0].createTextMessage("start");
+
+ for (int batch = 0; batch <= batchSize; batch++)
+ // while (_running)
+ {
+ long start = System.nanoTime();
+
+ testMessage.setText("start");
+ testMessage.setIntProperty("BATCH", batch);
+
+ _client.producer.send(testMessage);
+ _rateAdapter.sentMessage();
+
+ testMessage.setText("test");
+ // start at 2 so start and end count as part of batch
+ for (int m = 2; m < _batchSize; m++)
+ {
+ _client.producer.send(testMessage);
+ _rateAdapter.sentMessage();
+ }
+
+ testMessage.setText("end");
+ _client.producer.send(testMessage);
+ _rateAdapter.sentMessage();
+
+ long end = System.nanoTime();
+
+ long sendtime = end - start;
+
+ if (log.isDebugEnabled())
+ {
+ log.info("Sent batch[" + batch + "](" + _batchSize + ") in " + sendtime); // timings[batch]);
+ }
+
+ if ((batch % LOG_UPATE_INTERVAL) == 0)
+ {
+ console.info("Sent Batch[" + batch + "](" + _batchSize + ")" + status());
+ }
+
+ _rateAdapter.sleepBatch();
+
+ }
+ }
+ catch (JMSException e)
+ {
+ console.error("Runner ended");
+ }
+ }
+
+ private String status()
+ {
+ return " TotalDuration: " + _totalDuration + " for " + delays.size() + " consumers" + " Delay is " + _delay
+ + " resulting in "
+ + ((_delay > (TEN_MILLI_SEC * _batchSize)) ? ((_delay / _batchSize) + "/msg") : (_delay + "/batch"));
+ }
+
+ private void sleepBatch()
+ {
+ if (checkForSlowClients())
+ { // if there werwe slow clients we have already slept so don't sleep anymore again.
+ return;
+ }
+
+ if (!SLEEP_PER_MESSAGE)
+ {
+ // per batch sleep.. if sleep is to small to spread over the batch.
+ if (_delay <= (TEN_MILLI_SEC * _batchSize))
+ {
+ sleepLong(_delay);
+ }
+ else
+ {
+ log.info("Not sleeping _delay > ten*batch is:" + _delay);
+ }
+ }
+ }
+
+ public void stop()
+ {
+ _running = false;
+ }
+
+ Map<String, Long> delays = new HashMap<String, Long>();
+ Long _totalReceived = 0L;
+ Long _totalDuration = 0L;
+ int _skipUpdate = 0;
+
+ /**
+ * Adjust the delay for sending messages based on this update from the client
+ *
+ * @param client The client that send this update
+ * @param duration The time taken for the last batch of messagse
+ * @param batchNumber The reported batchnumber from the client
+ */
+ private void adjustDelay(String client, int batchNumber, long duration)
+ {
+ // Retrieve the current total time taken for this client.
+ Long currentTime = delays.get(client);
+
+ // Add the new duration time to this client
+ if (currentTime == null)
+ {
+ currentTime = duration;
+ }
+ else
+ {
+ currentTime += duration;
+ }
+
+ delays.put(client, currentTime);
+
+ long batchesSent = _sent / _batchSize;
+
+ // ensure we don't divide by zero
+ if (batchesSent == 0)
+ {
+ batchesSent = 1L;
+ }
+
+ _totalReceived += _batchSize;
+ _totalDuration += duration;
+
+ // calculate average duration accross clients per batch
+ long averageDuration = _totalDuration / delays.size() / batchesSent;
+
+ // calculate the difference between current send delay and average report delay
+ long diff = (duration) - averageDuration;
+
+ if (log.isInfoEnabled() && ((batchNumber % DEBUG_LOG_UPATE_INTERVAL) == 0))
+ {
+ log.info("TotalDuration:" + _totalDuration + " for " + delays.size() + " consumers." + " on batch: "
+ + batchesSent + " received batch: " + batchNumber + " Batch Duration: " + duration + " Average: "
+ + averageDuration + " so diff: " + diff + " for : " + client + " Delay is " + _delay + " resulting in "
+ + ((_delay > (TEN_MILLI_SEC * _batchSize)) ? ((_delay / _batchSize) + "/msg") : (_delay + "/batch")));
+ }
+
+ // if the averageDuration differs from the current by more than the specified variane then adjust delay.
+ if (Math.abs(diff) > _timeVariance)
+ {
+
+ // if the the _delay is larger than the required duration to send report
+ // speed up
+ if (diff > TEN_MILLI_SEC)
+ {
+ _delay -= TEN_MILLI_SEC;
+
+ if (_delay < 0)
+ {
+ _delay = 0;
+ log.info("Reset _delay to 0");
+ delayStable();
+ }
+ else
+ {
+ delayChanged();
+ }
+
+ }
+ else if (diff < 0) // diff < 0 diff cannot be 0 as it is > _timeVariance
+ {
+ // the report took longer
+ _delay += TEN_MILLI_SEC;
+ delayChanged();
+ }
+ }
+ else
+ {
+ delayStable();
+ }
+
+ // If we have a consumer that is behind with the batches.
+ if ((batchesSent - batchNumber) > _batchVariance)
+ {
+ log.debug("Increasing _delay as sending more than receiving");
+
+ _delay += 2 * TEN_MILLI_SEC;
+ delayChanged();
+ }
+
+ }
+
+ /** Reset the number of iterations before we say the delay has stabilised. */
+ private void delayChanged()
+ {
+ _delayShifting = REPORTS_WITHOUT_CHANGE;
+ }
+
+ /**
+ * Record the fact that delay has stabilised If delay has stablised for REPORTS_WITHOUT_CHANGE then it will
+ * output Delay stabilised
+ */
+ private void delayStable()
+ {
+ _delayShifting--;
+
+ if (_delayShifting < 0)
+ {
+ _delayShifting = 0;
+ console.debug("Delay stabilised:" + _delay);
+ }
+ }
+
+ /**
+ * Checks that the client has received enough messages. If the client has fallen behind then they are put in the
+ * _slowClients lists which will increase the delay.
+ *
+ * @param client The client identifier to check
+ * @param received the number of messages received by that client
+ * @param batchNumber
+ */
+ private void recordSlow(String client, long received, int batchNumber)
+ {
+ if (Math.abs(batchNumber - (_sent / _batchSize)) > _batchVariance)
+ {
+ _slowClients.put(client, received);
+ }
+ else
+ {
+ _slowClients.remove(client);
+ }
+ }
+
+ /** Incrment the number of sent messages and then sleep, if required. */
+ public void sentMessage()
+ {
+
+ _sent++;
+
+ if (_delay > (TEN_MILLI_SEC * _batchSize))
+ {
+ long batchDelay = _delay / _batchSize;
+ // less than 10ms sleep doesn't always work.
+ // _delay is in nano seconds
+ // if (batchDelay < (TEN_MILLI_SEC))
+ // {
+ // sleep(0, (int) batchDelay);
+ // }
+ // else
+ {
+ // if (batchDelay < 30000000000L)
+ {
+ sleepLong(batchDelay);
+ }
+ }
+ }
+ else
+ {
+ if (SLEEP_PER_MESSAGE && (_delay > 0))
+ {
+ sleepLong(_delay / _batchSize);
+ }
+ }
+ }
+
+ /**
+ * Check at the end of each batch and pause sending messages to allow slow clients to catch up.
+ *
+ * @return true if there were slow clients that caught up.
+ */
+ private boolean checkForSlowClients()
+ {
+ // This will allways be true as we are running this at the end of each batchSize
+ // if (_sent % _batchSize == 0)
+ {
+ // Cause test to pause when we have slow
+ if (!_slowClients.isEmpty() || NO_CLIENTS)
+ {
+
+ while (!_slowClients.isEmpty())
+ {
+ if (log.isInfoEnabled() && ((_sent / _batchSize % DEBUG_LOG_UPATE_INTERVAL) == 0))
+ {
+ String clients = "";
+ Iterator it = _slowClients.keySet().iterator();
+ while (it.hasNext())
+ {
+ clients += it.next();
+ if (it.hasNext())
+ {
+ clients += ", ";
+ }
+ }
+
+ log.info("Pausing for slow clients:" + clients);
+ }
+
+ if (console.isDebugEnabled() && ((_sent / _batchSize % LOG_UPATE_INTERVAL) == 0))
+ {
+ console.debug(_slowClients.size() + " slow clients.");
+ }
+
+ sleep(PAUSE_SLEEP);
+ }
+
+ if (NO_CLIENTS)
+ {
+ sleep(NO_CLIENT_SLEEP);
+ }
+
+ log.debug("Continuing");
+
+ return true;
+ }
+ else
+ {
+ if ((_sent / _batchSize % LOG_UPATE_INTERVAL) == 0)
+ {
+ console.info("Total Delay :" + _delay + " "
+ + ((_delayShifting == 0) ? "Stablised" : ("Not Stablised(" + _delayShifting + ")")));
+ }
+ }
+
+ }
+
+ return false;
+ }
+
+ /**
+ * Sleep normally takes micro-seconds this allows the use of a nano-second value.
+ *
+ * @param delay nanoseconds to sleep for.
+ */
+ private void sleepLong(long delay)
+ {
+ sleep(delay / 1000000, (int) (delay % 1000000));
+ }
+
+ /**
+ * Sleep for the specified micro-seconds.
+ * @param sleep microseconds to sleep for.
+ */
+ private void sleep(long sleep)
+ {
+ sleep(sleep, 0);
+ }
+
+ /**
+ * Perform the sleep , swallowing any InteruptException.
+ *
+ * NOTE: If a sleep request is > 10s then reset only sleep for 5s
+ *
+ * @param milli to sleep for
+ * @param nano sub miliseconds to sleep for
+ */
+ private void sleep(long milli, int nano)
+ {
+ try
+ {
+ log.debug("Sleep:" + milli + ":" + nano);
+ if (milli > 10000)
+ {
+
+ if (_delay == milli)
+ {
+ _totalDuration = _totalReceived / _batchSize * EXPECTED_TIME_PER_BATCH;
+ log.error("Sleeping for more than 10 seconds adjusted to 5s!:" + (milli / 1000)
+ + "s. Reset _totalDuration:" + _totalDuration);
+ }
+ else
+ {
+ log.error("Sleeping for more than 10 seconds adjusted to 5s!:" + (milli / 1000) + "s");
+ }
+
+ milli = 5000;
+ }
+
+ Thread.sleep(milli, nano);
+ }
+ catch (InterruptedException e)
+ {
+ //
+ }
+ }
+
+ public void setClient(SustainedClientTestCase client)
+ {
+ _client = client;
+ }
+ }
+
+}
diff --git a/java/integrationtests/src/main/java/org/apache/qpid/sustained/SustainedTestCase.java b/java/integrationtests/src/main/java/org/apache/qpid/sustained/SustainedTestCase.java
new file mode 100644
index 0000000000..36f9b4eaf1
--- /dev/null
+++ b/java/integrationtests/src/main/java/org/apache/qpid/sustained/SustainedTestCase.java
@@ -0,0 +1,126 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT 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.sustained;
+
+import org.apache.log4j.Logger;
+
+import org.apache.qpid.client.AMQSession;
+import org.apache.qpid.test.framework.distributedtesting.DistributedTestCase;
+import org.apache.qpid.test.framework.DropInTest;
+
+import javax.jms.JMSException;
+import javax.jms.Message;
+
+import java.util.Properties;
+
+/**
+ * SustainedTestCase is a {@link org.apache.qpid.test.framework.distributedtesting.DistributedTestCase} that runs the "Perf_SustainedPubSub" test case. This consists of one
+ * test client sending, and several receiving, and attempts to find the highest rate at which messages can be broadcast
+ * to the receivers. It is also a {@link DropInTest} to which more test clients may be added during a test run.
+ *
+ * <p/><table id="crc"><caption>CRC Card</caption>
+ * <tr><th> Responsibilities <th> Collaborations
+ * <tr><td>
+ * </table>
+ */
+public class SustainedTestCase extends DistributedTestCase implements DropInTest
+{
+ /** Used for debugging. */
+ Logger log = Logger.getLogger(SustainedTestCase.class);
+
+ /** Holds the root name of the topic on which to send the test messages. */
+ private static final String SUSTAINED_KEY = "Perf_SustainedPubSub";
+
+ /**
+ * Creates a new coordinating test case with the specified name.
+ *
+ * @param name The test case name.
+ */
+ public SustainedTestCase(String name)
+ {
+ super(name);
+ }
+
+ /**
+ * Performs a single test run of the sustained test.
+ *
+ * @throws Exception Any exceptions are allowed to fall through and fail the test.
+ */
+ public void testBasicPubSub() throws Exception
+ {
+ log.debug("public void testSinglePubSubCycle(): called");
+
+ Properties testConfig = new Properties();
+ testConfig.put("TEST_NAME", "Perf_SustainedPubSub");
+ testConfig.put("SUSTAINED_KEY", SUSTAINED_KEY);
+ testConfig.put("SUSTAINED_NUM_RECEIVERS", Integer.getInteger("numReceives", 2));
+ testConfig.put("SUSTAINED_UPDATE_INTERVAL", Integer.getInteger("batchSize", 1000));
+ testConfig.put("SUSTAINED_UPDATE_KEY", SUSTAINED_KEY + ".UPDATE");
+ testConfig.put("ACKNOWLEDGE_MODE", Integer.getInteger("ackMode", AMQSession.AUTO_ACKNOWLEDGE));
+
+ log.info("Created Config: " + testConfig.entrySet().toArray());
+
+ getTestSequencer().sequenceTest(null, null, testConfig);
+ }
+
+ /**
+ * Accepts a late joining client into this test case. The client will be enlisted with a control message
+ * with the 'CONTROL_TYPE' field set to the value 'LATEJOIN'. It should also provide values for the fields:
+ *
+ * <p/><table>
+ * <tr><td> CLIENT_NAME <td> A unique name for the new client.
+ * <tr><td> CLIENT_PRIVATE_CONTROL_KEY <td> The key for the route on which the client receives its control messages.
+ * </table>
+ *
+ * @param message The late joiners join message.
+ *
+ * @throws JMSException Any JMS Exception are allowed to fall through, indicating that the join failed.
+ */
+ public void lateJoin(Message message) throws JMSException
+ {
+ throw new RuntimeException("Not implemented.");
+ /*
+ // Extract the joining clients details from its join request message.
+ TestClientDetails clientDetails = new TestClientDetails();
+ clientDetails.clientName = message.getStringProperty("CLIENT_NAME");
+ clientDetails.privateControlKey = message.getStringProperty("CLIENT_PRIVATE_CONTROL_KEY");
+
+ // Register the joining client, but do block for confirmation as cannot do a synchronous receivers during this
+ // method call, as it may have been called from an 'onMessage' method.
+ assignReceiverRole(clientDetails, new Properties(), false);
+ */
+ }
+
+ /**
+ * Should provide a translation from the junit method name of a test to its test case name as known to the test
+ * clients that will run the test. The purpose of this is to convert the JUnit method name into the correct test
+ * case name to place into the test invite. For example the method "testP2P" might map onto the interop test case
+ * name "TC2_BasicP2P".
+ *
+ * @param methodName The name of the JUnit test method.
+ *
+ * @return The name of the corresponding interop test case.
+ */
+ public String getTestCaseNameForTestMethod(String methodName)
+ {
+ return "Perf_SustainedPubSub";
+ }
+}
diff --git a/java/integrationtests/src/main/java/org/apache/qpid/sustained/SustainedTestClient.java b/java/integrationtests/src/main/java/org/apache/qpid/sustained/SustainedTestClient.java
index 6f2089290a..79707bafa5 100644
--- a/java/integrationtests/src/main/java/org/apache/qpid/sustained/SustainedTestClient.java
+++ b/java/integrationtests/src/main/java/org/apache/qpid/sustained/SustainedTestClient.java
@@ -425,7 +425,7 @@ public class SustainedTestClient extends TestCase3BasicPubSub implements Excepti
class SustainedRateAdapter implements MessageListener, Runnable
{
private SustainedTestClient _client;
- private long _batchVariance = 3; //no. batches to allow drifting
+ private long _batchVariance = Integer.getInteger("batchVariance", 3); //no. batches to allow drifting
private long _timeVariance = TEN_MILLI_SEC * 5; // no. nanos between send and report delay (10ms)
private volatile long _delay; //in nanos
private long _sent;
@@ -434,9 +434,11 @@ public class SustainedTestClient extends TestCase3BasicPubSub implements Excepti
private static final long NO_CLIENT_SLEEP = 1000; // 1s
private volatile boolean NO_CLIENTS = true;
private int _delayShifting;
- private static final int REPORTS_WITHOUT_CHANGE = 5;
+ private final int REPORTS_WITHOUT_CHANGE = Integer.getInteger("stableReportCount", 5);
private boolean _warmedup = false;
private static final long EXPECTED_TIME_PER_BATCH = 100000L;
+ private int _warmUpBatches = Integer.getInteger("warmUpBatches", 10);
+
SustainedRateAdapter(SustainedTestClient client)
{
@@ -493,8 +495,6 @@ public class SustainedTestClient extends TestCase3BasicPubSub implements Excepti
CountDownLatch _warmup = new CountDownLatch(1);
- int _warmUpBatches = Integer.getInteger("warmUpBatches", 10);
-
int _numBatches = 10000;
// long[] _timings = new long[_numBatches];
diff --git a/java/integrationtests/src/main/java/org/apache/qpid/sustained/SustainedTestCoordinator.java b/java/integrationtests/src/main/java/org/apache/qpid/sustained/SustainedTestCoordinator.java
deleted file mode 100644
index 0075e45a8c..0000000000
--- a/java/integrationtests/src/main/java/org/apache/qpid/sustained/SustainedTestCoordinator.java
+++ /dev/null
@@ -1,222 +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.sustained;
-
-import org.apache.log4j.Logger;
-import org.apache.qpid.client.AMQSession;
-import org.apache.qpid.interop.coordinator.ListeningCoordinatorTest;
-import org.apache.qpid.interop.coordinator.TestClientDetails;
-import org.apache.qpid.interop.coordinator.testcases.CoordinatingTestCase3BasicPubSub;
-import org.apache.qpid.util.ConversationFactory;
-
-import javax.jms.Destination;
-import javax.jms.JMSException;
-import javax.jms.Message;
-import javax.jms.Session;
-import java.util.HashMap;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Map;
-
-public class SustainedTestCoordinator extends CoordinatingTestCase3BasicPubSub implements ListeningCoordinatorTest
-{
- /** Used for debugging. */
- private static final Logger log = Logger.getLogger(SustainedTestCoordinator.class);
- private List<TestClientDetails> _receivers;
- private static final String SUSTAINED_KEY = "Perf_SustainedPubSub";
- Map<String, Object> _testProperties;
-
- /**
- * Creates a new coordinating test case with the specified name.
- *
- * @param name The test case name.
- */
- public SustainedTestCoordinator(String name)
- {
- super(name);
- _receivers = new LinkedList();
- }
-
- /**
- * Adds a receiver to this test.
- *
- * @param receiver The contact details of the sending client in the test.
- */
- public void setReceiver(TestClientDetails receiver)
- {
- _receivers.add(receiver);
- }
-
-
- /**
- * Performs the a single test run
- *
- * @throws Exception if there was a problem running the test.
- */
- public void testBasicPubSub() throws Exception
- {
- log.debug("public void testSinglePubSubCycle(): called");
-
- Map<String, Object> testConfig = new HashMap<String, Object>();
- testConfig.put("TEST_NAME", "Perf_SustainedPubSub");
- testConfig.put("SUSTAINED_KEY", SUSTAINED_KEY);
- testConfig.put("SUSTAINED_NUM_RECEIVERS", Integer.getInteger("numReceives", 2));
- testConfig.put("SUSTAINED_UPDATE_INTERVAL", Integer.getInteger("batchSize", 1000));
- testConfig.put("SUSTAINED_UPDATE_KEY", SUSTAINED_KEY + ".UPDATE");
- testConfig.put("ACKNOWLEDGE_MODE", Integer.getInteger("ackMode", AMQSession.AUTO_ACKNOWLEDGE));
-
- log.info("Created Config: " + testConfig.entrySet().toArray());
-
- sequenceTest(testConfig);
- }
-
- /**
- * Holds a test coordinating conversation with the test clients. This is the basic implementation of the inner loop
- * of Use Case 5. It consists of assigning the test roles, begining the test and gathering the test reports from the
- * participants.
- *
- * @param testProperties The test case definition.
- *
- * @return The test results from the senders and receivers.
- *
- * @throws javax.jms.JMSException All underlying JMSExceptions are allowed to fall through.
- */
- protected Message[] sequenceTest(Map<String, Object> testProperties) throws JMSException
- {
- log.debug("protected Message[] sequenceTest(Object... testProperties = " + testProperties + "): called");
-
- Session session = conversationFactory.getSession();
- Destination senderControlTopic = session.createTopic(sender.privateControlKey);
-
- ConversationFactory.Conversation senderConversation = conversationFactory.startConversation();
-
- // Assign the sender role to the sending test client.
- Message assignSender = conversationFactory.getSession().createMessage();
- setPropertiesOnMessage(assignSender, testProperties);
- assignSender.setStringProperty("CONTROL_TYPE", "ASSIGN_ROLE");
- assignSender.setStringProperty("ROLE", "SENDER");
- assignSender.setStringProperty("CLIENT_NAME", "Sustained_SENDER");
-
- senderConversation.send(senderControlTopic, assignSender);
-
- //Assign and wait for the receiver ckuebts to be ready.
- _testProperties = testProperties;
-
- // Wait for the senders to confirm their roles.
- senderConversation.receive();
-
- assignReceivers();
-
- // Start the test.
- Message start = session.createMessage();
- start.setStringProperty("CONTROL_TYPE", "START");
-
- senderConversation.send(senderControlTopic, start);
-
- // Wait for the test sender to return its report.
- Message senderReport = senderConversation.receive();
-
- try
- {
- Thread.sleep(500);
- }
- catch (InterruptedException e)
- {
- }
-
- // Ask the receiver for its report.
- Message statusRequest = session.createMessage();
- statusRequest.setStringProperty("CONTROL_TYPE", "STATUS_REQUEST");
-
-
- return new Message[]{senderReport};
- }
-
- private void assignReceivers()
- {
- for (TestClientDetails receiver : _receivers)
- {
- registerReceiver(receiver);
- }
- }
-
- private void registerReceiver(TestClientDetails receiver)
- {
- log.info("registerReceiver called for receiver:" + receiver);
- try
- {
- Session session = conversationFactory.getSession();
- Destination receiverControlTopic = session.createTopic(receiver.privateControlKey);
- ConversationFactory.Conversation receiverConversation = conversationFactory.startConversation();
- // Assign the receiver role the receiving client.
- Message assignReceiver = session.createMessage();
- setPropertiesOnMessage(assignReceiver, _testProperties);
- assignReceiver.setStringProperty("CONTROL_TYPE", "ASSIGN_ROLE");
- assignReceiver.setStringProperty("ROLE", "RECEIVER");
- assignReceiver.setStringProperty("CLIENT_NAME", "Sustained_RECEIVER_" + receiver.clientName);
-
- receiverConversation.send(receiverControlTopic, assignReceiver);
-
- //Don't wait for receiver to be ready.... we can't this is being done in
- // the dispatcher thread, and most likely the acceptance message we
- // want is sitting in the Dispatcher._queue waiting its turn for being
- // dispatched so if we block here we won't can't get the message.
- // So assume consumer is ready for action.
- //receiverConversation.receive();
- }
- catch (JMSException e)
- {
- log.warn("Unable to assign receiver:" + receiver + ". Due to:" + e.getMessage());
- }
- }
-
- public void latejoin(Message message)
- {
- try
- {
-
- TestClientDetails clientDetails = new TestClientDetails();
- clientDetails.clientName = message.getStringProperty("CLIENT_NAME");
- clientDetails.privateControlKey = message.getStringProperty("CLIENT_PRIVATE_CONTROL_KEY");
-
-
- registerReceiver(clientDetails);
- }
- catch (JMSException e)
- {
- //swallow
- }
- }
-
- /**
- * Should provide a translation from the junit method name of a test to its test case name as defined in the interop
- * testing specification. For example the method "testP2P" might map onto the interop test case name
- * "TC2_BasicP2P".
- *
- * @param methodName The name of the JUnit test method.
- *
- * @return The name of the corresponding interop test case.
- */
- public String getTestCaseNameForTestMethod(String methodName)
- {
- return "Perf_SustainedPubSub";
- }
-}
diff --git a/java/integrationtests/src/main/java/org/apache/qpid/sustained/TestClient.java b/java/integrationtests/src/main/java/org/apache/qpid/sustained/TestClient.java
deleted file mode 100644
index 44fc090410..0000000000
--- a/java/integrationtests/src/main/java/org/apache/qpid/sustained/TestClient.java
+++ /dev/null
@@ -1,157 +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.sustained;
-
-import org.apache.log4j.Logger;
-import org.apache.qpid.interop.testclient.InteropClientTestCase;
-import org.apache.qpid.util.CommandLineParser;
-
-import javax.jms.JMSException;
-import javax.jms.Message;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.Properties;
-
-public class TestClient extends org.apache.qpid.interop.testclient.TestClient
-{
- private static Logger log = Logger.getLogger(TestClient.class);
-
- /**
- * Creates a new interop test client, listenting to the specified broker and virtual host, with the specified client
- * identifying name.
- *
- * @param brokerUrl The url of the broker to connect to.
- * @param virtualHost The virtual host to conect to.
- * @param clientName The client name to use.
- */
- public TestClient(String brokerUrl, String virtualHost, String clientName)
- {
- super(brokerUrl, virtualHost, clientName);
- }
-
- /**
- * The entry point for the interop test coordinator. This client accepts the following command line arguments:
- *
- * <p/><table> <tr><td> -b <td> The broker URL. <td> Optional. <tr><td> -h <td> The virtual
- * host. <td> Optional. <tr><td> -n <td> The test client name. <td> Optional. <tr><td> name=value <td>
- * Trailing argument define name/value pairs. Added to system properties. <td> Optional. </table>
- *
- * @param args The command line arguments.
- */
- public static void main(String[] args)
- {
- // Use the command line parser to evaluate the command line.
- CommandLineParser commandLine =
- new CommandLineParser(
- new String[][]
- {
- {"b", "The broker URL.", "broker", "false"},
- {"h", "The virtual host to use.", "virtual host", "false"},
- {"n", "The test client name.", "name", "false"},
- {"j", "Join this test client to running test.", "join", ""}
- });
-
- // Capture the command line arguments or display errors and correct usage and then exit.
- Properties options = null;
-
- try
- {
- options = commandLine.parseCommandLine(args);
- }
- catch (IllegalArgumentException e)
- {
- System.out.println(commandLine.getErrors());
- System.out.println(commandLine.getUsage());
- System.exit(1);
- }
-
- // Extract the command line options.
- String brokerUrl = options.getProperty("b");
- String virtualHost = options.getProperty("h");
- String clientName = options.getProperty("n");
- String join = options.getProperty("j");
-
- // Add all the trailing command line options (name=value pairs) to system properties. Tests may pick up
- // overridden values from there.
- commandLine.addCommandLineToSysProperties();
-
- // Create a test client and start it running.
- TestClient client = new TestClient(brokerUrl, virtualHost, (clientName == null) ? CLIENT_NAME : clientName);
-
- // Use a class path scanner to find all the interop test case implementations.
- Collection<Class<? extends InteropClientTestCase>> testCaseClasses =
- new ArrayList<Class<? extends InteropClientTestCase>>();
- // ClasspathScanner.getMatches(InteropClientTestCase.class, "^TestCase.*", true);
- // Hard code the test classes till the classpath scanner is fixed.
- Collections.addAll(testCaseClasses,
- SustainedTestClient.class);
-
-
- try
- {
- client.start(testCaseClasses, join);
- }
- catch (Exception e)
- {
- log.error("The test client was unable to start.", e);
- System.exit(1);
- }
- }
-
- protected void start(Collection<Class<? extends InteropClientTestCase>> testCaseClasses, String join) throws JMSException, ClassNotFoundException
- {
- super.start(testCaseClasses);
- log.debug("private void start(): called");
-
- if (join != null && !join.equals(""))
- {
- Message latejoin = session.createMessage();
-
- try
- {
- Object test = Class.forName(join).newInstance();
- if (test instanceof InteropClientTestCase)
- {
- currentTestCase = (InteropClientTestCase) test;
- }
- else
- {
- throw new RuntimeException("Requested to join class '" + join + "' but this is not a InteropClientTestCase.");
- }
-
- latejoin.setStringProperty("CONTROL_TYPE", "LATEJOIN");
- latejoin.setStringProperty("CLIENT_NAME", clientName);
- latejoin.setStringProperty("CLIENT_PRIVATE_CONTROL_KEY", "iop.control." + clientName);
- producer.send(session.createTopic("iop.control.test." + currentTestCase.getName()), latejoin);
- }
- catch (InstantiationException e)
- {
- log.warn("Unable to request latejoining of test:" + currentTestCase);
- }
- catch (IllegalAccessException e)
- {
- log.warn("Unable to request latejoining of test:" + currentTestCase);
- }
- }
- }
-
-}
diff --git a/java/integrationtests/src/main/java/org/apache/qpid/sustained/TestCoordinator.java b/java/integrationtests/src/main/java/org/apache/qpid/sustained/TestCoordinator.java
deleted file mode 100644
index 7e12fe39fb..0000000000
--- a/java/integrationtests/src/main/java/org/apache/qpid/sustained/TestCoordinator.java
+++ /dev/null
@@ -1,117 +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.sustained;
-
-import org.apache.qpid.interop.coordinator.Coordinator;
-import org.apache.qpid.interop.coordinator.ListeningTestDecorator;
-import org.apache.qpid.interop.coordinator.TestClientDetails;
-import org.apache.qpid.util.CommandLineParser;
-import org.apache.qpid.util.ConversationFactory;
-import org.apache.log4j.Logger;
-
-import java.util.Properties;
-import java.util.Set;
-
-import junit.framework.TestResult;
-import uk.co.thebadgerset.junit.extensions.WrappedSuiteTestDecorator;
-
-import javax.jms.Connection;
-
-public class TestCoordinator extends Coordinator
-{
-
- private static final Logger log = Logger.getLogger(TestCoordinator.class);
-
- /**
- * Creates an interop test coordinator on the specified broker and virtual host.
- *
- * @param brokerUrl The URL of the broker to connect to.
- * @param virtualHost The virtual host to run all tests on. Optional, may be <tt>null</tt>.
- */
- TestCoordinator(String brokerUrl, String virtualHost)
- {
- super(brokerUrl, virtualHost);
- }
-
- protected WrappedSuiteTestDecorator newTestDecorator(WrappedSuiteTestDecorator targetTest, Set<TestClientDetails> enlistedClients, ConversationFactory conversationFactory, Connection connection)
- {
- return new ListeningTestDecorator(targetTest, enlistedClients, conversationFactory, connection);
- }
-
-
- /**
- * The entry point for the interop test coordinator. This client accepts the following command line arguments:
- *
- * <p/><table> <tr><td> -b <td> The broker URL. <td> Mandatory. <tr><td> -h <td> The virtual host.
- * <td> Optional. <tr><td> name=value <td> Trailing argument define name/value pairs. Added to system properties.
- * <td> Optional. </table>
- *
- * @param args The command line arguments.
- */
- public static void main(String[] args)
- {
- try
- {
- // Use the command line parser to evaluate the command line with standard handling behaviour (print errors
- // and usage then exist if there are errors).
- Properties options =
- CommandLineParser.processCommandLine(args,
- new CommandLineParser(
- new String[][]
- {
- {"b", "The broker URL.", "broker", "false"},
- {"h", "The virtual host to use.", "virtual host", "false"},
- {"o", "The name of the directory to output test timings to.", "dir", "false"}
- }));
-
- // Extract the command line options.
- String brokerUrl = options.getProperty("b");
- String virtualHost = options.getProperty("h");
- String reportDir = options.getProperty("o");
- reportDir = (reportDir == null) ? "." : reportDir;
-
-
- String[] testClassNames = {SustainedTestCoordinator.class.getName()};
-
- // Create a coordinator and begin its test procedure.
- Coordinator coordinator = new TestCoordinator(brokerUrl, virtualHost);
-
- coordinator.setReportDir(reportDir);
-
- TestResult testResult = coordinator.start(testClassNames);
-
- if (testResult.failureCount() > 0)
- {
- System.exit(FAILURE_EXIT);
- }
- else
- {
- System.exit(SUCCESS_EXIT);
- }
- }
- catch (Exception e)
- {
- System.err.println(e.getMessage());
- log.error("Top level handler caught execption.", e);
- System.exit(EXCEPTION_EXIT);
- }
- }
-}
diff --git a/java/integrationtests/src/main/java/org/apache/qpid/interop/testclient/InteropClientTestCase.java b/java/integrationtests/src/main/java/org/apache/qpid/test/framework/distributedtesting/InteropClientTestCase.java
index 37952d08c8..5e6d61a9e0 100644
--- a/java/integrationtests/src/main/java/org/apache/qpid/interop/testclient/InteropClientTestCase.java
+++ b/java/integrationtests/src/main/java/org/apache/qpid/test/framework/distributedtesting/InteropClientTestCase.java
@@ -18,7 +18,7 @@
* under the License.
*
*/
-package org.apache.qpid.interop.testclient;
+package org.apache.qpid.test.framework.distributedtesting;
import javax.jms.JMSException;
import javax.jms.Message;
@@ -44,7 +44,11 @@ public interface InteropClientTestCase extends MessageListener
/** Defines the possible test case roles that an interop test case can take on. */
public enum Roles
{
- SENDER, RECEIVER;
+ /** Specifies the sender role. */
+ SENDER,
+
+ /** Specifies the receivers role. */
+ RECEIVER
}
/**
@@ -70,7 +74,7 @@ public interface InteropClientTestCase extends MessageListener
* Assigns the role to be played by this test case. The test parameters are fully specified in the
* assignment message. When this method return the test case will be ready to execute.
*
- * @param role The role to be played; sender or receiver.
+ * @param role The role to be played; sender or receivers.
* @param assignRoleMessage The role assingment message, contains the full test parameters.
*
* @throws JMSException Any JMSException resulting from reading the message are allowed to fall through.
@@ -78,20 +82,13 @@ public interface InteropClientTestCase extends MessageListener
public void assignRole(Roles role, Message assignRoleMessage) throws JMSException;
/**
- * Performs the test case actions.
- * return from here when you have finished the test.. this will signal the controller that the test has ended.
+ * Performs the test case actions. Returning from here, indicates that the sending role has completed its test.
+ *
* @throws JMSException Any JMSException resulting from reading the message are allowed to fall through.
*/
public void start() throws JMSException;
/**
- * Gives notice of termination of the test case actions.
- *
- * @throws JMSException Any JMSException resulting from allowed to fall through.
- */
- public void terminate() throws JMSException, InterruptedException;
-
- /**
* Gets a report on the actions performed by the test case in its assigned role.
*
* @param session The session to create the report message in.
diff --git a/java/integrationtests/src/main/java/org/apache/qpid/interop/testclient/TestClient.java b/java/integrationtests/src/main/java/org/apache/qpid/test/framework/distributedtesting/TestClient.java
index a904bfa419..12c0d0aa69 100644
--- a/java/integrationtests/src/main/java/org/apache/qpid/interop/testclient/TestClient.java
+++ b/java/integrationtests/src/main/java/org/apache/qpid/test/framework/distributedtesting/TestClient.java
@@ -18,45 +18,41 @@
* under the License.
*
*/
-package org.apache.qpid.interop.testclient;
+package org.apache.qpid.test.framework.distributedtesting;
import org.apache.log4j.Logger;
-import org.apache.qpid.interop.testclient.testcases.TestCase1DummyRun;
-import org.apache.qpid.interop.testclient.testcases.TestCase2BasicP2P;
-import org.apache.qpid.util.CommandLineParser;
-import org.apache.qpid.util.PropertiesUtils;
-
-import javax.jms.Connection;
-import javax.jms.ConnectionFactory;
-import javax.jms.JMSException;
-import javax.jms.Message;
-import javax.jms.MessageConsumer;
-import javax.jms.MessageListener;
-import javax.jms.MessageProducer;
-import javax.jms.Session;
-import javax.naming.Context;
-import javax.naming.InitialContext;
-import javax.naming.NamingException;
-import java.io.IOException;
+
+import org.apache.qpid.interop.clienttestcases.TestCase1DummyRun;
+import org.apache.qpid.interop.clienttestcases.TestCase2BasicP2P;
+import org.apache.qpid.interop.clienttestcases.TestCase3BasicPubSub;
+import org.apache.qpid.sustained.SustainedClientTestCase;
+import org.apache.qpid.test.framework.MessagingTestConfigProperties;
+import org.apache.qpid.test.framework.TestUtils;
+
+import uk.co.thebadgerset.junit.extensions.util.ParsedProperties;
+import uk.co.thebadgerset.junit.extensions.util.TestContextProperties;
+
+import javax.jms.*;
+
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
-import java.util.Properties;
/**
* Implements a test client as described in the interop testing spec
* (http://cwiki.apache.org/confluence/display/qpid/Interop+Testing+Specification). A test client is an agent that
- * reacts to control message sequences send by the test {@link org.apache.qpid.interop.coordinator.Coordinator}.
+ * reacts to control message sequences send by the test {@link org.apache.qpid.test.framework.distributedtesting.Coordinator}.
*
- * <p/><table><caption>Messages Handled by TestClient</caption>
+ * <p/><table><caption>Messages Handled by SustainedTestClient</caption>
* <tr><th> Message <th> Action
* <tr><td> Invite(compulsory) <td> Reply with Enlist.
* <tr><td> Invite(test case) <td> Reply with Enlist if test case available.
* <tr><td> AssignRole(test case) <td> Reply with Accept Role if matches an enlisted test. Keep test parameters.
* <tr><td> Start <td> Send test messages defined by test parameters. Send report on messages sent.
* <tr><td> Status Request <td> Send report on messages received.
+ * <tr><td> Terminate <td> Terminate the test client.
* </table>
*
* <p><table id="crc"><caption>CRC Card</caption>
@@ -67,12 +63,14 @@ import java.util.Properties;
*/
public class TestClient implements MessageListener
{
- private static Logger log = Logger.getLogger(TestClient.class);
+ /** Used for debugging. */
+ private static final Logger log = Logger.getLogger(TestClient.class);
- public static final String CONNECTION_PROPERTY = "connectionfactory.broker";
- public static final String CONNECTION_NAME = "broker";
+ /** Used for reporting to the console. */
+ private static final Logger console = Logger.getLogger("CONSOLE");
+
+ /** Holds the default identifying name of the test client. */
public static final String CLIENT_NAME = "java";
- public static final String DEFAULT_CONNECTION_PROPS_RESOURCE = "org/apache/qpid/interop/connection.properties";
/** Holds the URL of the broker to run the tests on. */
public static String brokerUrl;
@@ -80,17 +78,34 @@ public class TestClient implements MessageListener
/** Holds the virtual host to run the tests on. If <tt>null</tt>, then the default virtual host is used. */
public static String virtualHost;
+ /**
+ * Holds the test context properties that provides the default test parameters, plus command line overrides.
+ * This is initialized with the default test parameters, to which command line overrides may be applied.
+ */
+ public static ParsedProperties testContextProperties =
+ TestContextProperties.getInstance(MessagingTestConfigProperties.defaults);
+
/** Holds all the test cases loaded from the classpath. */
Map<String, InteropClientTestCase> testCases = new HashMap<String, InteropClientTestCase>();
+ /** Holds the test case currently being run by this client. */
protected InteropClientTestCase currentTestCase;
- protected Connection _connection;
+ /** Holds the connection to the broker that the test is being coordinated on. */
+ protected Connection connection;
+
+ /** Holds the message producer to hold the test coordination over. */
protected MessageProducer producer;
+
+ /** Holds the JMS session for the test coordination. */
protected Session session;
+ /** Holds the name of this client, with a default value. */
protected String clientName = CLIENT_NAME;
+ /** This flag indicates that the test client should attempt to join the currently running test case on start up. */
+ protected boolean join;
+
/**
* Creates a new interop test client, listenting to the specified broker and virtual host, with the specified client
* identifying name.
@@ -99,15 +114,16 @@ public class TestClient implements MessageListener
* @param virtualHost The virtual host to conect to.
* @param clientName The client name to use.
*/
- public TestClient(String brokerUrl, String virtualHost, String clientName)
+ public TestClient(String brokerUrl, String virtualHost, String clientName, boolean join)
{
- log.debug("public TestClient(String brokerUrl = " + brokerUrl + ", String virtualHost = " + virtualHost
- + ", String clientName = " + clientName + "): called");
+ log.debug("public SustainedTestClient(String brokerUrl = " + brokerUrl + ", String virtualHost = " + virtualHost
+ + ", String clientName = " + clientName + "): called");
// Retain the connection parameters.
this.brokerUrl = brokerUrl;
this.virtualHost = virtualHost;
this.clientName = clientName;
+ this.join = join;
}
/**
@@ -124,49 +140,41 @@ public class TestClient implements MessageListener
*/
public static void main(String[] args)
{
- // Use the command line parser to evaluate the command line.
- CommandLineParser commandLine =
- new CommandLineParser(
+ // Override the default broker url to be localhost:5672.
+ testContextProperties.setProperty(MessagingTestConfigProperties.BROKER_PROPNAME, "tcp://localhost:5672");
+
+ // Use the command line parser to evaluate the command line with standard handling behaviour (print errors
+ // and usage then exist if there are errors).
+ // Any options and trailing name=value pairs are also injected into the test context properties object,
+ // to override any defaults that may have been set up.
+ ParsedProperties options =
+ new ParsedProperties(uk.co.thebadgerset.junit.extensions.util.CommandLineParser.processCommandLine(args,
+ new uk.co.thebadgerset.junit.extensions.util.CommandLineParser(
new String[][]
- {
- {"b", "The broker URL.", "broker", "false"},
- {"h", "The virtual host to use.", "virtual host", "false"},
- {"n", "The test client name.", "name", "false"}
- });
-
- // Capture the command line arguments or display errors and correct usage and then exit.
- Properties options = null;
-
- try
- {
- options = commandLine.parseCommandLine(args);
- }
- catch (IllegalArgumentException e)
- {
- System.out.println(commandLine.getErrors());
- System.out.println(commandLine.getUsage());
- System.exit(1);
- }
+ {
+ { "b", "The broker URL.", "broker", "false" },
+ { "h", "The virtual host to use.", "virtual host", "false" },
+ { "o", "The name of the directory to output test timings to.", "dir", "false" },
+ { "n", "The name of the test client.", "name", "false" },
+ { "j", "Join this test client to running test.", "false" }
+ }), testContextProperties));
// Extract the command line options.
String brokerUrl = options.getProperty("b");
String virtualHost = options.getProperty("h");
String clientName = options.getProperty("n");
-
- // Add all the trailing command line options (name=value pairs) to system properties. Tests may pick up
- // overridden values from there.
- commandLine.addCommandLineToSysProperties();
+ boolean join = options.getPropertyAsBoolean("j");
// Create a test client and start it running.
- TestClient client = new TestClient(brokerUrl, virtualHost, (clientName == null) ? CLIENT_NAME : clientName);
+ TestClient client = new TestClient(brokerUrl, virtualHost, (clientName == null) ? CLIENT_NAME : clientName, join);
// Use a class path scanner to find all the interop test case implementations.
+ // Hard code the test classes till the classpath scanner is fixed.
Collection<Class<? extends InteropClientTestCase>> testCaseClasses =
- new ArrayList<Class<? extends InteropClientTestCase>>();
+ new ArrayList<Class<? extends InteropClientTestCase>>();
// ClasspathScanner.getMatches(InteropClientTestCase.class, "^TestCase.*", true);
- // Hard code the test classes till the classpath scanner is fixed.
- Collections.addAll(testCaseClasses,
- new Class[]{TestCase1DummyRun.class, TestCase2BasicP2P.class, TestClient.class});
+ Collections.addAll(testCaseClasses, TestCase1DummyRun.class, TestCase2BasicP2P.class, TestCase3BasicPubSub.class,
+ SustainedClientTestCase.class);
try
{
@@ -182,7 +190,10 @@ public class TestClient implements MessageListener
/**
* Starts the interop test client running. This causes it to start listening for incoming test invites.
*
- * @throws JMSException Any underlying JMSExceptions are allowed to fall through. @param testCaseClasses
+ * @param testCaseClasses The classes of the available test cases. The test case names from these are used to
+ * matchin incoming test invites against.
+ *
+ * @throws JMSException Any underlying JMSExceptions are allowed to fall through.
*/
protected void start(Collection<Class<? extends InteropClientTestCase>> testCaseClasses) throws JMSException
{
@@ -209,84 +220,36 @@ public class TestClient implements MessageListener
}
// Open a connection to communicate with the coordinator on.
- _connection = createConnection(DEFAULT_CONNECTION_PROPS_RESOURCE, clientName, brokerUrl, virtualHost);
-
- session = _connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
+ connection = TestUtils.createConnection(testContextProperties);
+ session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
// Set this up to listen for control messages.
- MessageConsumer consumer = session.createConsumer(session.createTopic("iop.control." + clientName));
+ Topic privateControlTopic = session.createTopic("iop.control." + clientName);
+ MessageConsumer consumer = session.createConsumer(privateControlTopic);
consumer.setMessageListener(this);
- MessageConsumer consumer2 = session.createConsumer(session.createTopic("iop.control"));
+ Topic controlTopic = session.createTopic("iop.control");
+ MessageConsumer consumer2 = session.createConsumer(controlTopic);
consumer2.setMessageListener(this);
// Create a producer to send replies with.
producer = session.createProducer(null);
- // Start listening for incoming control messages.
- _connection.start();
- }
-
-
- public static Connection createConnection(String connectionPropsResource, String brokerUrl, String virtualHost)
- {
- return createConnection(connectionPropsResource, "clientID", brokerUrl, virtualHost);
- }
-
- /**
- * Establishes a JMS connection using a properties file and qpids built in JNDI implementation. This is a simple
- * convenience method for code that does anticipate handling connection failures. All exceptions that indicate that
- * the connection has failed, are wrapped as rutime exceptions, preumably handled by a top level failure handler.
- *
- * @param connectionPropsResource The name of the connection properties file.
- * @param clientID
- * @param brokerUrl The broker url to connect to, <tt>null</tt> to use the default from the
- * properties.
- * @param virtualHost The virtual host to connectio to, <tt>null</tt> to use the default.
- *
- * @return A JMS conneciton.
- *
- * @todo Make username/password configurable. Allow multiple urls for fail over. Once it feels right, move it to a
- * Utils library class.
- */
- public static Connection createConnection(String connectionPropsResource, String clientID, String brokerUrl, String virtualHost)
- {
- log.debug("public static Connection createConnection(String connectionPropsResource = " + connectionPropsResource
- + ", String brokerUrl = " + brokerUrl + ", String clientID = " + clientID
- + ", String virtualHost = " + virtualHost + " ): called");
-
- try
+ // If the join flag was set, then broadcast a join message to notify the coordinator that a new test client
+ // is available to join the current test case, if it supports it. This message may be ignored, or it may result
+ // in this test client receiving a test invite.
+ if (join)
{
- Properties connectionProps =
- PropertiesUtils.getProperties(TestClient.class.getClassLoader().getResourceAsStream(
- connectionPropsResource));
-
- if (brokerUrl != null)
- {
- String connectionString =
- "amqp://guest:guest@" + clientID + "/" + ((virtualHost != null) ? virtualHost : "") + "?brokerlist='" + brokerUrl + "'";
- connectionProps.setProperty(CONNECTION_PROPERTY, connectionString);
- }
-
- Context ctx = new InitialContext(connectionProps);
-
- ConnectionFactory cf = (ConnectionFactory) ctx.lookup(CONNECTION_NAME);
- Connection connection = cf.createConnection();
+ Message joinMessage = session.createMessage();
- return connection;
- }
- catch (IOException e)
- {
- throw new RuntimeException(e);
- }
- catch (NamingException e)
- {
- throw new RuntimeException(e);
- }
- catch (JMSException e)
- {
- throw new RuntimeException(e);
+ joinMessage.setStringProperty("CONTROL_TYPE", "JOIN");
+ joinMessage.setStringProperty("CLIENT_NAME", clientName);
+ joinMessage.setStringProperty("CLIENT_PRIVATE_CONTROL_KEY", "iop.control." + clientName);
+ producer.send(controlTopic, joinMessage);
}
+
+ // Start listening for incoming control messages.
+ connection.start();
}
/**
@@ -327,7 +290,7 @@ public class TestClient implements MessageListener
}
else
{
- log.warn("'" + testName + "' not part of this clients tests.");
+ log.debug("Received an invite to the test '" + testName + "' but this test is not known.");
}
}
else
@@ -394,16 +357,8 @@ public class TestClient implements MessageListener
{
log.info("Received termination instruction from coordinator.");
-// try
-// {
-// currentTestCase.terminate();
-// }
-// catch (InterruptedException e)
-// {
-// //
-// }
// Is a cleaner shutdown needed?
- _connection.close();
+ connection.close();
System.exit(0);
}
else
diff --git a/java/management/eclipse-plugin/pom.xml b/java/management/eclipse-plugin/pom.xml
index 6637460822..2ec30d212a 100644
--- a/java/management/eclipse-plugin/pom.xml
+++ b/java/management/eclipse-plugin/pom.xml
@@ -15,7 +15,7 @@
KIND, either express or implied. See the License for the
specific language governing permissions and limitations
under the License.
--->
+ -->
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
@@ -38,17 +38,17 @@
</properties>
<repositories>
- <repository>
+ <repository>
<id>repo1.maven.org</id>
<name>Maven eclipse Repository</name>
<url>http://repo1.maven.org/eclipse</url>
- </repository>
- <repository>
+ </repository>
+ <repository>
<id>apache.snapshots</id>
<name>Apache SNAPSHOT Repository</name>
<url>http://people.apache.org/repo/m2-snapshot-repository</url>
<snapshots>
- <enabled>true</enabled>
+ <enabled>true</enabled>
</snapshots>
</repository>
</repositories>
@@ -197,43 +197,46 @@
<directory>icons/</directory>
<targetPath>icons/</targetPath>
<includes>
- <include>**</include>
+ <include>**</include>
</includes>
</resource>
<resource>
<directory>icons/</directory>
<targetPath>/</targetPath>
<includes>
- <include>splash.bmp</include>
+ <include>splash.bmp</include>
</includes>
</resource>
<resource>
- <directory>${basedir}</directory>
- <targetPath>/</targetPath>
- <includes>
- <include>plugin.xml</include>
- <include>plugin.properties</include>
- </includes>
+ <directory>${basedir}</directory>
+ <targetPath>/</targetPath>
+ <includes>
+ <include>plugin.xml</include>
+ <include>plugin.properties</include>
+ </includes>
</resource>
- </resources>
+ </resources>
<plugins>
<!--
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-antrun-plugin</artifactId>
</plugin>
+ -->
+ <!-- This is required to identify the JAR to eclipse as a plugin -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<configuration>
- <archive>
- <manifestFile>META-INF/MANIFEST.MF</manifestFile>
- </archive>
- <finalName>${artifactId}_${version}</finalName>
+ <archive>
+ <manifestFile>META-INF/MANIFEST.MF</manifestFile>
+ </archive>
+ <finalName>${artifactId}_${version}</finalName>
</configuration>
- </plugin>
+ </plugin>
+ <!--
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
diff --git a/java/management/eclipse-plugin/src/test/java/org/apache/qpid/management/ui/ManagementConsoleTest.java b/java/management/eclipse-plugin/src/test/java/org/apache/qpid/management/ui/ManagementConsoleTest.java
index 6b0394f1a6..56eadbb3b2 100644
--- a/java/management/eclipse-plugin/src/test/java/org/apache/qpid/management/ui/ManagementConsoleTest.java
+++ b/java/management/eclipse-plugin/src/test/java/org/apache/qpid/management/ui/ManagementConsoleTest.java
@@ -1,17 +1,21 @@
/*
- * Copyright (c) 2006 The Apache Software Foundation
*
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
*
- * http://www.apache.org/licenses/LICENSE-2.0
+ * http://www.apache.org/licenses/LICENSE-2.0
*
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT 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.ui;
diff --git a/java/perftests/pom.xml b/java/perftests/pom.xml
index 77d70b7020..e07b0696e5 100644
--- a/java/perftests/pom.xml
+++ b/java/perftests/pom.xml
@@ -87,6 +87,12 @@
<artifactId>junit</artifactId>
</dependency>
+ <dependency>
+ <groupId>org.slf4j</groupId>
+ <artifactId>slf4j-log4j12</artifactId>
+ <version>1.4.0</version>
+ </dependency>
+
</dependencies>
<build>
@@ -186,124 +192,124 @@
-->
<!-- Transient, P2P Tests -->
- <TQR-Qpid-01>-n TQR-Qpid-01 -d10M -s[1000] -c[8] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=false pubsub=false transacted=true commitBatchSize=100 batchSize=1000 messageSize=256 destinationsCount=1 rate=0 maxPending=1000000 </TQR-Qpid-01>
- <TQR-Qpid-02>-n TQR-Qpid-02 -d10M -s[1000] -c[8] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=false pubsub=false transacted=false commitBatchSize=100 batchSize=1000 messageSize=256 destinationsCount=1 rate=0 maxPending=1000000 </TQR-Qpid-02>
- <TQR-Qpid-03>-n TQR-Qpid-03 -d24H -s[100000] -c[8] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=false pubsub=false transacted=true commitBatchSize=100 batchSize=100000 messageSize=256 destinationsCount=1 rate=0 maxPending=1000000 </TQR-Qpid-03>
- <TQR-Qpid-04>-n TQR-Qpid-04 -d24H -s[100000] -c[8] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=false pubsub=false transacted=false commitBatchSize=100 batchSize=100000 messageSize=256 destinationsCount=1 rate=0 maxPending=1000000 </TQR-Qpid-04>
-
- <TQC-Qpid-01>-n TQC-Qpid-01 -d1M -s[1000] -c[1,30],samples=30 -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=false pubsub=false transacted=true commitBatchSize=100 batchSize=1000 messageSize=256 destinationsCount=1 rate=1000 maxPending=1000000 </TQC-Qpid-01>
- <TQC-Qpid-02>-n TQC-Qpid-02 -d1M -s[1000] -c[1,30],samples=30 -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=false pubsub=false transacted=false commitBatchSize=100 batchSize=1000 messageSize=256 destinationsCount=1 rate=1000 maxPending=1000000 </TQC-Qpid-02>
- <TQC-Qpid-03>-n TQC-Qpid-03 -d10M -s[1000] -c[10] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=false pubsub=false transacted=true commitBatchSize=100 batchSize=1000 messageSize=256 destinationsCount=10 rate=0 maxPending=1000000 </TQC-Qpid-03>
- <TQC-Qpid-04>-n TQC-Qpid-04 -d10M -s[1000] -c[10] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=false pubsub=false transacted=false commitBatchSize=100 batchSize=1000 messageSize=256 destinationsCount=10 rate=0 maxPending=1000000 </TQC-Qpid-04>
- <TQC-Qpid-05>-n TQC-Qpid-05 -d10M -s[1000] -c[100] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=false pubsub=false transacted=true commitBatchSize=100 batchSize=1000 messageSize=256 destinationsCount=10 rate=0 maxPending=100000 </TQC-Qpid-05>
- <TQC-Qpid-06>-n TQC-Qpid-06 -d10M -s[1000] -c[100] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=false pubsub=false transacted=false commitBatchSize=100 batchSize=1000 messageSize=256 destinationsCount=10 rate=0 maxPending=100000 </TQC-Qpid-06>
-
- <TQM-Qpid-01-512b>-n TQM-Qpid-01-512b -d10M -s[1000] -c[1] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=false pubsub=false transacted=true commitBatchSize=10 batchSize=1000 messageSize=512 destinationsCount=1 rate=0 maxPending=20000000</TQM-Qpid-01-512b>
- <TQM-Qpid-02-512b>-n TQM-Qpid-02-512b -d10M -s[1000] -c[1] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=false pubsub=false transacted=false commitBatchSize=10 batchSize=1000 messageSize=512 destinationsCount=1 rate=0 maxPending=20000000</TQM-Qpid-02-512b>
- <TQM-Qpid-01-1K>-n TQM-Qpid-01-1K -d10M -s[1000] -c[1] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=false pubsub=false transacted=true commitBatchSize=10 batchSize=1000 messageSize=1024 destinationsCount=1 rate=0 maxPending=20000000</TQM-Qpid-01-1K>
- <TQM-Qpid-02-1K>-n TQM-Qpid-02-1K -d10M -s[1000] -c[1] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=false pubsub=false transacted=false commitBatchSize=10 batchSize=1000 messageSize=1024 destinationsCount=1 rate=0 maxPending=20000000</TQM-Qpid-02-1K>
- <TQM-Qpid-01-5K>-n TQM-Qpid-01-5K -d10M -s[1000] -c[1] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=false pubsub=false transacted=true commitBatchSize=10 batchSize=1000 messageSize=5120 destinationsCount=1 rate=0 maxPending=20000000</TQM-Qpid-01-5K>
- <TQM-Qpid-02-5K>-n TQM-Qpid-02-5K -d10M -s[1000] -c[1] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=false pubsub=false transacted=false commitBatchSize=10 batchSize=1000 messageSize=5120 destinationsCount=1 rate=0 maxPending=20000000</TQM-Qpid-02-5K>
- <TQM-Qpid-01-10K>-n TQM-Qpid-01-10K -d10M -s[1000] -c[1] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=false pubsub=false transacted=true commitBatchSize=10 batchSize=1000 messageSize=10240 destinationsCount=1 rate=0 maxPending=20000000</TQM-Qpid-01-10K>
- <TQM-Qpid-02-10K>-n TQM-Qpid-02-10K -d10M -s[1000] -c[1] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=false pubsub=false transacted=false commitBatchSize=10 batchSize=1000 messageSize=10240 destinationsCount=1 rate=0 maxPending=20000000</TQM-Qpid-02-10K>
- <TQM-Qpid-01-50K>-n TQM-Qpid-01-50K -d10M -s[1000] -c[1] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=false pubsub=false transacted=true commitBatchSize=10 batchSize=1000 messageSize=51200 destinationsCount=1 rate=0 maxPending=20000000</TQM-Qpid-01-50K>
- <TQM-Qpid-02-50K>-n TQM-Qpid-02-50K -d10M -s[1000] -c[1] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=false pubsub=false transacted=false commitBatchSize=10 batchSize=1000 messageSize=51200 destinationsCount=1 rate=0 maxPending=20000000</TQM-Qpid-02-50K>
- <TQM-Qpid-01-100K>-n TQM-Qpid-01-100K -d10M -s[1000] -c[1] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=false pubsub=false transacted=true commitBatchSize=10 batchSize=1000 messageSize=102400 destinationsCount=1 rate=0 maxPending=20000000</TQM-Qpid-01-100K>
- <TQM-Qpid-02-100K>-n TQM-Qpid-02-100K -d10M -s[1000] -c[1] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=false pubsub=false transacted=false commitBatchSize=10 batchSize=1000 messageSize=102400 destinationsCount=1 rate=0 maxPending=20000000</TQM-Qpid-02-100K>
- <TQM-Qpid-01-500K>-n TQM-Qpid-01-500K -d10M -s[1000] -c[1] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=false pubsub=false transacted=true commitBatchSize=10 batchSize=1000 messageSize=512000 destinationsCount=1 rate=0 maxPending=20000000</TQM-Qpid-01-500K>
- <TQM-Qpid-02-500K>-n TQM-Qpid-02-500K -d10M -s[1000] -c[1] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=false pubsub=false transacted=false commitBatchSize=10 batchSize=1000 messageSize=512000 destinationsCount=1 rate=0 maxPending=20000000</TQM-Qpid-02-500K>
- <TQM-Qpid-01-1M>-n TQM-Qpid-01-1M -d10M -s[1000] -c[1] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=false pubsub=false transacted=true commitBatchSize=10 batchSize=1000 messageSize=1048576 destinationsCount=1 rate=0 maxPending=20000000</TQM-Qpid-01-1M>
- <TQM-Qpid-02-1M>-n TQM-Qpid-02-1M -d10M -s[1000] -c[1] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=false pubsub=false transacted=false commitBatchSize=10 batchSize=1000 messageSize=1048576 destinationsCount=1 rate=0 maxPending=20000000</TQM-Qpid-02-1M>
+ <TQR-Qpid-01>-n TQR-Qpid-01 -d10M -s[1000] -c[8] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=false pubsub=false transacted=true commitBatchSize=100 batchSize=1000 messageSize=256 destinationCount=1 rate=0 maxPending=1000000 </TQR-Qpid-01>
+ <TQR-Qpid-02>-n TQR-Qpid-02 -d10M -s[1000] -c[8] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=false pubsub=false transacted=false commitBatchSize=100 batchSize=1000 messageSize=256 destinationCount=1 rate=0 maxPending=1000000 </TQR-Qpid-02>
+ <TQR-Qpid-03>-n TQR-Qpid-03 -d24H -s[100000] -c[8] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=false pubsub=false transacted=true commitBatchSize=100 batchSize=100000 messageSize=256 destinationCount=1 rate=0 maxPending=1000000 </TQR-Qpid-03>
+ <TQR-Qpid-04>-n TQR-Qpid-04 -d24H -s[100000] -c[8] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=false pubsub=false transacted=false commitBatchSize=100 batchSize=100000 messageSize=256 destinationCount=1 rate=0 maxPending=1000000 </TQR-Qpid-04>
+
+ <TQC-Qpid-01>-n TQC-Qpid-01 -d1M -s[1000] -c[1,30],samples=30 -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=false pubsub=false transacted=true commitBatchSize=100 batchSize=1000 messageSize=256 destinationCount=1 rate=2000 maxPending=1000000 </TQC-Qpid-01>
+ <TQC-Qpid-02>-n TQC-Qpid-02 -d1M -s[1000] -c[1,30],samples=30 -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=false pubsub=false transacted=false commitBatchSize=100 batchSize=1000 messageSize=256 destinationCount=1 rate=2000 maxPending=1000000 </TQC-Qpid-02>
+ <TQC-Qpid-03>-n TQC-Qpid-03 -d10M -s[1000] -c[10] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=false pubsub=false transacted=true commitBatchSize=100 batchSize=1000 messageSize=256 destinationCount=10 rate=0 maxPending=1000000 </TQC-Qpid-03>
+ <TQC-Qpid-04>-n TQC-Qpid-04 -d10M -s[1000] -c[10] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=false pubsub=false transacted=false commitBatchSize=100 batchSize=1000 messageSize=256 destinationCount=10 rate=0 maxPending=1000000 </TQC-Qpid-04>
+ <TQC-Qpid-05>-n TQC-Qpid-05 -d10M -s[1000] -c[100] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=false pubsub=false transacted=true commitBatchSize=100 batchSize=1000 messageSize=256 destinationCount=10 rate=0 maxPending=100000 </TQC-Qpid-05>
+ <TQC-Qpid-06>-n TQC-Qpid-06 -d10M -s[1000] -c[100] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=false pubsub=false transacted=false commitBatchSize=100 batchSize=1000 messageSize=256 destinationCount=10 rate=0 maxPending=100000 </TQC-Qpid-06>
+
+ <TQM-Qpid-01-512b>-n TQM-Qpid-01-512b -d10M -s[1000] -c[8] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=false pubsub=false transacted=true commitBatchSize=10 batchSize=1000 messageSize=512 destinationCount=1 rate=0 maxPending=20000000</TQM-Qpid-01-512b>
+ <TQM-Qpid-02-512b>-n TQM-Qpid-02-512b -d10M -s[1000] -c[8] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=false pubsub=false transacted=false commitBatchSize=10 batchSize=1000 messageSize=512 destinationCount=1 rate=0 maxPending=20000000</TQM-Qpid-02-512b>
+ <TQM-Qpid-01-1K>-n TQM-Qpid-01-1K -d10M -s[1000] -c[8] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=false pubsub=false transacted=true commitBatchSize=10 batchSize=1000 messageSize=1024 destinationCount=1 rate=0 maxPending=20000000</TQM-Qpid-01-1K>
+ <TQM-Qpid-02-1K>-n TQM-Qpid-02-1K -d10M -s[1000] -c[8] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=false pubsub=false transacted=false commitBatchSize=10 batchSize=1000 messageSize=1024 destinationCount=1 rate=0 maxPending=20000000</TQM-Qpid-02-1K>
+ <TQM-Qpid-01-5K>-n TQM-Qpid-01-5K -d10M -s[1000] -c[8] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=false pubsub=false transacted=true commitBatchSize=10 batchSize=1000 messageSize=5120 destinationCount=1 rate=0 maxPending=20000000</TQM-Qpid-01-5K>
+ <TQM-Qpid-02-5K>-n TQM-Qpid-02-5K -d10M -s[1000] -c[8] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=false pubsub=false transacted=false commitBatchSize=10 batchSize=1000 messageSize=5120 destinationCount=1 rate=0 maxPending=20000000</TQM-Qpid-02-5K>
+ <TQM-Qpid-01-10K>-n TQM-Qpid-01-10K -d10M -s[1000] -c[8] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=false pubsub=false transacted=true commitBatchSize=10 batchSize=1000 messageSize=10240 destinationCount=1 rate=0 maxPending=20000000</TQM-Qpid-01-10K>
+ <TQM-Qpid-02-10K>-n TQM-Qpid-02-10K -d10M -s[1000] -c[8] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=false pubsub=false transacted=false commitBatchSize=10 batchSize=1000 messageSize=10240 destinationCount=1 rate=0 maxPending=20000000</TQM-Qpid-02-10K>
+ <TQM-Qpid-01-50K>-n TQM-Qpid-01-50K -d10M -s[1000] -c[8] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=false pubsub=false transacted=true commitBatchSize=10 batchSize=1000 messageSize=51200 destinationCount=1 rate=0 maxPending=20000000</TQM-Qpid-01-50K>
+ <TQM-Qpid-02-50K>-n TQM-Qpid-02-50K -d10M -s[1000] -c[8] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=false pubsub=false transacted=false commitBatchSize=10 batchSize=1000 messageSize=51200 destinationCount=1 rate=0 maxPending=20000000</TQM-Qpid-02-50K>
+ <TQM-Qpid-01-100K>-n TQM-Qpid-01-100K -d10M -s[1000] -c[8] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=false pubsub=false transacted=true commitBatchSize=10 batchSize=1000 messageSize=102400 destinationCount=1 rate=0 maxPending=20000000</TQM-Qpid-01-100K>
+ <TQM-Qpid-02-100K>-n TQM-Qpid-02-100K -d10M -s[1000] -c[8] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=false pubsub=false transacted=false commitBatchSize=10 batchSize=1000 messageSize=102400 destinationCount=1 rate=0 maxPending=20000000</TQM-Qpid-02-100K>
+ <TQM-Qpid-01-500K>-n TQM-Qpid-01-500K -d10M -s[1000] -c[8] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=false pubsub=false transacted=true commitBatchSize=10 batchSize=1000 messageSize=512000 destinationCount=1 rate=0 maxPending=20000000</TQM-Qpid-01-500K>
+ <TQM-Qpid-02-500K>-n TQM-Qpid-02-500K -d10M -s[1000] -c[8] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=false pubsub=false transacted=false commitBatchSize=10 batchSize=1000 messageSize=512000 destinationCount=1 rate=0 maxPending=20000000</TQM-Qpid-02-500K>
+ <TQM-Qpid-01-1M>-n TQM-Qpid-01-1M -d10M -s[1000] -c[8] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=false pubsub=false transacted=true commitBatchSize=10 batchSize=1000 messageSize=1048576 destinationCount=1 rate=0 maxPending=20000000</TQM-Qpid-01-1M>
+ <TQM-Qpid-02-1M>-n TQM-Qpid-02-1M -d10M -s[1000] -c[8] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=false pubsub=false transacted=false commitBatchSize=10 batchSize=1000 messageSize=1048576 destinationCount=1 rate=0 maxPending=20000000</TQM-Qpid-02-1M>
<!-- Transient, Pub/Sub Tests -->
- <TTR-Qpid-01>-n TTR-Qpid-01 -d10M -s[1000] -c[8] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=false pubsub=true transacted=true commitBatchSize=100 batchSize=1000 messageSize=256 destinationsCount=1 rate=0 maxPending=1000000 </TTR-Qpid-01>
- <TTR-Qpid-02>-n TTR-Qpid-02 -d10M -s[1000] -c[8] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=false pubsub=true transacted=false commitBatchSize=100 batchSize=1000 messageSize=256 destinationsCount=1 rate=0 maxPending=1000000 </TTR-Qpid-02>
- <TTR-Qpid-03>-n TTR-Qpid-03 -d24H -s[100000] -c[8] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=false pubsub=true transacted=true commitBatchSize=100 batchSize=10000 messageSize=256 destinationsCount=1 rate=0 maxPending=1000000 </TTR-Qpid-03>
- <TTR-Qpid-04>-n TTR-Qpid-04 -d24H -s[100000] -c[8] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=false pubsub=true transacted=false commitBatchSize=100 batchSize=10000 messageSize=256 destinationsCount=1 rate=0 maxPending=1000000 </TTR-Qpid-04>
-
- <TTC-Qpid-01>-n TTC-Qpid-01 -d1M -s[1000] -c[1,30],samples=30 -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=false pubsub=true transacted=true commitBatchSize=100 batchSize=1000 messageSize=256 destinationsCount=1 rate=1000 maxPending=1000000 </TTC-Qpid-01>
- <TTC-Qpid-02>-n TTC-Qpid-02 -d1M -s[1000] -c[1,30],samples=30 -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=false pubsub=true transacted=false commitBatchSize=100 batchSize=1000 messageSize=256 destinationsCount=1 rate=1000 maxPending=1000000 </TTC-Qpid-02>
- <TTC-Qpid-03>-n TTC-Qpid-03 -d10M -s[1000] -c[10] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=false pubsub=true transacted=true commitBatchSize=100 batchSize=1000 messageSize=256 destinationsCount=10 rate=0 maxPending=1000000 </TTC-Qpid-03>
- <TTC-Qpid-04>-n TTC-Qpid-04 -d10M -s[1000] -c[10] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=false pubsub=true transacted=false commitBatchSize=100 batchSize=1000 messageSize=256 destinationsCount=10 rate=0 maxPending=1000000 </TTC-Qpid-04>
- <TTC-Qpid-05>-n TTC-Qpid-05 -d10M -s[1000] -c[100] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=false pubsub=true transacted=true commitBatchSize=100 batchSize=1000 messageSize=256 destinationsCount=10 rate=0 maxPending=100000 </TTC-Qpid-05>
- <TTC-Qpid-06>-n TTC-Qpid-06 -d10M -s[1000] -c[100] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=false pubsub=true transacted=false commitBatchSize=100 batchSize=1000 messageSize=256 destinationsCount=10 rate=0 maxPending=100000 </TTC-Qpid-06>
-
- <TTM-Qpid-01-512b>-n TTM-Qpid-01-512b -d10M -s[1000] -c[1] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=false pubsub=true transacted=true commitBatchSize=10 batchSize=1000 messageSize=512 destinationsCount=1 rate=0 maxPending=20000000</TTM-Qpid-01-512b>
- <TTM-Qpid-02-512b>-n TTM-Qpid-02-512b -d10M -s[1000] -c[1] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=false pubsub=true transacted=false commitBatchSize=10 batchSize=1000 messageSize=512 destinationsCount=1 rate=0 maxPending=20000000</TTM-Qpid-02-512b>
- <TTM-Qpid-01-1K>-n TTM-Qpid-01-1K -d10M -s[1000] -c[1] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=false pubsub=true transacted=true commitBatchSize=10 batchSize=1000 messageSize=1024 destinationsCount=1 rate=0 maxPending=20000000</TTM-Qpid-01-1K>
- <TTM-Qpid-02-1K>-n TTM-Qpid-02-1K -d10M -s[1000] -c[1] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=false pubsub=true transacted=false commitBatchSize=10 batchSize=1000 messageSize=1024 destinationsCount=1 rate=0 maxPending=20000000</TTM-Qpid-02-1K>
- <TTM-Qpid-01-5K>-n TTM-Qpid-01-5K -d10M -s[1000] -c[1] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=false pubsub=true transacted=true commitBatchSize=10 batchSize=1000 messageSize=5120 destinationsCount=1 rate=0 maxPending=20000000</TTM-Qpid-01-5K>
- <TTM-Qpid-02-5K>-n TTM-Qpid-02-5K -d10M -s[1000] -c[1] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=false pubsub=true transacted=false commitBatchSize=10 batchSize=1000 messageSize=5120 destinationsCount=1 rate=0 maxPending=20000000</TTM-Qpid-02-5K>
- <TTM-Qpid-01-10K>-n TTM-Qpid-01-10K -d10M -s[1000] -c[1] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=false pubsub=true transacted=true commitBatchSize=10 batchSize=1000 messageSize=10240 destinationsCount=1 rate=0 maxPending=20000000</TTM-Qpid-01-10K>
- <TTM-Qpid-02-10K>-n TTM-Qpid-02-10K -d10M -s[1000] -c[1] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=false pubsub=true transacted=false commitBatchSize=10 batchSize=1000 messageSize=10240 destinationsCount=1 rate=0 maxPending=20000000</TTM-Qpid-02-10K>
- <TTM-Qpid-01-50K>-n TTM-Qpid-01-50K -d10M -s[1000] -c[1] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=false pubsub=true transacted=true commitBatchSize=10 batchSize=1000 messageSize=51200 destinationsCount=1 rate=0 maxPending=20000000</TTM-Qpid-01-50K>
- <TTM-Qpid-02-50K>-n TTM-Qpid-02-50K -d10M -s[1000] -c[1] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=false pubsub=true transacted=false commitBatchSize=10 batchSize=1000 messageSize=51200 destinationsCount=1 rate=0 maxPending=20000000</TTM-Qpid-02-50K>
- <TTM-Qpid-01-100K>-n TTM-Qpid-01-100K -d10M -s[1000] -c[1] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=false pubsub=true transacted=true commitBatchSize=10 batchSize=1000 messageSize=102400 destinationsCount=1 rate=0 maxPending=20000000</TTM-Qpid-01-100K>
- <TTM-Qpid-02-100K>-n TTM-Qpid-02-100K -d10M -s[1000] -c[1] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=false pubsub=true transacted=false commitBatchSize=10 batchSize=1000 messageSize=102400 destinationsCount=1 rate=0 maxPending=20000000</TTM-Qpid-02-100K>
- <TTM-Qpid-01-500K>-n TTM-Qpid-01-500K -d10M -s[1000] -c[1] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=false pubsub=true transacted=true commitBatchSize=10 batchSize=1000 messageSize=512000 destinationsCount=1 rate=0 maxPending=20000000</TTM-Qpid-01-500K>
- <TTM-Qpid-02-500K>-n TTM-Qpid-02-500K -d10M -s[1000] -c[1] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=false pubsub=true transacted=false commitBatchSize=10 batchSize=1000 messageSize=512000 destinationsCount=1 rate=0 maxPending=20000000</TTM-Qpid-02-500K>
- <TTM-Qpid-01-1M>-n TTM-Qpid-01-1M -d10M -s[1000] -c[1] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=false pubsub=true transacted=true commitBatchSize=10 batchSize=1000 messageSize=1048576 destinationsCount=1 rate=0 maxPending=20000000</TTM-Qpid-01-1M>
- <TTM-Qpid-02-1M>-n TTM-Qpid-02-1M -d10M -s[1000] -c[1] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=false pubsub=true transacted=false commitBatchSize=10 batchSize=1000 messageSize=1048476 destinationsCount=1 rate=0 maxPending=20000000</TTM-Qpid-02-1M>
+ <TTR-Qpid-01>-n TTR-Qpid-01 -d10M -s[1000] -c[8] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=false pubsub=true transacted=true commitBatchSize=100 batchSize=1000 messageSize=256 destinationCount=1 rate=0 maxPending=1000000 </TTR-Qpid-01>
+ <TTR-Qpid-02>-n TTR-Qpid-02 -d10M -s[1000] -c[8] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=false pubsub=true transacted=false commitBatchSize=100 batchSize=1000 messageSize=256 destinationCount=1 rate=0 maxPending=1000000 </TTR-Qpid-02>
+ <TTR-Qpid-03>-n TTR-Qpid-03 -d24H -s[100000] -c[8] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=false pubsub=true transacted=true commitBatchSize=100 batchSize=10000 messageSize=256 destinationCount=1 rate=0 maxPending=1000000 </TTR-Qpid-03>
+ <TTR-Qpid-04>-n TTR-Qpid-04 -d24H -s[100000] -c[8] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=false pubsub=true transacted=false commitBatchSize=100 batchSize=10000 messageSize=256 destinationCount=1 rate=0 maxPending=1000000 </TTR-Qpid-04>
+
+ <TTC-Qpid-01>-n TTC-Qpid-01 -d1M -s[1000] -c[1,30],samples=30 -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=false pubsub=true transacted=true commitBatchSize=100 batchSize=1000 messageSize=256 destinationCount=1 rate=2000 maxPending=1000000 </TTC-Qpid-01>
+ <TTC-Qpid-02>-n TTC-Qpid-02 -d1M -s[1000] -c[1,30],samples=30 -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=false pubsub=true transacted=false commitBatchSize=100 batchSize=1000 messageSize=256 destinationCount=1 rate=2000 maxPending=1000000 </TTC-Qpid-02>
+ <TTC-Qpid-03>-n TTC-Qpid-03 -d10M -s[1000] -c[10] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=false pubsub=true transacted=true commitBatchSize=100 batchSize=1000 messageSize=256 destinationCount=10 rate=0 maxPending=1000000 </TTC-Qpid-03>
+ <TTC-Qpid-04>-n TTC-Qpid-04 -d10M -s[1000] -c[10] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=false pubsub=true transacted=false commitBatchSize=100 batchSize=1000 messageSize=256 destinationCount=10 rate=0 maxPending=1000000 </TTC-Qpid-04>
+ <TTC-Qpid-05>-n TTC-Qpid-05 -d10M -s[1000] -c[100] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=false pubsub=true transacted=true commitBatchSize=100 batchSize=1000 messageSize=256 destinationCount=10 rate=0 maxPending=100000 </TTC-Qpid-05>
+ <TTC-Qpid-06>-n TTC-Qpid-06 -d10M -s[1000] -c[100] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=false pubsub=true transacted=false commitBatchSize=100 batchSize=1000 messageSize=256 destinationCount=10 rate=0 maxPending=100000 </TTC-Qpid-06>
+
+ <TTM-Qpid-01-512b>-n TTM-Qpid-01-512b -d10M -s[1000] -c[8] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=false pubsub=true transacted=true commitBatchSize=10 batchSize=1000 messageSize=512 destinationCount=1 rate=0 maxPending=20000000</TTM-Qpid-01-512b>
+ <TTM-Qpid-02-512b>-n TTM-Qpid-02-512b -d10M -s[1000] -c[8] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=false pubsub=true transacted=false commitBatchSize=10 batchSize=1000 messageSize=512 destinationCount=1 rate=0 maxPending=20000000</TTM-Qpid-02-512b>
+ <TTM-Qpid-01-1K>-n TTM-Qpid-01-1K -d10M -s[1000] -c[8] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=false pubsub=true transacted=true commitBatchSize=10 batchSize=1000 messageSize=1024 destinationCount=1 rate=0 maxPending=20000000</TTM-Qpid-01-1K>
+ <TTM-Qpid-02-1K>-n TTM-Qpid-02-1K -d10M -s[1000] -c[8] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=false pubsub=true transacted=false commitBatchSize=10 batchSize=1000 messageSize=1024 destinationCount=1 rate=0 maxPending=20000000</TTM-Qpid-02-1K>
+ <TTM-Qpid-01-5K>-n TTM-Qpid-01-5K -d10M -s[1000] -c[8] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=false pubsub=true transacted=true commitBatchSize=10 batchSize=1000 messageSize=5120 destinationCount=1 rate=0 maxPending=20000000</TTM-Qpid-01-5K>
+ <TTM-Qpid-02-5K>-n TTM-Qpid-02-5K -d10M -s[1000] -c[8] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=false pubsub=true transacted=false commitBatchSize=10 batchSize=1000 messageSize=5120 destinationCount=1 rate=0 maxPending=20000000</TTM-Qpid-02-5K>
+ <TTM-Qpid-01-10K>-n TTM-Qpid-01-10K -d10M -s[1000] -c[8] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=false pubsub=true transacted=true commitBatchSize=10 batchSize=1000 messageSize=10240 destinationCount=1 rate=0 maxPending=20000000</TTM-Qpid-01-10K>
+ <TTM-Qpid-02-10K>-n TTM-Qpid-02-10K -d10M -s[1000] -c[8] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=false pubsub=true transacted=false commitBatchSize=10 batchSize=1000 messageSize=10240 destinationCount=1 rate=0 maxPending=20000000</TTM-Qpid-02-10K>
+ <TTM-Qpid-01-50K>-n TTM-Qpid-01-50K -d10M -s[1000] -c[8] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=false pubsub=true transacted=true commitBatchSize=10 batchSize=1000 messageSize=51200 destinationCount=1 rate=0 maxPending=20000000</TTM-Qpid-01-50K>
+ <TTM-Qpid-02-50K>-n TTM-Qpid-02-50K -d10M -s[1000] -c[8] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=false pubsub=true transacted=false commitBatchSize=10 batchSize=1000 messageSize=51200 destinationCount=1 rate=0 maxPending=20000000</TTM-Qpid-02-50K>
+ <TTM-Qpid-01-100K>-n TTM-Qpid-01-100K -d10M -s[1000] -c[8] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=false pubsub=true transacted=true commitBatchSize=10 batchSize=1000 messageSize=102400 destinationCount=1 rate=0 maxPending=20000000</TTM-Qpid-01-100K>
+ <TTM-Qpid-02-100K>-n TTM-Qpid-02-100K -d10M -s[1000] -c[8] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=false pubsub=true transacted=false commitBatchSize=10 batchSize=1000 messageSize=102400 destinationCount=1 rate=0 maxPending=20000000</TTM-Qpid-02-100K>
+ <TTM-Qpid-01-500K>-n TTM-Qpid-01-500K -d10M -s[1000] -c[8] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=false pubsub=true transacted=true commitBatchSize=10 batchSize=1000 messageSize=512000 destinationCount=1 rate=0 maxPending=20000000</TTM-Qpid-01-500K>
+ <TTM-Qpid-02-500K>-n TTM-Qpid-02-500K -d10M -s[1000] -c[8] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=false pubsub=true transacted=false commitBatchSize=10 batchSize=1000 messageSize=512000 destinationCount=1 rate=0 maxPending=20000000</TTM-Qpid-02-500K>
+ <TTM-Qpid-01-1M>-n TTM-Qpid-01-1M -d10M -s[1000] -c[8] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=false pubsub=true transacted=true commitBatchSize=10 batchSize=1000 messageSize=1048576 destinationCount=1 rate=0 maxPending=20000000</TTM-Qpid-01-1M>
+ <TTM-Qpid-02-1M>-n TTM-Qpid-02-1M -d10M -s[1000] -c[8] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=false pubsub=true transacted=false commitBatchSize=10 batchSize=1000 messageSize=1048476 destinationCount=1 rate=0 maxPending=20000000</TTM-Qpid-02-1M>
<!-- Persistent, P2P Tests -->
- <PQR-Qpid-01>-n PQR-Qpid-01 -d10M -s[1000] -c[8] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=true pubsub=false transacted=true commitBatchSize=100 batchSize=1000 messageSize=256 destinationsCount=1 rate=0 maxPending=1000000 </PQR-Qpid-01>
- <PQR-Qpid-02>-n PQR-Qpid-02 -d10M -s[1000] -c[8] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=true pubsub=false transacted=false commitBatchSize=100 batchSize=1000 messageSize=256 destinationsCount=1 rate=0 maxPending=1000000 </PQR-Qpid-02>
- <PQR-Qpid-03>-n PQR-Qpid-03 -d24H -s[100000] -c[8] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=true pubsub=false transacted=true commitBatchSize=100 batchSize=100000 messageSize=256 destinationsCount=1 rate=0 maxPending=1000000 </PQR-Qpid-03>
- <PQR-Qpid-04>-n PQR-Qpid-04 -d24H -s[100000] -c[8] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=true pubsub=false transacted=false commitBatchSize=100 batchSize=100000 messageSize=256 destinationsCount=1 rate=0 maxPending=1000000 </PQR-Qpid-04>
-
- <PQC-Qpid-01>-n PQC-Qpid-01 -d1M -s[100] -c[1,30],samples=30 -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=true pubsub=false transacted=true commitBatchSize=100 batchSize=1000 messageSize=256 destinationsCount=1 rate=300 maxPending=1000000 </PQC-Qpid-01>
- <PQC-Qpid-02>-n PQC-Qpid-02 -d1M -s[100] -c[1,30],samples=30 -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=true pubsub=false transacted=false commitBatchSize=100 batchSize=1000 messageSize=256 destinationsCount=1 rate=100 maxPending=1000000 </PQC-Qpid-02>
- <PQC-Qpid-03>-n PQC-Qpid-03 -d10M -s[1000] -c[10] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=true pubsub=false transacted=true commitBatchSize=100 batchSize=100 messageSize=256 destinationsCount=10 rate=0 maxPending=1000000 </PQC-Qpid-03>
- <PQC-Qpid-04>-n PQC-Qpid-04 -d10M -s[1000] -c[10] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=true pubsub=false transacted=false commitBatchSize=100 batchSize=1000 messageSize=256 destinationsCount=10 rate=0 maxPending=1000000 </PQC-Qpid-04>
- <PQC-Qpid-05>-n PQC-Qpid-05 -d10M -s[1000] -c[100] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=true pubsub=false transacted=true commitBatchSize=100 batchSize=1000 messageSize=256 destinationsCount=10 rate=0 maxPending=100000 </PQC-Qpid-05>
- <PQC-Qpid-06>-n PQC-Qpid-06 -d10M -s[1000] -c[100] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=true pubsub=false transacted=false commitBatchSize=100 batchSize=1000 messageSize=256 destinationsCount=10 rate=0 maxPending=100000 </PQC-Qpid-06>
-
- <PQM-Qpid-01-512b>-n PQM-Qpid-01-512b -d10M -s[1000] -c[1] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=true pubsub=false transacted=true commitBatchSize=10 batchSize=1000 messageSize=512 destinationsCount=1 rate=0 maxPending=20000000</PQM-Qpid-01-512b>
- <PQM-Qpid-02-512b>-n PQM-Qpid-02-512b -d10M -s[1000] -c[1] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=true pubsub=false transacted=false commitBatchSize=10 batchSize=1000 messageSize=512 destinationsCount=1 rate=0 maxPending=20000000</PQM-Qpid-02-512b>
- <PQM-Qpid-01-1K>-n PQM-Qpid-01-1K -d10M -s[1000] -c[1] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=true pubsub=false transacted=true commitBatchSize=10 batchSize=1000 messageSize=1024 destinationsCount=1 rate=0 maxPending=20000000</PQM-Qpid-01-1K>
- <PQM-Qpid-02-1K>-n PQM-Qpid-02-1K -d10M -s[1000] -c[1] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=true pubsub=false transacted=false commitBatchSize=10 batchSize=1000 messageSize=1024 destinationsCount=1 rate=0 maxPending=20000000</PQM-Qpid-02-1K>
- <PQM-Qpid-01-5K>-n PQM-Qpid-01-5K -d10M -s[1000] -c[1] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=true pubsub=false transacted=true commitBatchSize=10 batchSize=1000 messageSize=5120 destinationsCount=1 rate=0 maxPending=20000000</PQM-Qpid-01-5K>
- <PQM-Qpid-02-5K>-n PQM-Qpid-02-5K -d10M -s[1000] -c[1] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=true pubsub=false transacted=false commitBatchSize=10 batchSize=1000 messageSize=5120 destinationsCount=1 rate=0 maxPending=20000000</PQM-Qpid-02-5K>
- <PQM-Qpid-01-10K>-n PQM-Qpid-01-10K -d10M -s[1000] -c[1] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=true pubsub=false transacted=true commitBatchSize=10 batchSize=1000 messageSize=10240 destinationsCount=1 rate=0 maxPending=20000000</PQM-Qpid-01-10K>
- <PQM-Qpid-02-10K>-n PQM-Qpid-02-10K -d10M -s[1000] -c[1] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=true pubsub=false transacted=false commitBatchSize=10 batchSize=1000 messageSize=10240 destinationsCount=1 rate=0 maxPending=20000000</PQM-Qpid-02-10K>
- <PQM-Qpid-01-50K>-n PQM-Qpid-01-50K -d10M -s[1000] -c[1] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=true pubsub=false transacted=true commitBatchSize=10 batchSize=1000 messageSize=51200 destinationsCount=1 rate=0 maxPending=20000000</PQM-Qpid-01-50K>
- <PQM-Qpid-02-50K>-n PQM-Qpid-02-50K -d10M -s[1000] -c[1] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=true pubsub=false transacted=false commitBatchSize=10 batchSize=1000 messageSize=51200 destinationsCount=1 rate=0 maxPending=20000000</PQM-Qpid-02-50K>
- <PQM-Qpid-01-100K>-n PQM-Qpid-01-100K -d10M -s[1000] -c[1] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=true pubsub=false transacted=true commitBatchSize=10 batchSize=1000 messageSize=102400 destinationsCount=1 rate=0 maxPending=20000000</PQM-Qpid-01-100K>
- <PQM-Qpid-02-100K>-n PQM-Qpid-02-100K -d10M -s[1000] -c[1] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=true pubsub=false transacted=false commitBatchSize=10 batchSize=1000 messageSize=102400 destinationsCount=1 rate=0 maxPending=20000000</PQM-Qpid-02-100K>
- <PQM-Qpid-01-500K>-n PQM-Qpid-01-500K -d10M -s[1000] -c[1] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=true pubsub=false transacted=true commitBatchSize=10 batchSize=1000 messageSize=512000 destinationsCount=1 rate=0 maxPending=20000000</PQM-Qpid-01-500K>
- <PQM-Qpid-02-500K>-n PQM-Qpid-02-500K -d10M -s[1000] -c[1] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=true pubsub=false transacted=false commitBatchSize=10 batchSize=1000 messageSize=512000 destinationsCount=1 rate=0 maxPending=20000000</PQM-Qpid-02-500K>
- <PQM-Qpid-01-1M>-n PQM-Qpid-01-1M -d10M -s[1000] -c[1] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=true pubsub=false transacted=true commitBatchSize=10 batchSize=1000 messageSize=1048576 destinationsCount=1 rate=0 maxPending=20000000</PQM-Qpid-01-1M>
- <PQM-Qpid-02-1M>-n PQM-Qpid-02-1M -d10M -s[1000] -c[1] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=true pubsub=false transacted=false commitBatchSize=10 batchSize=1000 messageSize=1048576 destinationsCount=1 rate=0 maxPending=20000000</PQM-Qpid-02-1M>
+ <PQR-Qpid-01>-n PQR-Qpid-01 -d10M -s[1000] -c[8] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=true pubsub=false transacted=true commitBatchSize=100 batchSize=1000 messageSize=256 destinationCount=1 rate=0 maxPending=1000000 </PQR-Qpid-01>
+ <PQR-Qpid-02>-n PQR-Qpid-02 -d10M -s[1000] -c[8] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=true pubsub=false transacted=false commitBatchSize=100 batchSize=1000 messageSize=256 destinationCount=1 rate=0 maxPending=1000000 </PQR-Qpid-02>
+ <PQR-Qpid-03>-n PQR-Qpid-03 -d24H -s[100000] -c[8] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=true pubsub=false transacted=true commitBatchSize=100 batchSize=100000 messageSize=256 destinationCount=1 rate=0 maxPending=1000000 </PQR-Qpid-03>
+ <PQR-Qpid-04>-n PQR-Qpid-04 -d24H -s[100000] -c[8] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=true pubsub=false transacted=false commitBatchSize=100 batchSize=100000 messageSize=256 destinationCount=1 rate=0 maxPending=1000000 </PQR-Qpid-04>
+
+ <PQC-Qpid-01>-n PQC-Qpid-01 -d1M -s[100] -c[1,30],samples=30 -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=true pubsub=false transacted=true commitBatchSize=100 batchSize=1000 messageSize=256 destinationCount=1 rate=600 maxPending=1000000 </PQC-Qpid-01>
+ <PQC-Qpid-02>-n PQC-Qpid-02 -d1M -s[100] -c[1,30],samples=30 -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=true pubsub=false transacted=false commitBatchSize=100 batchSize=1000 messageSize=256 destinationCount=1 rate=100 maxPending=1000000 </PQC-Qpid-02>
+ <PQC-Qpid-03>-n PQC-Qpid-03 -d10M -s[1000] -c[10] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=true pubsub=false transacted=true commitBatchSize=100 batchSize=100 messageSize=256 destinationCount=10 rate=0 maxPending=1000000 </PQC-Qpid-03>
+ <PQC-Qpid-04>-n PQC-Qpid-04 -d10M -s[1000] -c[10] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=true pubsub=false transacted=false commitBatchSize=100 batchSize=1000 messageSize=256 destinationCount=10 rate=0 maxPending=1000000 </PQC-Qpid-04>
+ <PQC-Qpid-05>-n PQC-Qpid-05 -d10M -s[1000] -c[100] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=true pubsub=false transacted=true commitBatchSize=100 batchSize=1000 messageSize=256 destinationCount=10 rate=0 maxPending=100000 </PQC-Qpid-05>
+ <PQC-Qpid-06>-n PQC-Qpid-06 -d10M -s[1000] -c[100] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=true pubsub=false transacted=false commitBatchSize=100 batchSize=1000 messageSize=256 destinationCount=10 rate=0 maxPending=100000 </PQC-Qpid-06>
+
+ <PQM-Qpid-01-512b>-n PQM-Qpid-01-512b -d10M -s[1000] -c[8] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=true pubsub=false transacted=true commitBatchSize=10 batchSize=1000 messageSize=512 destinationCount=1 rate=0 maxPending=20000000</PQM-Qpid-01-512b>
+ <PQM-Qpid-02-512b>-n PQM-Qpid-02-512b -d10M -s[1000] -c[8] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=true pubsub=false transacted=false commitBatchSize=10 batchSize=1000 messageSize=512 destinationCount=1 rate=0 maxPending=20000000</PQM-Qpid-02-512b>
+ <PQM-Qpid-01-1K>-n PQM-Qpid-01-1K -d10M -s[1000] -c[8] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=true pubsub=false transacted=true commitBatchSize=10 batchSize=1000 messageSize=1024 destinationCount=1 rate=0 maxPending=20000000</PQM-Qpid-01-1K>
+ <PQM-Qpid-02-1K>-n PQM-Qpid-02-1K -d10M -s[1000] -c[8] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=true pubsub=false transacted=false commitBatchSize=10 batchSize=1000 messageSize=1024 destinationCount=1 rate=0 maxPending=20000000</PQM-Qpid-02-1K>
+ <PQM-Qpid-01-5K>-n PQM-Qpid-01-5K -d10M -s[1000] -c[8] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=true pubsub=false transacted=true commitBatchSize=10 batchSize=1000 messageSize=5120 destinationCount=1 rate=0 maxPending=20000000</PQM-Qpid-01-5K>
+ <PQM-Qpid-02-5K>-n PQM-Qpid-02-5K -d10M -s[1000] -c[8] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=true pubsub=false transacted=false commitBatchSize=10 batchSize=1000 messageSize=5120 destinationCount=1 rate=0 maxPending=20000000</PQM-Qpid-02-5K>
+ <PQM-Qpid-01-10K>-n PQM-Qpid-01-10K -d10M -s[1000] -c[8] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=true pubsub=false transacted=true commitBatchSize=10 batchSize=1000 messageSize=10240 destinationCount=1 rate=0 maxPending=20000000</PQM-Qpid-01-10K>
+ <PQM-Qpid-02-10K>-n PQM-Qpid-02-10K -d10M -s[1000] -c[8] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=true pubsub=false transacted=false commitBatchSize=10 batchSize=1000 messageSize=10240 destinationCount=1 rate=0 maxPending=20000000</PQM-Qpid-02-10K>
+ <PQM-Qpid-01-50K>-n PQM-Qpid-01-50K -d10M -s[1000] -c[8] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=true pubsub=false transacted=true commitBatchSize=10 batchSize=1000 messageSize=51200 destinationCount=1 rate=0 maxPending=20000000</PQM-Qpid-01-50K>
+ <PQM-Qpid-02-50K>-n PQM-Qpid-02-50K -d10M -s[1000] -c[8] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=true pubsub=false transacted=false commitBatchSize=10 batchSize=1000 messageSize=51200 destinationCount=1 rate=0 maxPending=20000000</PQM-Qpid-02-50K>
+ <PQM-Qpid-01-100K>-n PQM-Qpid-01-100K -d10M -s[1000] -c[8] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=true pubsub=false transacted=true commitBatchSize=10 batchSize=1000 messageSize=102400 destinationCount=1 rate=0 maxPending=20000000</PQM-Qpid-01-100K>
+ <PQM-Qpid-02-100K>-n PQM-Qpid-02-100K -d10M -s[1000] -c[8] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=true pubsub=false transacted=false commitBatchSize=10 batchSize=1000 messageSize=102400 destinationCount=1 rate=0 maxPending=20000000</PQM-Qpid-02-100K>
+ <PQM-Qpid-01-500K>-n PQM-Qpid-01-500K -d10M -s[1000] -c[8] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=true pubsub=false transacted=true commitBatchSize=10 batchSize=1000 messageSize=512000 destinationCount=1 rate=0 maxPending=20000000</PQM-Qpid-01-500K>
+ <PQM-Qpid-02-500K>-n PQM-Qpid-02-500K -d10M -s[1000] -c[8] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=true pubsub=false transacted=false commitBatchSize=10 batchSize=1000 messageSize=512000 destinationCount=1 rate=0 maxPending=20000000</PQM-Qpid-02-500K>
+ <PQM-Qpid-01-1M>-n PQM-Qpid-01-1M -d10M -s[1000] -c[8] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=true pubsub=false transacted=true commitBatchSize=10 batchSize=1000 messageSize=1048576 destinationCount=1 rate=0 maxPending=20000000</PQM-Qpid-01-1M>
+ <PQM-Qpid-02-1M>-n PQM-Qpid-02-1M -d10M -s[1000] -c[8] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=true pubsub=false transacted=false commitBatchSize=10 batchSize=1000 messageSize=1048576 destinationCount=1 rate=0 maxPending=20000000</PQM-Qpid-02-1M>
<!-- Persistent, Pub/Sub Tests -->
- <PTR-Qpid-01>-n PTR-Qpid-01 -d10M -s[1000] -c[8] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=true pubsub=true transacted=true commitBatchSize=100 batchSize=1000 messageSize=256 destinationsCount=1 rate=0 maxPending=1000000 </PTR-Qpid-01>
- <PTR-Qpid-02>-n PTR-Qpid-02 -d10M -s[1000] -c[8] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=true pubsub=true transacted=false commitBatchSize=100 batchSize=1000 messageSize=256 destinationsCount=1 rate=0 maxPending=1000000 </PTR-Qpid-02>
- <PTR-Qpid-03>-n PTR-Qpid-03 -d24H -s[100000] -c[8] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=true pubsub=true transacted=true commitBatchSize=100 batchSize=10000 messageSize=256 destinationsCount=1 rate=0 maxPending=1000000 </PTR-Qpid-03>
- <PTR-Qpid-04>-n PTR-Qpid-04 -d24H -s[100000] -c[8] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=true pubsub=true transacted=false commitBatchSize=100 batchSize=10000 messageSize=256 destinationsCount=1 rate=0 maxPending=1000000 </PTR-Qpid-04>
-
- <PTC-Qpid-01>-n PTC-Qpid-01 -d1M -s[100] -c[1,30],samples=30 -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=true pubsub=true transacted=true commitBatchSize=100 batchSize=1000 messageSize=256 destinationsCount=1 rate=300 maxPending=1000000 </PTC-Qpid-01>
- <PTC-Qpid-02>-n PTC-Qpid-02 -d1M -s[100] -c[1,30],samples=30 -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=true pubsub=true transacted=false commitBatchSize=100 batchSize=1000 messageSize=256 destinationsCount=1 rate=100 maxPending=1000000 </PTC-Qpid-02>
- <PTC-Qpid-03>-n PTC-Qpid-03 -d10M -s[1000] -c[10] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=true pubsub=true transacted=true commitBatchSize=100 batchSize=1000 messageSize=256 destinationsCount=10 rate=0 maxPending=1000000 </PTC-Qpid-03>
- <PTC-Qpid-04>-n PTC-Qpid-04 -d10M -s[1000] -c[10] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=true pubsub=true transacted=false commitBatchSize=100 batchSize=1000 messageSize=256 destinationsCount=10 rate=0 maxPending=1000000 </PTC-Qpid-04>
- <PTC-Qpid-05>-n PTC-Qpid-05 -d10M -s[1000] -c[100] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=true pubsub=true transacted=true commitBatchSize=100 batchSize=1000 messageSize=256 destinationsCount=10 rate=0 maxPending=100000 </PTC-Qpid-05>
- <PTC-Qpid-06>-n PTC-Qpid-06 -d10M -s[1000] -c[100] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=true pubsub=true transacted=false commitBatchSize=100 batchSize=1000 messageSize=256 destinationsCount=10 rate=0 maxPending=100000 </PTC-Qpid-06>
-
- <PTM-Qpid-01-512b>-n PTM-Qpid-01-512b -d10M -s[1000] -c[1] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=true pubsub=true transacted=true commitBatchSize=10 batchSize=1000 messageSize=512 destinationsCount=1 rate=0 maxPending=20000000</PTM-Qpid-01-512b>
- <PTM-Qpid-02-512b>-n PTM-Qpid-02-512b -d10M -s[1000] -c[1] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=true pubsub=true transacted=false commitBatchSize=10 batchSize=1000 messageSize=512 destinationsCount=1 rate=0 maxPending=20000000</PTM-Qpid-02-512b>
- <PTM-Qpid-01-1K>-n PTM-Qpid-01-1K -d10M -s[1000] -c[1] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=true pubsub=true transacted=true commitBatchSize=10 batchSize=1000 messageSize=1024 destinationsCount=1 rate=0 maxPending=20000000</PTM-Qpid-01-1K>
- <PTM-Qpid-02-1K>-n PTM-Qpid-02-1K -d10M -s[1000] -c[1] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=true pubsub=true transacted=false commitBatchSize=10 batchSize=1000 messageSize=1024 destinationsCount=1 rate=0 maxPending=20000000</PTM-Qpid-02-1K>
- <PTM-Qpid-01-5K>-n PTM-Qpid-01-5K -d10M -s[1000] -c[1] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=true pubsub=true transacted=true commitBatchSize=10 batchSize=1000 messageSize=5120 destinationsCount=1 rate=0 maxPending=20000000</PTM-Qpid-01-5K>
- <PTM-Qpid-02-5K>-n PTM-Qpid-02-5K -d10M -s[1000] -c[1] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=true pubsub=true transacted=false commitBatchSize=10 batchSize=1000 messageSize=5120 destinationsCount=1 rate=0 maxPending=20000000</PTM-Qpid-02-5K>
- <PTM-Qpid-01-10K>-n PTM-Qpid-01-10K -d10M -s[1000] -c[1] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=true pubsub=true transacted=true commitBatchSize=10 batchSize=1000 messageSize=10240 destinationsCount=1 rate=0 maxPending=20000000</PTM-Qpid-01-10K>
- <PTM-Qpid-02-10K>-n PTM-Qpid-02-10K -d10M -s[1000] -c[1] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=true pubsub=true transacted=false commitBatchSize=10 batchSize=1000 messageSize=10240 destinationsCount=1 rate=0 maxPending=20000000</PTM-Qpid-02-10K>
- <PTM-Qpid-01-50K>-n PTM-Qpid-01-50K -d10M -s[1000] -c[1] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=true pubsub=true transacted=true commitBatchSize=10 batchSize=1000 messageSize=51200 destinationsCount=1 rate=0 maxPending=20000000</PTM-Qpid-01-50K>
- <PTM-Qpid-02-50K>-n PTM-Qpid-02-50K -d10M -s[1000] -c[1] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=true pubsub=true transacted=false commitBatchSize=10 batchSize=1000 messageSize=51200 destinationsCount=1 rate=0 maxPending=20000000</PTM-Qpid-02-50K>
- <PTM-Qpid-01-100K>-n PTM-Qpid-01-100K -d10M -s[1000] -c[1] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=true pubsub=true transacted=true commitBatchSize=10 batchSize=1000 messageSize=102400 destinationsCount=1 rate=0 maxPending=20000000</PTM-Qpid-01-100K>
- <PTM-Qpid-02-100K>-n PTM-Qpid-02-100K -d10M -s[1000] -c[1] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=true pubsub=true transacted=false commitBatchSize=10 batchSize=1000 messageSize=102400 destinationsCount=1 rate=0 maxPending=20000000</PTM-Qpid-02-100K>
- <PTM-Qpid-01-500K>-n PTM-Qpid-01-500K -d10M -s[1000] -c[1] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=true pubsub=true transacted=true commitBatchSize=10 batchSize=1000 messageSize=512000 destinationsCount=1 rate=0 maxPending=20000000</PTM-Qpid-01-500K>
- <PTM-Qpid-02-500K>-n PTM-Qpid-02-500K -d10M -s[1000] -c[1] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=true pubsub=true transacted=false commitBatchSize=10 batchSize=1000 messageSize=512000 destinationsCount=1 rate=0 maxPending=20000000</PTM-Qpid-02-500K>
- <PTM-Qpid-01-1M>-n PTM-Qpid-01-1M -d10M -s[1000] -c[1] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=true pubsub=true transacted=true commitBatchSize=10 batchSize=1000 messageSize=1048576 destinationsCount=1 rate=0 maxPending=20000000</PTM-Qpid-01-1M>
- <PTM-Qpid-02-1M>-n PTM-Qpid-02-1M -d10M -s[1000] -c[1] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=true pubsub=true transacted=false commitBatchSize=10 batchSize=1000 messageSize=1048476 destinationsCount=1 rate=0 maxPending=20000000</PTM-Qpid-02-1M>
+ <PTR-Qpid-01>-n PTR-Qpid-01 -d10M -s[1000] -c[8] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=true pubsub=true transacted=true commitBatchSize=100 batchSize=1000 messageSize=256 destinationCount=1 rate=0 maxPending=1000000 </PTR-Qpid-01>
+ <PTR-Qpid-02>-n PTR-Qpid-02 -d10M -s[1000] -c[8] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=true pubsub=true transacted=false commitBatchSize=100 batchSize=1000 messageSize=256 destinationCount=1 rate=0 maxPending=1000000 </PTR-Qpid-02>
+ <PTR-Qpid-03>-n PTR-Qpid-03 -d24H -s[100000] -c[8] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=true pubsub=true transacted=true commitBatchSize=100 batchSize=10000 messageSize=256 destinationCount=1 rate=0 maxPending=1000000 </PTR-Qpid-03>
+ <PTR-Qpid-04>-n PTR-Qpid-04 -d24H -s[100000] -c[8] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=true pubsub=true transacted=false commitBatchSize=100 batchSize=10000 messageSize=256 destinationCount=1 rate=0 maxPending=1000000 </PTR-Qpid-04>
+
+ <PTC-Qpid-01>-n PTC-Qpid-01 -d1M -s[100] -c[1,30],samples=30 -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=true pubsub=true transacted=true commitBatchSize=100 batchSize=1000 messageSize=256 destinationCount=1 rate=600 maxPending=1000000 </PTC-Qpid-01>
+ <PTC-Qpid-02>-n PTC-Qpid-02 -d1M -s[100] -c[1,30],samples=30 -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=true pubsub=true transacted=false commitBatchSize=100 batchSize=1000 messageSize=256 destinationCount=1 rate=100 maxPending=1000000 </PTC-Qpid-02>
+ <PTC-Qpid-03>-n PTC-Qpid-03 -d10M -s[1000] -c[10] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=true pubsub=true transacted=true commitBatchSize=100 batchSize=1000 messageSize=256 destinationCount=10 rate=0 maxPending=1000000 </PTC-Qpid-03>
+ <PTC-Qpid-04>-n PTC-Qpid-04 -d10M -s[1000] -c[10] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=true pubsub=true transacted=false commitBatchSize=100 batchSize=1000 messageSize=256 destinationCount=10 rate=0 maxPending=1000000 </PTC-Qpid-04>
+ <PTC-Qpid-05>-n PTC-Qpid-05 -d10M -s[1000] -c[100] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=true pubsub=true transacted=true commitBatchSize=100 batchSize=1000 messageSize=256 destinationCount=10 rate=0 maxPending=100000 </PTC-Qpid-05>
+ <PTC-Qpid-06>-n PTC-Qpid-06 -d10M -s[1000] -c[100] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=true pubsub=true transacted=false commitBatchSize=100 batchSize=1000 messageSize=256 destinationCount=10 rate=0 maxPending=100000 </PTC-Qpid-06>
+
+ <PTM-Qpid-01-512b>-n PTM-Qpid-01-512b -d10M -s[1000] -c[8] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=true pubsub=true transacted=true commitBatchSize=10 batchSize=1000 messageSize=512 destinationCount=1 rate=0 maxPending=20000000</PTM-Qpid-01-512b>
+ <PTM-Qpid-02-512b>-n PTM-Qpid-02-512b -d10M -s[1000] -c[8] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=true pubsub=true transacted=false commitBatchSize=10 batchSize=1000 messageSize=512 destinationCount=1 rate=0 maxPending=20000000</PTM-Qpid-02-512b>
+ <PTM-Qpid-01-1K>-n PTM-Qpid-01-1K -d10M -s[1000] -c[8] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=true pubsub=true transacted=true commitBatchSize=10 batchSize=1000 messageSize=1024 destinationCount=1 rate=0 maxPending=20000000</PTM-Qpid-01-1K>
+ <PTM-Qpid-02-1K>-n PTM-Qpid-02-1K -d10M -s[1000] -c[8] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=true pubsub=true transacted=false commitBatchSize=10 batchSize=1000 messageSize=1024 destinationCount=1 rate=0 maxPending=20000000</PTM-Qpid-02-1K>
+ <PTM-Qpid-01-5K>-n PTM-Qpid-01-5K -d10M -s[1000] -c[8] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=true pubsub=true transacted=true commitBatchSize=10 batchSize=1000 messageSize=5120 destinationCount=1 rate=0 maxPending=20000000</PTM-Qpid-01-5K>
+ <PTM-Qpid-02-5K>-n PTM-Qpid-02-5K -d10M -s[1000] -c[8] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=true pubsub=true transacted=false commitBatchSize=10 batchSize=1000 messageSize=5120 destinationCount=1 rate=0 maxPending=20000000</PTM-Qpid-02-5K>
+ <PTM-Qpid-01-10K>-n PTM-Qpid-01-10K -d10M -s[1000] -c[8] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=true pubsub=true transacted=true commitBatchSize=10 batchSize=1000 messageSize=10240 destinationCount=1 rate=0 maxPending=20000000</PTM-Qpid-01-10K>
+ <PTM-Qpid-02-10K>-n PTM-Qpid-02-10K -d10M -s[1000] -c[8] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=true pubsub=true transacted=false commitBatchSize=10 batchSize=1000 messageSize=10240 destinationCount=1 rate=0 maxPending=20000000</PTM-Qpid-02-10K>
+ <PTM-Qpid-01-50K>-n PTM-Qpid-01-50K -d10M -s[1000] -c[8] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=true pubsub=true transacted=true commitBatchSize=10 batchSize=1000 messageSize=51200 destinationCount=1 rate=0 maxPending=20000000</PTM-Qpid-01-50K>
+ <PTM-Qpid-02-50K>-n PTM-Qpid-02-50K -d10M -s[1000] -c[8] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=true pubsub=true transacted=false commitBatchSize=10 batchSize=1000 messageSize=51200 destinationCount=1 rate=0 maxPending=20000000</PTM-Qpid-02-50K>
+ <PTM-Qpid-01-100K>-n PTM-Qpid-01-100K -d10M -s[1000] -c[8] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=true pubsub=true transacted=true commitBatchSize=10 batchSize=1000 messageSize=102400 destinationCount=1 rate=0 maxPending=20000000</PTM-Qpid-01-100K>
+ <PTM-Qpid-02-100K>-n PTM-Qpid-02-100K -d10M -s[1000] -c[8] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=true pubsub=true transacted=false commitBatchSize=10 batchSize=1000 messageSize=102400 destinationCount=1 rate=0 maxPending=20000000</PTM-Qpid-02-100K>
+ <PTM-Qpid-01-500K>-n PTM-Qpid-01-500K -d10M -s[1000] -c[8] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=true pubsub=true transacted=true commitBatchSize=10 batchSize=1000 messageSize=512000 destinationCount=1 rate=0 maxPending=20000000</PTM-Qpid-01-500K>
+ <PTM-Qpid-02-500K>-n PTM-Qpid-02-500K -d10M -s[1000] -c[8] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=true pubsub=true transacted=false commitBatchSize=10 batchSize=1000 messageSize=512000 destinationCount=1 rate=0 maxPending=20000000</PTM-Qpid-02-500K>
+ <PTM-Qpid-01-1M>-n PTM-Qpid-01-1M -d10M -s[1000] -c[8] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=true pubsub=true transacted=true commitBatchSize=10 batchSize=1000 messageSize=1048576 destinationCount=1 rate=0 maxPending=20000000</PTM-Qpid-01-1M>
+ <PTM-Qpid-02-1M>-n PTM-Qpid-02-1M -d10M -s[1000] -c[8] -o $QPID_WORK/results -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf persistent=true pubsub=true transacted=false commitBatchSize=10 batchSize=1000 messageSize=1048476 destinationCount=1 rate=0 maxPending=20000000</PTM-Qpid-02-1M>
<!-- Failover Tests. -->
<FT-Qpid-01>-n FT-Qpid-01 -s[250000] -t testAsyncPingOk org.apache.qpid.ping.PingAsyncTestPerf messageSize=256 batchSize=10000 transacted=true broker="tcp://127.0.0.1:5001;tcp://127.0.0.1:5002" failBeforeSend=true -o $QPID_WORK/results</FT-Qpid-01>
diff --git a/java/perftests/src/main/java/org/apache/qpid/client/message/TestMessageFactory.java b/java/perftests/src/main/java/org/apache/qpid/client/message/TestMessageFactory.java
index eeb4021f34..64ccb719b6 100644
--- a/java/perftests/src/main/java/org/apache/qpid/client/message/TestMessageFactory.java
+++ b/java/perftests/src/main/java/org/apache/qpid/client/message/TestMessageFactory.java
@@ -1,18 +1,21 @@
/*
*
- * Copyright (c) 2006 The Apache Software Foundation
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
*
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
+ * http://www.apache.org/licenses/LICENSE-2.0
*
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
*
*/
package org.apache.qpid.client.message;
diff --git a/java/perftests/src/main/java/org/apache/qpid/ping/PingDurableClient.java b/java/perftests/src/main/java/org/apache/qpid/ping/PingDurableClient.java
index 2765986868..c5f71b4774 100644
--- a/java/perftests/src/main/java/org/apache/qpid/ping/PingDurableClient.java
+++ b/java/perftests/src/main/java/org/apache/qpid/ping/PingDurableClient.java
@@ -20,18 +20,6 @@
*/
package org.apache.qpid.ping;
-import java.io.BufferedReader;
-import java.io.IOException;
-import java.io.InputStreamReader;
-import java.util.List;
-import java.util.Properties;
-import java.util.concurrent.atomic.AtomicInteger;
-
-import javax.jms.Destination;
-import javax.jms.ExceptionListener;
-import javax.jms.JMSException;
-import javax.jms.Message;
-
import org.apache.log4j.Logger;
import org.apache.qpid.requestreply.PingPongProducer;
@@ -40,6 +28,18 @@ import org.apache.qpid.util.CommandLineParser;
import uk.co.thebadgerset.junit.extensions.util.MathUtils;
import uk.co.thebadgerset.junit.extensions.util.ParsedProperties;
+import javax.jms.Destination;
+import javax.jms.ExceptionListener;
+import javax.jms.JMSException;
+import javax.jms.Message;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.util.List;
+import java.util.Properties;
+import java.util.concurrent.atomic.AtomicInteger;
+
/**
* PingDurableClient is a variation of the {@link PingPongProducer} ping tool. Instead of sending its pings and
* receiving replies to them at the same time, this tool sends pings until it is signalled by some 'event' to stop
@@ -167,7 +167,8 @@ public class PingDurableClient extends PingPongProducer implements ExceptionList
try
{
// Create a ping producer overriding its defaults with all options passed on the command line.
- Properties options = CommandLineParser.processCommandLine(args, new CommandLineParser(new String[][] {}));
+ Properties options =
+ CommandLineParser.processCommandLine(args, new CommandLineParser(new String[][] {}), System.getProperties());
PingDurableClient pingProducer = new PingDurableClient(options);
// Create a shutdown hook to terminate the ping-pong producer.
diff --git a/java/perftests/src/main/java/org/apache/qpid/ping/PingSendOnlyClient.java b/java/perftests/src/main/java/org/apache/qpid/ping/PingSendOnlyClient.java
index bbe337ca0a..2879f0c322 100644
--- a/java/perftests/src/main/java/org/apache/qpid/ping/PingSendOnlyClient.java
+++ b/java/perftests/src/main/java/org/apache/qpid/ping/PingSendOnlyClient.java
@@ -57,7 +57,7 @@ public class PingSendOnlyClient extends PingDurableClient
try
{
// Create a ping producer overriding its defaults with all options passed on the command line.
- Properties options = CommandLineParser.processCommandLine(args, new CommandLineParser(new String[][] {}));
+ Properties options = CommandLineParser.processCommandLine(args, new CommandLineParser(new String[][] {}), System.getProperties());
PingSendOnlyClient pingProducer = new PingSendOnlyClient(options);
// Create a shutdown hook to terminate the ping-pong producer.
diff --git a/java/perftests/src/main/java/org/apache/qpid/requestreply/PingPongProducer.java b/java/perftests/src/main/java/org/apache/qpid/requestreply/PingPongProducer.java
index d5d1c304e9..03f5f0549d 100644
--- a/java/perftests/src/main/java/org/apache/qpid/requestreply/PingPongProducer.java
+++ b/java/perftests/src/main/java/org/apache/qpid/requestreply/PingPongProducer.java
@@ -20,20 +20,6 @@
*/
package org.apache.qpid.requestreply;
-import java.io.IOException;
-import java.net.InetAddress;
-import java.text.DateFormat;
-import java.text.SimpleDateFormat;
-import java.util.*;
-import java.util.concurrent.BrokenBarrierException;
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.CyclicBarrier;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.atomic.AtomicInteger;
-import java.util.concurrent.atomic.AtomicLong;
-
-import javax.jms.*;
-
import org.apache.log4j.Logger;
import org.apache.qpid.AMQException;
@@ -51,6 +37,18 @@ import uk.co.thebadgerset.junit.extensions.BatchedThrottle;
import uk.co.thebadgerset.junit.extensions.Throttle;
import uk.co.thebadgerset.junit.extensions.util.ParsedProperties;
+import javax.jms.*;
+
+import java.io.IOException;
+import java.net.InetAddress;
+import java.text.DateFormat;
+import java.text.SimpleDateFormat;
+import java.util.*;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicInteger;
+import java.util.concurrent.atomic.AtomicLong;
+
/**
* PingPongProducer is a client that sends test messages, and waits for replies to these messages. The replies may
* either be generated by another client (see {@link PingPongBouncer}, or an extension of it may be used that listens
@@ -89,7 +87,7 @@ import uk.co.thebadgerset.junit.extensions.util.ParsedProperties;
* <tr><td> destinationCount <td> 1 <td> The number of receivers listening to the pings.
* <tr><td> timeout <td> 30000 <td> In milliseconds. The timeout to stop waiting for replies.
* <tr><td> commitBatchSize <td> 1 <td> The number of messages per transaction in transactional mode.
- * <tr><td> uniqueDests <td> true <td> Whether each receiver only listens to one ping destination or all.
+ * <tr><td> uniqueDests <td> true <td> Whether each receivers only listens to one ping destination or all.
* <tr><td> durableDests <td> false <td> Whether or not durable destinations are used.
* <tr><td> ackMode <td> AUTO_ACK <td> The message acknowledgement mode. Possible values are:
* 0 - SESSION_TRANSACTED
@@ -237,7 +235,7 @@ public class PingPongProducer implements Runnable, MessageListener, ExceptionLis
/** Holds the default message selector. */
public static final String SELECTOR_DEFAULT = "";
- /** Holds the name of the proeprty to get the destination count from. */
+ /** Holds the name of the property to get the destination count from. */
public static final String DESTINATION_COUNT_PROPNAME = "destinationCount";
/** Defines the default number of destinations to ping. */
@@ -373,7 +371,7 @@ public class PingPongProducer implements Runnable, MessageListener, ExceptionLis
protected int _maxPendingSize;
/**
- * Holds a monitor which is used to synchronize sender and receiver threads, where the sender has elected
+ * Holds a monitor which is used to synchronize sender and receivers threads, where the sender has elected
* to wait until the number of unreceived message is reduced before continuing to send.
*/
protected Object _sendPauseMonitor = new Object();
@@ -570,7 +568,8 @@ public class PingPongProducer implements Runnable, MessageListener, ExceptionLis
{
try
{
- Properties options = CommandLineParser.processCommandLine(args, new CommandLineParser(new String[][] {}));
+ Properties options =
+ CommandLineParser.processCommandLine(args, new CommandLineParser(new String[][] {}), System.getProperties());
// Create a ping producer overriding its defaults with all options passed on the command line.
PingPongProducer pingProducer = new PingPongProducer(options);
diff --git a/java/pom.xml b/java/pom.xml
index 87ed34846f..f6f719eb80 100644
--- a/java/pom.xml
+++ b/java/pom.xml
@@ -155,14 +155,26 @@ under the License.
<module>perftests</module>
<module>integrationtests</module>
<module>management/eclipse-plugin</module>
- <module>client/example</module>
- <module>client-java14</module>
+ <module>client/example</module>
+ <module>client-java14</module>
</modules>
<build>
<resources>
+
+ <resource>
+ <targetPath>META-INF/</targetPath>
+ <filtering>false</filtering>
+ <directory>../resources</directory>
+ <includes>
+ <include>DISCLAIMER</include>
+ <include>LICENSE</include>
+ <include>NOTICE</include>
+ </includes>
+ </resource>
+
<resource>
<directory>src/main/java</directory>
<excludes>
@@ -172,26 +184,28 @@ under the License.
</resource>
<resource>
<directory>src/main/resources</directory>
- <includes>
- <include>**</include>
- </includes>
</resource>
<resource>
<directory>src/main/resources-filtered</directory>
- <includes>
- <include>**</include>
- </includes>
<filtering>true</filtering>
</resource>
<resource>
<directory>target/generated/src/main/resources</directory>
- <includes>
- <include>**</include>
- </includes>
</resource>
</resources>
<testResources>
+ <testResource>
+ <targetPath>META-INF/</targetPath>
+ <filtering>false</filtering>
+ <directory>../resources</directory>
+ <includes>
+ <include>DISCLAIMER</include>
+ <include>LICENSE</include>
+ <include>NOTICE</include>
+ </includes>
+ </testResource>
+
<testResource>
<directory>src/test/java</directory>
<excludes>
@@ -200,9 +214,6 @@ under the License.
</testResource>
<testResource>
<directory>src/test/resources</directory>
- <includes>
- <include>**</include>
- </includes>
</testResource>
<testResource>
<directory>src/test/java</directory>
@@ -391,7 +402,19 @@ under the License.
<version>0.5</version>
</plugin>
- <plugin>
+
+
+
+ </plugins>
+ </pluginManagement>
+
+
+ <plugins>
+
+ <!-- Disabled as plugin crashes on the systest module.
+ Also, the resulting NOTICE file doesn't include all license info due to missing data in dependant poms.
+
+ <plugin>
<artifactId>maven-remote-resources-plugin</artifactId>
<version>1.0-alpha-5</version>
<executions>
@@ -411,11 +434,8 @@ under the License.
</configuration>
</execution>
</executions>
- </plugin>
-
-
- </plugins>
- </pluginManagement>
+ </plugin-->
+ </plugins>
<defaultGoal>install</defaultGoal>
@@ -586,7 +606,6 @@ under the License.
-->
<!-- Run the javadoc report. -->
- <!--
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
@@ -600,7 +619,6 @@ under the License.
</tags>
</configuration>
</plugin>
- -->
<!-- Generate the clover coverage report. -->
<!--
diff --git a/java/release-docs/RELEASE_NOTES.txt b/java/release-docs/RELEASE_NOTES.txt
index 638f4c6f61..811bc4f4c0 100644
--- a/java/release-docs/RELEASE_NOTES.txt
+++ b/java/release-docs/RELEASE_NOTES.txt
@@ -1,8 +1,9 @@
-Apache Incubator Qpid Java M1 Release Notes
+Apache Incubator Qpid Java M2 Release Notes
-------------------------------------------
-The Qpid M1 release is intended to serve as a useful baseline release
-for the project, allowing interested users to use the current featureset.
+The Qpid M2 release contains support the for AMQP 0-8 specification.
+You can access the 0-8 specification using the following link.
+http://www.amqp.org/tikiwiki/tiki-index.php?page=Download
For full details of Qpid capabilities, as they currently stand, see our
detailed project documentation at:
@@ -17,58 +18,88 @@ Known Issues/OUtstanding Work
-----------------------------
You can view the outstanding task list for Qpid by visiting our JIRA:
-
http://issues.apache.org/jira/browse/QPID
+These issues are moved to M3 release.
-M1 Tasks Completed
--------------------
-
-The set of JIRA tasks completed as part of the M1 effort is available at:
-
-http://cwiki.apache.org/confluence/display/qpid/Qpid+Java+M1+Release+Notes
-
-This list is copied below for convenience:
-
-Bugs
-----
-http://issues.apache.org/jira/browse/QPID-4 - Remove '/' and ':' from generated queue names
-http://issues.apache.org/jira/browse/QPID-7 - Occasionally messages are ack'd more than once
-http://issues.apache.org/jira/browse/QPID-10- Broker throughput falls off with transactions
-http://issues.apache.org/jira/browse/QPID-56 - AMQQueueMBean - MessageCount on the management interface is not correct.
-http://issues.apache.org/jira/browse/QPID-58 - Creating a QueueReceiver results in ClassCastException
-http://issues.apache.org/jira/browse/QPID-66 - AMQSession implementation of TopicSession and QueueSession interfaces not JMS compliant
-http://issues.apache.org/jira/browse/QPID-68 - Ant build system fails if the project path contains a space
-http://issues.apache.org/jira/browse/QPID-69 - Race condition in Delivery Manager
-
-Improvements
-------------
-http://issues.apache.org/jira/browse/QPID-36 - Add high and low watermark to flow control
-http://issues.apache.org/jira/browse/QPID-44 - Add high and low watermark to flow control
-http://issues.apache.org/jira/browse/QPID-57 - AMQQueueMBean - Message header attributes should be sent along with message content.
-
-
-New Features
-------------
-http://issues.apache.org/jira/browse/QPID-13 - Add option to include prefix and suffix in log file name for broker
-http://issues.apache.org/jira/browse/QPID-23 - Extend JNDI support provided to include initial context factory
-http://issues.apache.org/jira/browse/QPID-29 - Provide support for using Qpid JMX with Tivoli for application monitoring
-http://issues.apache.org/jira/browse/QPID-30 - Allow configuration of working/log directories written to by broker
-http://issues.apache.org/jira/browse/QPID-40 - Implement tx.select, tx.commit & tx.rollback from AMQP
-
-
-Tasks
------
-http://issues.apache.org/jira/browse/QPID-18 - Update Java client and broker to MINA 1.0 release
-http://issues.apache.org/jira/browse/QPID-73 - Create Build Artifacts for release process using ant/maven
-http://issues.apache.org/jira/browse/QPID-74 - Create source distribtuion using build system
-http://issues.apache.org/jira/browse/QPID-75 - Create Standard Binary distribution using build system
-
-
+Here is a filtered list for your convinience
+---------------------------------------
+New Feature QPID-274 add connection configuratble timeout on waituntilStateHasChanged
+New Feature QPID-156 Implement persistence to disk for Qpid
+New Feature QPID-155 Add ability to configure (on/off) queue creation on demand
+New Feature QPID-43 Multiple-AMQP version support in the broker
+New Feature QPID-28 Allow user to select policy for undeliverable message handling
+New Feature QPID-27 Introduce user configurable redlivery delay
+New Feature QPID-22 Provide run scripts for clustered broker
+Improvement QPID-430 Message Age Alerting should not depend upon queue activity
+Improvement QPID-19 Add protocol logging capability to client and broker
+Improvement QPID-11 Move protocol literals from code to AMQConstant
+Bug QPID-539 HeadersExchange doesnot correctly implement isBound
+Bug QPID-517 Broker doesn't return NO_CONSUMERS code for an immediate message, when the consumer is disconnected.
+Bug QPID-469 Redelivered information is currently recorded per message it should be per message per queue.
+Bug QPID-463 Java client doesn't close connection gracefully when faced with broker with unsuported protocol version
+Bug QPID-462 Exclusive queues and with subscription that 'filtersMessages' will build up messages it doesn't hasInterest() in.
+Bug QPID-397 Client closeure can be processed before final message ack.
+Bug QPID-396 Broker OutOfMemory Error handling
+Bug QPID-377 NumberFormatException thrown by broker when running one performance test
+Bug QPID-293 setting MessageListener after connection has started can cause messages to be "lost" on a internal delivery queue.
+Bug QPID-185 Amend Java Broker handling of ifUnused & ifEmpty flags
+Bug QPID-168 qpid-server.bat needs updated to support same arguments/features as qpid-server (via qpid-run) bash script
+M2 Tasks Completed
+-------------------
+The set of JIRA tasks completed as part of the M2 effort is available at:
+https://issues.apache.org/jira/secure/ReleaseNote.jspa?projectId=12310520&styleName=Html&version=12312116
+
+
+Here is a filtered (by Java components) version of the JIRA items
+
+Task QPID-190 refactoring the java broker mbean classes
+Task QPID-125 Moving eclipse plugin for broker management to Maven
+Task QPID-93 Delete the old management modules (trunk\qpid\java\management)
+
+New Feature QPID-428 Add login functionality for a qpid server from the management console
+New Feature QPID-418 Add ability to save user preferences to Java Management Console
+New Feature QPID-170 Enhance Management features to support moving a message from one queue to another
+
+Improvement QPID-482 [Java] Small performance tweaks
+Improvement QPID-466 Create STRICT_AMQP System property to disable JMS extensions in Java client
+Improvement QPID-453 AMQShortString should implement Comparable
+Improvement QPID-422 Consolidate notification view to display all user configured notifications on one view
+Improvement QPID-421 Provide enumerated description for static constants including delivery mode
+Improvement QPID-420 Add client id to information displayed about connections on management console
+Improvement QPID-419 Introduce read-only and modify authorisation for all objects in a virtual host
+Improvement QPID-129 improving Broker MBeans
+
+Bug QPID-540 Transient Broker throws NullPointerException and locks up.
+Bug QPID-538 [Memory Leak] Connecting lots of consumers causes the broker memory to leak
+Bug QPID-537 Make AMQMessage.incrementReference public
+Bug QPID-531 [Memory Leak] Broker retains messages that are consumed with NO_ACK
+Bug QPID-527 encoding issue
+Bug QPID-508 [Memory Leak] Broker does not return mandatory messages sent outside of a transaction.
+Bug QPID-476 AMQProtocolSession channelId2SessionMap does not have sessions removed
+Bug QPID-472 Creation of TemporaryQueues will not guarantee unqiue queue names if created rapidly.
+Bug QPID-471 UserManagement panel lists all users but only after a View Users has been executed and is not updated on Create/Delete User
+
+Bug QPID-467 Complete Interop Testing
+Bug QPID-465 Incorrect Exception thrown from send() method.
+Bug QPID-459 Broker doesn't correctly handle noLocal consumers when messages are pre-exisiting on queues.
+Bug QPID-458 Queue Browsing Broken
+Bug QPID-454 Message 'taken' notion is per message. But should be per message per queue
+Bug QPID-443 Abruptly disconnecting client on transaction publish causes error
+Bug QPID-440 Can create dangling transactions on unroutable messages.
+Bug QPID-436 topic exchange doesn't obey the mandatory flag
+Bug QPID-414 Authentication requires plain text passwords in password file
+Bug QPID-408 Queue Depth data incorrect
+Bug QPID-290 Java broker does not honor maximum number of channels threshold
+Bug QPID-276 Potential race condition in AMQChannel
+Bug QPID-200 set/get Destination not implemented in JMSMessage impl
+Bug QPID-166 Check for pre conditions to satisfy JMS spec requirments
+Bug QPID-162 over 600 warnings when building under Eclipse
+Bug QPID-159 The following Interface implementations do not throw Exceptions as required by the spec
diff --git a/java/distribution/src/main/release/LICENSE.txt b/java/resources/LICENSE
index 6b0b1270ff..6b0b1270ff 100755..100644
--- a/java/distribution/src/main/release/LICENSE.txt
+++ b/java/resources/LICENSE
diff --git a/java/resources/META-INF/DISCLAIMER b/java/resources/META-INF/DISCLAIMER
new file mode 100644
index 0000000000..1ca63e46e2
--- /dev/null
+++ b/java/resources/META-INF/DISCLAIMER
@@ -0,0 +1,10 @@
+Apache Qpid is an effort undergoing incubation at the Apache Software
+Foundation (ASF), sponsored by the Apache Incubator PMC.
+
+Incubation is required of all newly accepted projects until a further review
+indicates that the infrastructure, communications, and decision making process
+have stabilized in a manner consistent with other successful ASF projects.
+
+While incubation status is not necessarily a reflection of the completeness
+or stability of the code, it does indicate that the project has yet to be
+fully endorsed by the ASF.
diff --git a/java/resources/META-INF/DISCLAIMER.txt b/java/resources/META-INF/DISCLAIMER.txt
deleted file mode 100644
index d33c54a807..0000000000
--- a/java/resources/META-INF/DISCLAIMER.txt
+++ /dev/null
@@ -1,7 +0,0 @@
-Qpid is an effort undergoing incubation at the Apache Software Foundation
-(ASF). Incubation is required of all newly accepted projects until a further
-review indicates that the infrastructure, communications, and decision making
-process have stabilized in a manner consistent with other successful ASF
-projects. While incubation status is not necessarily a reflection of the
-completeness or stability of the code, it does indicate that the project
-has yet to be fully endorsed by the ASF. \ No newline at end of file
diff --git a/java/resources/LICENSE.txt b/java/resources/META-INF/LICENSE
index 6b0b1270ff..6b0b1270ff 100755..100644
--- a/java/resources/LICENSE.txt
+++ b/java/resources/META-INF/LICENSE
diff --git a/java/resources/META-INF/NOTICE b/java/resources/META-INF/NOTICE
new file mode 100644
index 0000000000..f62ec14896
--- /dev/null
+++ b/java/resources/META-INF/NOTICE
@@ -0,0 +1,105 @@
+// ------------------------------------------------------------------
+// NOTICE file corresponding to the section 4d of The Apache License,
+// Version 2.0, in this case for Qpid Common Utilities
+// ------------------------------------------------------------------
+
+Apache Qpid
+Copyright 2006-2007 Apache Software Foundation
+
+This product includes software developed at
+Apache Software Foundation (http://www.apache.org/)
+License: Apache 2.0 License (http://www.apache.org/licenses/LICENSE-2.0)
+
+This product includes/uses software, Unnamed - relaxngDatatype:relaxngDatatype:jar:20020414 (http://sourceforge.net/projects/relaxng)
+License: BSD License (http://www.opensource.org/licenses/bsd-license.php)
+
+This product includes/uses software, Apache MINA Core API (http://directory.apache.org/projects/mina/)
+License: Apache 2.0 License (http://www.apache.org/licenses/LICENSE-2.0)
+
+This product includes/uses software, Unnamed - isorelax:isorelax:jar:20020414
+License: MIT license (http://www.opensource.org/licenses/mit-license.html)
+
+This product includes/uses software, SLF4J API Module (http://www.slf4j.org),
+developed by QOS.ch (http://www.qos.ch)
+License: MIT License (http://www.slf4j.org/license.html)
+
+This product includes/uses software, Commons Collections - commons-collections:commons-collections:jar:3.1,
+developed by Apache Software Foundation (http://www.apache.org)
+License: Apache 2.0 License (http://www.apache.org/licenses/LICENSE-2.0)
+
+This product includes/uses software, Commons Digester - commons-digester:commons-digester:jar:1.6
+developed by Apache Software Foundation (http://www.apache.org)
+License: Apache 2.0 License (http://www.apache.org/licenses/LICENSE-2.0)
+
+This product includes/uses software, Commons CLI - commons-cli:commons-cli:jar:1.0
+Ideveloped by Apache Software Foundation (http://www.apache.org)
+License: Apache 2.0 License (http://www.apache.org/licenses/LICENSE-2.0)
+
+This product includes/uses software, Unnamed - msv:msv:jar:20020414
+developed by (https://msv.dev.java.net/)
+License:
+
+This product includes/uses software, Codec (http://jakarta.apache.org/commons/codec/),
+developed by The Apache Software Foundation (http://jakarta.apache.org)
+License: The Apache Software License, Version 2.0 (http://www.apache.org/licenses/LICENSE-2.0)
+
+This product includes/uses software, Commons Logging - commons-logging:commons-logging:jar:1.0
+developed by Apache Software Foundation (http://www.apache.org)
+License: Apache 2.0 License (http://www.apache.org/licenses/LICENSE-2.0)
+
+This product includes/uses software, Backport of JSR 166 (http://www.mathcs.emory.edu/dcl/util/backport-util-concurrent/),
+developed by Dawid Kurzyniec (http://www.mathcs.emory.edu/~dawidk/)
+License: Public Domain (http://creativecommons.org/licenses/publicdomain)
+
+This product includes/uses software, Commons Lang - commons-lang:commons-lang:jar:2.1
+developed by Apache Software Foundation (http://www.apache.org)
+License: Apache 2.0 License (http://www.apache.org/licenses/LICENSE-2.0)
+
+This product includes/uses software, Apache MINA SSL Filter (http://directory.apache.org/subprojects/mina/mina-filter-ssl)
+developed by Apache Software Foundation (http://www.apache.org)
+License: Apache 2.0 License (http://www.apache.org/licenses/LICENSE-2.0)
+
+This product includes/uses software, Unnamed - xerces:xercesImpl:jar:2.2.1
+developed by The Apache Software Foundation (http://jakarta.apache.org)
+License: Apache 2.0 License (http://www.apache.org/licenses/LICENSE-2.0)
+
+This product includes/uses software, - javax.servlet:servlet-api:jar:2.3
+
+This product includes/uses software, Xalan - xalan:xalan:jar:2.7.0
+developed by Apache Software Foundation (http://www.apache.org)
+License: Apache 2.0 License (http://www.apache.org/licenses/LICENSE-2.0)
+
+This product includes/uses software, Commons Configuration (http://jakarta.apache.org/commons/),
+developed by The Apache Software Foundation (http://jakarta.apache.org)
+License: Apache 2.0 License (http://www.apache.org/licenses/LICENSE-2.0)
+
+This product includes/uses software, Apache MINA Java5 Extensions (http://directory.apache.org/subprojects/mina/mina-java5)
+License: Apache 2.0 License (http://www.apache.org/licenses/LICENSE-2.0)
+
+This product includes/uses software, Jaxen - jaxen:jaxen:jar:1.0-FCS
+License: Apache License (http://jaxen.org/faq.html)
+
+This product includes/uses software, BeanUtils (http://jakarta.apache.org/commons/beanutils/)
+developed by The Apache Software Foundation (http://jakarta.apache.org)
+License: Apache 2.0 License (http://www.apache.org/licenses/LICENSE-2.0)
+
+This product includes/uses software, XML Commons External Components XML APIs (http://xml.apache.org/commons/#external),
+developed by Apache Software Foundation (http://www.apache.org/)
+License: The Apache Software License, Version 2.0 (http://www.apache.org/licenses/LICENSE-2.0.txt)
+
+This product includes/uses software, Commons Beanutils Core - commons-beanutils:commons-beanutils-core:jar:1.7.0
+developed by The Apache Software Foundation (http://jakarta.apache.org)
+License: Apache 2.0 License (http://www.apache.org/licenses/LICENSE-2.0)
+
+This product includes/uses software, Commons Logging API - commons-logging:commons-logging-api:jar:1.0.4
+developed by The Apache Software Foundation (http://jakarta.apache.org)
+License: Apache 2.0 License (http://www.apache.org/licenses/LICENSE-2.0)
+
+This product includes/uses software, Dom4j - dom4j:dom4j:jar:1.4
+developed by MetaStuff, Ltd. (http://www.dom4j.org/)
+License: BSD License (http://www.dom4j.org/license.html)
+
+This product includes/uses software, Saxon - saxpath:saxpath:jar:1.0-FCS
+developed by Michael Kay (http://saxon.sourceforge.net/)
+License: Mozilla Public License v1.0, (http://www.opensource.org/licenses/mozilla1.0.php)
+
diff --git a/java/resources/NOTICE b/java/resources/NOTICE
new file mode 100644
index 0000000000..f62ec14896
--- /dev/null
+++ b/java/resources/NOTICE
@@ -0,0 +1,105 @@
+// ------------------------------------------------------------------
+// NOTICE file corresponding to the section 4d of The Apache License,
+// Version 2.0, in this case for Qpid Common Utilities
+// ------------------------------------------------------------------
+
+Apache Qpid
+Copyright 2006-2007 Apache Software Foundation
+
+This product includes software developed at
+Apache Software Foundation (http://www.apache.org/)
+License: Apache 2.0 License (http://www.apache.org/licenses/LICENSE-2.0)
+
+This product includes/uses software, Unnamed - relaxngDatatype:relaxngDatatype:jar:20020414 (http://sourceforge.net/projects/relaxng)
+License: BSD License (http://www.opensource.org/licenses/bsd-license.php)
+
+This product includes/uses software, Apache MINA Core API (http://directory.apache.org/projects/mina/)
+License: Apache 2.0 License (http://www.apache.org/licenses/LICENSE-2.0)
+
+This product includes/uses software, Unnamed - isorelax:isorelax:jar:20020414
+License: MIT license (http://www.opensource.org/licenses/mit-license.html)
+
+This product includes/uses software, SLF4J API Module (http://www.slf4j.org),
+developed by QOS.ch (http://www.qos.ch)
+License: MIT License (http://www.slf4j.org/license.html)
+
+This product includes/uses software, Commons Collections - commons-collections:commons-collections:jar:3.1,
+developed by Apache Software Foundation (http://www.apache.org)
+License: Apache 2.0 License (http://www.apache.org/licenses/LICENSE-2.0)
+
+This product includes/uses software, Commons Digester - commons-digester:commons-digester:jar:1.6
+developed by Apache Software Foundation (http://www.apache.org)
+License: Apache 2.0 License (http://www.apache.org/licenses/LICENSE-2.0)
+
+This product includes/uses software, Commons CLI - commons-cli:commons-cli:jar:1.0
+Ideveloped by Apache Software Foundation (http://www.apache.org)
+License: Apache 2.0 License (http://www.apache.org/licenses/LICENSE-2.0)
+
+This product includes/uses software, Unnamed - msv:msv:jar:20020414
+developed by (https://msv.dev.java.net/)
+License:
+
+This product includes/uses software, Codec (http://jakarta.apache.org/commons/codec/),
+developed by The Apache Software Foundation (http://jakarta.apache.org)
+License: The Apache Software License, Version 2.0 (http://www.apache.org/licenses/LICENSE-2.0)
+
+This product includes/uses software, Commons Logging - commons-logging:commons-logging:jar:1.0
+developed by Apache Software Foundation (http://www.apache.org)
+License: Apache 2.0 License (http://www.apache.org/licenses/LICENSE-2.0)
+
+This product includes/uses software, Backport of JSR 166 (http://www.mathcs.emory.edu/dcl/util/backport-util-concurrent/),
+developed by Dawid Kurzyniec (http://www.mathcs.emory.edu/~dawidk/)
+License: Public Domain (http://creativecommons.org/licenses/publicdomain)
+
+This product includes/uses software, Commons Lang - commons-lang:commons-lang:jar:2.1
+developed by Apache Software Foundation (http://www.apache.org)
+License: Apache 2.0 License (http://www.apache.org/licenses/LICENSE-2.0)
+
+This product includes/uses software, Apache MINA SSL Filter (http://directory.apache.org/subprojects/mina/mina-filter-ssl)
+developed by Apache Software Foundation (http://www.apache.org)
+License: Apache 2.0 License (http://www.apache.org/licenses/LICENSE-2.0)
+
+This product includes/uses software, Unnamed - xerces:xercesImpl:jar:2.2.1
+developed by The Apache Software Foundation (http://jakarta.apache.org)
+License: Apache 2.0 License (http://www.apache.org/licenses/LICENSE-2.0)
+
+This product includes/uses software, - javax.servlet:servlet-api:jar:2.3
+
+This product includes/uses software, Xalan - xalan:xalan:jar:2.7.0
+developed by Apache Software Foundation (http://www.apache.org)
+License: Apache 2.0 License (http://www.apache.org/licenses/LICENSE-2.0)
+
+This product includes/uses software, Commons Configuration (http://jakarta.apache.org/commons/),
+developed by The Apache Software Foundation (http://jakarta.apache.org)
+License: Apache 2.0 License (http://www.apache.org/licenses/LICENSE-2.0)
+
+This product includes/uses software, Apache MINA Java5 Extensions (http://directory.apache.org/subprojects/mina/mina-java5)
+License: Apache 2.0 License (http://www.apache.org/licenses/LICENSE-2.0)
+
+This product includes/uses software, Jaxen - jaxen:jaxen:jar:1.0-FCS
+License: Apache License (http://jaxen.org/faq.html)
+
+This product includes/uses software, BeanUtils (http://jakarta.apache.org/commons/beanutils/)
+developed by The Apache Software Foundation (http://jakarta.apache.org)
+License: Apache 2.0 License (http://www.apache.org/licenses/LICENSE-2.0)
+
+This product includes/uses software, XML Commons External Components XML APIs (http://xml.apache.org/commons/#external),
+developed by Apache Software Foundation (http://www.apache.org/)
+License: The Apache Software License, Version 2.0 (http://www.apache.org/licenses/LICENSE-2.0.txt)
+
+This product includes/uses software, Commons Beanutils Core - commons-beanutils:commons-beanutils-core:jar:1.7.0
+developed by The Apache Software Foundation (http://jakarta.apache.org)
+License: Apache 2.0 License (http://www.apache.org/licenses/LICENSE-2.0)
+
+This product includes/uses software, Commons Logging API - commons-logging:commons-logging-api:jar:1.0.4
+developed by The Apache Software Foundation (http://jakarta.apache.org)
+License: Apache 2.0 License (http://www.apache.org/licenses/LICENSE-2.0)
+
+This product includes/uses software, Dom4j - dom4j:dom4j:jar:1.4
+developed by MetaStuff, Ltd. (http://www.dom4j.org/)
+License: BSD License (http://www.dom4j.org/license.html)
+
+This product includes/uses software, Saxon - saxpath:saxpath:jar:1.0-FCS
+developed by Michael Kay (http://saxon.sourceforge.net/)
+License: Mozilla Public License v1.0, (http://www.opensource.org/licenses/mozilla1.0.php)
+
diff --git a/java/resources/NOTICE.txt b/java/resources/NOTICE.txt
deleted file mode 100644
index 82d3dbc632..0000000000
--- a/java/resources/NOTICE.txt
+++ /dev/null
@@ -1,36 +0,0 @@
-=========================================================================
-== NOTICE file corresponding to the section 4 d of ==
-== the Apache License, Version 2.0, ==
-== in this case for the Apache Qpid distribution. ==
-=========================================================================
-
-This product includes software developed by the Apache Software Foundation
-(http://www.apache.org/).
-
-Please read the LICENSE.txt file present in the root directory of this
-distribution.
-
-
-Aside from contributions to the Apache Qpid project, this software also
-includes (binary only):
-
- - The SAXON XSLT Processor from Michael Kay distributed under the
- Mozilla Public License v1.0, which is available for download at
- http://saxon.sourceforge.net/
-
- - The JUnit regression testing framework written by Erich Gamma
- and Kent Beck and distributed under the Common Public License v1.0.
- JUnit is available for download at
- http://sourceforge.net/projects/junit/
-
- - The Simple Logging Facade For Java (slf4j), Copyright (c)
- 2004-2005 SLF4J.ORG, Copyright (c) 2004-2005 QOS.ch. slf4j is
- licensed under identical terms to the MIT/X11 license and
- available for download at http://www.slf4j.org/
-
- - Software from the Eclipse project. The binaries from this project are
- distributed under the Eclipse Public License and can be donwloaded
- from http://www.eclipse.org/
-
-
-
diff --git a/java/resources/README.txt b/java/resources/README
index 1d52d487fb..1d52d487fb 100644
--- a/java/resources/README.txt
+++ b/java/resources/README
diff --git a/java/systests/pom.xml b/java/systests/pom.xml
index f845b9fb44..c2fedec25a 100644
--- a/java/systests/pom.xml
+++ b/java/systests/pom.xml
@@ -79,6 +79,9 @@
<configuration>
<testSourceDirectory>${basedir}/src/main</testSourceDirectory>
<testClassesDirectory>target/classes</testClassesDirectory>
+ <includes>
+ <include>**/*Test.class</include>
+ </includes>
</configuration>
</plugin>
diff --git a/java/systests/src/main/java/org/apache/qpid/server/AMQBrokerManagerMBeanTest.java b/java/systests/src/main/java/org/apache/qpid/server/AMQBrokerManagerMBeanTest.java
index 20de0d5df0..370c2b43a7 100644
--- a/java/systests/src/main/java/org/apache/qpid/server/AMQBrokerManagerMBeanTest.java
+++ b/java/systests/src/main/java/org/apache/qpid/server/AMQBrokerManagerMBeanTest.java
@@ -1,30 +1,34 @@
/*
*
- * Copyright (c) 2006 The Apache Software Foundation
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
*
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
+ * http://www.apache.org/licenses/LICENSE-2.0
*
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT 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;
import junit.framework.TestCase;
+
+import org.apache.qpid.framing.AMQShortString;
import org.apache.qpid.server.exchange.ExchangeRegistry;
import org.apache.qpid.server.management.ManagedBroker;
import org.apache.qpid.server.queue.QueueRegistry;
import org.apache.qpid.server.registry.ApplicationRegistry;
import org.apache.qpid.server.registry.IApplicationRegistry;
import org.apache.qpid.server.virtualhost.VirtualHost;
-import org.apache.qpid.framing.AMQShortString;
public class AMQBrokerManagerMBeanTest extends TestCase
{
@@ -33,9 +37,9 @@ public class AMQBrokerManagerMBeanTest extends TestCase
public void testExchangeOperations() throws Exception
{
- String exchange1 = "testExchange1_" + System.currentTimeMillis();
- String exchange2 = "testExchange2_" + System.currentTimeMillis();
- String exchange3 = "testExchange3_" + System.currentTimeMillis();
+ String exchange1 = "testExchange1_" + System.currentTimeMillis();
+ String exchange2 = "testExchange2_" + System.currentTimeMillis();
+ String exchange3 = "testExchange3_" + System.currentTimeMillis();
assertTrue(_exchangeRegistry.getExchange(new AMQShortString(exchange1)) == null);
assertTrue(_exchangeRegistry.getExchange(new AMQShortString(exchange2)) == null);
@@ -43,10 +47,10 @@ public class AMQBrokerManagerMBeanTest extends TestCase
VirtualHost vHost = ApplicationRegistry.getInstance().getVirtualHostRegistry().getVirtualHost("test");
- ManagedBroker mbean = new AMQBrokerManagerMBean((VirtualHost.VirtualHostMBean)vHost.getManagedObject());
- mbean.createNewExchange(exchange1,"direct",false);
- mbean.createNewExchange(exchange2,"topic",false);
- mbean.createNewExchange(exchange3,"headers",false);
+ ManagedBroker mbean = new AMQBrokerManagerMBean((VirtualHost.VirtualHostMBean) vHost.getManagedObject());
+ mbean.createNewExchange(exchange1, "direct", false);
+ mbean.createNewExchange(exchange2, "topic", false);
+ mbean.createNewExchange(exchange3, "headers", false);
assertTrue(_exchangeRegistry.getExchange(new AMQShortString(exchange1)) != null);
assertTrue(_exchangeRegistry.getExchange(new AMQShortString(exchange2)) != null);
@@ -66,10 +70,10 @@ public class AMQBrokerManagerMBeanTest extends TestCase
String queueName = "testQueue_" + System.currentTimeMillis();
VirtualHost vHost = ApplicationRegistry.getInstance().getVirtualHostRegistry().getVirtualHost("test");
- ManagedBroker mbean = new AMQBrokerManagerMBean((VirtualHost.VirtualHostMBean)vHost.getManagedObject());
+ ManagedBroker mbean = new AMQBrokerManagerMBean((VirtualHost.VirtualHostMBean) vHost.getManagedObject());
assertTrue(_queueRegistry.getQueue(new AMQShortString(queueName)) == null);
-
+
mbean.createNewQueue(queueName, "test", false);
assertTrue(_queueRegistry.getQueue(new AMQShortString(queueName)) != null);
@@ -82,7 +86,7 @@ public class AMQBrokerManagerMBeanTest extends TestCase
{
super.setUp();
IApplicationRegistry appRegistry = ApplicationRegistry.getInstance();
- _queueRegistry = appRegistry.getVirtualHostRegistry().getVirtualHost("test").getQueueRegistry();
+ _queueRegistry = appRegistry.getVirtualHostRegistry().getVirtualHost("test").getQueueRegistry();
_exchangeRegistry = appRegistry.getVirtualHostRegistry().getVirtualHost("test").getExchangeRegistry();
}
}
diff --git a/java/systests/src/main/java/org/apache/qpid/server/exchange/ImmediateMessageTest.java b/java/systests/src/main/java/org/apache/qpid/server/exchange/ImmediateMessageTest.java
index 048fcfb0b3..4a0a27bb06 100644
--- a/java/systests/src/main/java/org/apache/qpid/server/exchange/ImmediateMessageTest.java
+++ b/java/systests/src/main/java/org/apache/qpid/server/exchange/ImmediateMessageTest.java
@@ -20,34 +20,15 @@
*/
package org.apache.qpid.server.exchange;
-import junit.framework.TestCase;
-
-import org.apache.log4j.NDC;
-
-import org.apache.qpid.client.AMQNoConsumersException;
-import org.apache.qpid.client.AMQNoRouteException;
-import org.apache.qpid.client.AMQSession;
-import org.apache.qpid.client.transport.TransportConnection;
-import static org.apache.qpid.server.exchange.MessagingTestConfigProperties.*;
-import org.apache.qpid.server.registry.ApplicationRegistry;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
+import org.apache.qpid.test.framework.sequencers.TestCaseSequencer;
+import org.apache.qpid.test.framework.Circuit;
+import org.apache.qpid.test.framework.FrameworkBaseCase;
+import org.apache.qpid.test.framework.MessagingTestConfigProperties;
+import static org.apache.qpid.test.framework.MessagingTestConfigProperties.*;
import uk.co.thebadgerset.junit.extensions.util.ParsedProperties;
import uk.co.thebadgerset.junit.extensions.util.TestContextProperties;
-import javax.jms.*;
-import javax.naming.Context;
-import javax.naming.InitialContext;
-import javax.naming.NamingException;
-
-import java.io.PrintWriter;
-import java.io.StringWriter;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.concurrent.atomic.AtomicLong;
-
/**
* ImmediateMessageTest tests for the desired behaviour of immediate messages. Immediate messages are a non-JMS
* feature. A message may be marked with an immediate delivery flag, which means that a consumer must be connected
@@ -58,60 +39,68 @@ import java.util.concurrent.atomic.AtomicLong;
* <tr><th> Responsibilities <th> Collaborations
* <tr><td> Check that an immediate message is sent succesfully not using transactions when a consumer is connected.
* <tr><td> Check that an immediate message is committed succesfully in a transaction when a consumer is connected.
- * <tr><td> Check that an immediate message results in no consumers code, not using transactions, when no consumer is
+ * <tr><td> Check that an immediate message results in no consumers code, not using transactions, when a consumer is
+ * disconnected.
+ * <tr><td> Check that an immediate message results in no consumers code, in a transaction, when a consumer is
+ * disconnected.
+ * <tr><td> Check that an immediate message results in no route code, not using transactions, when no outgoing route is
* connected.
- * <tr><td> Check that an immediate message results in no consumers code, upon transaction commit, when a consumer is
+ * <tr><td> Check that an immediate message results in no route code, upon transaction commit, when no outgoing route is
* connected.
+ * <tr><td> Check that an immediate message is sent succesfully not using transactions when a consumer is connected.
+ * <tr><td> Check that an immediate message is committed succesfully in a transaction when a consumer is connected.
* <tr><td> Check that an immediate message results in no consumers code, not using transactions, when a consumer is
* disconnected.
- * <tr><dt> Check that an immediate message results in no consumers code, in a transaction, when a consumer is
+ * <tr><td> Check that an immediate message results in no consumers code, in a transaction, when a consumer is
* disconnected.
+ * <tr><td> Check that an immediate message results in no route code, not using transactions, when no outgoing route is
+ * connected.
+ * <tr><td> Check that an immediate message results in no route code, upon transaction commit, when no outgoing route is
+ * connected.
* </table>
*
- * @todo Write a test decorator, the sole function of which is to populate test context properties, from sys properties,
- * from trailing prop=value pairs on the command line, from test properties files or other sources. This should
- * run through stanard JUnit without the JUnit toolkit extensions, and through Maven surefire, and also through
- * the JUnit toolkit extended test runners.
- *
- * @todo Veto test topologies using bounce back. Or else the bounce back client will act as an immediate consumer.
+ * @todo All of these test cases will be generated by a test generator that thoroughly tests all combinations of test
+ * circuits.
*/
-public class ImmediateMessageTest extends TestCase
+public class ImmediateMessageTest extends FrameworkBaseCase
{
- /** Used for debugging. */
- private static final Logger log = LoggerFactory.getLogger(ImmediateMessageTest.class);
-
/** Used to read the tests configurable properties through. */
ParsedProperties testProps;
- /** Used to create unique destination names for each test.
- * @todo Move into the test framework.
+ /**
+ * Creates a new test case with the specified name.
+ *
+ * @param name The test case name.
*/
- private static AtomicLong uniqueDestsId = new AtomicLong();
+ public ImmediateMessageTest(String name)
+ {
+ super(name);
+ }
/** Check that an immediate message is sent succesfully not using transactions when a consumer is connected. */
- public void test_QPID_517_ImmediateOkNoTxP2P() throws Exception
+ public void test_QPID_517_ImmediateOkNoTxP2P()
{
// Ensure transactional sessions are off.
testProps.setProperty(TRANSACTED_PROPNAME, false);
testProps.setProperty(PUBSUB_PROPNAME, false);
- PublisherReceiver testClients = PublisherReceiverImpl.connectClients(testProps);
-
- // Send one message with no errors.
- testClients.testNoExceptions(testProps);
+ // Run the default test sequence over the test circuit checking for no errors.
+ TestCaseSequencer sequencer = getTestSequencer();
+ Circuit testCircuit = sequencer.createCircuit(testProps);
+ sequencer.sequenceTest(testCircuit, assertionList(testCircuit.getPublisher().noExceptionsAssertion()), testProps);
}
/** Check that an immediate message is committed succesfully in a transaction when a consumer is connected. */
- public void test_QPID_517_ImmediateOkTxP2P() throws Exception
+ public void test_QPID_517_ImmediateOkTxP2P()
{
// Ensure transactional sessions are off.
testProps.setProperty(TRANSACTED_PROPNAME, true);
testProps.setProperty(PUBSUB_PROPNAME, false);
- PublisherReceiver testClients = PublisherReceiverImpl.connectClients(testProps);
-
// Send one message with no errors.
- testClients.testNoExceptions(testProps);
+ TestCaseSequencer sequencer = getTestSequencer();
+ Circuit testCircuit = sequencer.createCircuit(testProps);
+ sequencer.sequenceTest(testCircuit, assertionList(testCircuit.getPublisher().noExceptionsAssertion()), testProps);
}
/** Check that an immediate message results in no consumers code, not using transactions, when a consumer is disconnected. */
@@ -121,13 +110,14 @@ public class ImmediateMessageTest extends TestCase
testProps.setProperty(TRANSACTED_PROPNAME, false);
testProps.setProperty(PUBSUB_PROPNAME, false);
- PublisherReceiver testClients = PublisherReceiverImpl.connectClients(testProps);
+ TestCaseSequencer sequencer = getTestSequencer();
+ Circuit testCircuit = sequencer.createCircuit(testProps);
// Disconnect the consumer.
- testClients.getReceiver().getConsumer().close();
+ testCircuit.getReceiver().getConsumer().close();
// Send one message and get a linked no consumers exception.
- testClients.testWithAssertions(testProps, AMQNoConsumersException.class);
+ sequencer.sequenceTest(testCircuit, assertionList(testCircuit.getPublisher().noConsumersAssertion()), testProps);
}
/** Check that an immediate message results in no consumers code, in a transaction, when a consumer is disconnected. */
@@ -137,73 +127,74 @@ public class ImmediateMessageTest extends TestCase
testProps.setProperty(TRANSACTED_PROPNAME, true);
testProps.setProperty(PUBSUB_PROPNAME, false);
- PublisherReceiver testClients = PublisherReceiverImpl.connectClients(testProps);
+ TestCaseSequencer sequencer = getTestSequencer();
+ Circuit testCircuit = sequencer.createCircuit(testProps);
// Disconnect the consumer.
- testClients.getReceiver().getConsumer().close();
+ testCircuit.getReceiver().getConsumer().close();
// Send one message and get a linked no consumers exception.
- testClients.testWithAssertions(testProps, AMQNoConsumersException.class);
+ sequencer.sequenceTest(testCircuit, assertionList(testCircuit.getPublisher().noConsumersAssertion()), testProps);
}
- /** Check that an immediate message results in no consumers code, not using transactions, when no consumer is connected. */
- public void test_QPID_517_ImmediateFailsNoRouteNoTxP2P() throws Exception
+ /** Check that an immediate message results in no route code, not using transactions, when no outgoing route is connected. */
+ public void test_QPID_517_ImmediateFailsNoRouteNoTxP2P()
{
// Ensure transactional sessions are off.
testProps.setProperty(TRANSACTED_PROPNAME, false);
testProps.setProperty(PUBSUB_PROPNAME, false);
- // Set up the messaging topology so that only the publishers producer is bound (do not set up the receiver to
+ // Set up the messaging topology so that only the publishers producer is bound (do not set up the receivers to
// collect its messages).
testProps.setProperty(RECEIVER_CONSUMER_BIND_PROPNAME, false);
- PublisherReceiver testClients = PublisherReceiverImpl.connectClients(testProps);
-
- // Send one message and get a linked no consumers exception.
- testClients.testWithAssertions(testProps, AMQNoRouteException.class);
+ // Send one message and get a linked no route exception.
+ TestCaseSequencer sequencer = getTestSequencer();
+ Circuit testCircuit = sequencer.createCircuit(testProps);
+ sequencer.sequenceTest(testCircuit, assertionList(testCircuit.getPublisher().noRouteAssertion()), testProps);
}
- /** Check that an immediate message results in no consumers code, upon transaction commit, when a consumer is connected. */
- public void test_QPID_517_ImmediateFailsNoRouteTxP2P() throws Exception
+ /** Check that an immediate message results in no route code, upon transaction commit, when no outgoing route is connected. */
+ public void test_QPID_517_ImmediateFailsNoRouteTxP2P()
{
// Ensure transactional sessions are on.
testProps.setProperty(TRANSACTED_PROPNAME, true);
testProps.setProperty(PUBSUB_PROPNAME, false);
- // Set up the messaging topology so that only the publishers producer is bound (do not set up the receiver to
+ // Set up the messaging topology so that only the publishers producer is bound (do not set up the receivers to
// collect its messages).
testProps.setProperty(RECEIVER_CONSUMER_BIND_PROPNAME, false);
- PublisherReceiver testClients = PublisherReceiverImpl.connectClients(testProps);
-
- // Send one message and get a linked no consumers exception.
- testClients.testWithAssertions(testProps, AMQNoRouteException.class);
+ // Send one message and get a linked no route exception.
+ TestCaseSequencer sequencer = getTestSequencer();
+ Circuit testCircuit = sequencer.createCircuit(testProps);
+ sequencer.sequenceTest(testCircuit, assertionList(testCircuit.getPublisher().noRouteAssertion()), testProps);
}
/** Check that an immediate message is sent succesfully not using transactions when a consumer is connected. */
- public void test_QPID_517_ImmediateOkNoTxPubSub() throws Exception
+ public void test_QPID_517_ImmediateOkNoTxPubSub()
{
// Ensure transactional sessions are off.
testProps.setProperty(TRANSACTED_PROPNAME, false);
testProps.setProperty(PUBSUB_PROPNAME, true);
- PublisherReceiver testClients = PublisherReceiverImpl.connectClients(testProps);
-
// Send one message with no errors.
- testClients.testNoExceptions(testProps);
+ TestCaseSequencer sequencer = getTestSequencer();
+ Circuit testCircuit = sequencer.createCircuit(testProps);
+ sequencer.sequenceTest(testCircuit, assertionList(testCircuit.getPublisher().noExceptionsAssertion()), testProps);
}
/** Check that an immediate message is committed succesfully in a transaction when a consumer is connected. */
- public void test_QPID_517_ImmediateOkTxPubSub() throws Exception
+ public void test_QPID_517_ImmediateOkTxPubSub()
{
// Ensure transactional sessions are off.
testProps.setProperty(TRANSACTED_PROPNAME, true);
testProps.setProperty(PUBSUB_PROPNAME, true);
- PublisherReceiver testClients = PublisherReceiverImpl.connectClients(testProps);
-
// Send one message with no errors.
- testClients.testNoExceptions(testProps);
+ TestCaseSequencer sequencer = getTestSequencer();
+ Circuit testCircuit = sequencer.createCircuit(testProps);
+ sequencer.sequenceTest(testCircuit, assertionList(testCircuit.getPublisher().noExceptionsAssertion()), testProps);
}
/** Check that an immediate message results in no consumers code, not using transactions, when a consumer is disconnected. */
@@ -216,13 +207,14 @@ public class ImmediateMessageTest extends TestCase
// Use durable subscriptions, so that the route remains open with no subscribers.
testProps.setProperty(DURABLE_SUBSCRIPTION_PROPNAME, true);
- PublisherReceiver testClients = PublisherReceiverImpl.connectClients(testProps);
+ TestCaseSequencer sequencer = getTestSequencer();
+ Circuit testCircuit = sequencer.createCircuit(testProps);
// Disconnect the consumer.
- testClients.getReceiver().getConsumer().close();
+ testCircuit.getReceiver().getConsumer().close();
// Send one message and get a linked no consumers exception.
- testClients.testWithAssertions(testProps, AMQNoConsumersException.class);
+ sequencer.sequenceTest(testCircuit, assertionList(testCircuit.getPublisher().noConsumersAssertion()), testProps);
}
/** Check that an immediate message results in no consumers code, in a transaction, when a consumer is disconnected. */
@@ -235,696 +227,61 @@ public class ImmediateMessageTest extends TestCase
// Use durable subscriptions, so that the route remains open with no subscribers.
testProps.setProperty(DURABLE_SUBSCRIPTION_PROPNAME, true);
- PublisherReceiver testClients = PublisherReceiverImpl.connectClients(testProps);
+ TestCaseSequencer sequencer = getTestSequencer();
+ Circuit testCircuit = sequencer.createCircuit(testProps);
// Disconnect the consumer.
- testClients.getReceiver().getConsumer().close();
+ testCircuit.getReceiver().getConsumer().close();
// Send one message and get a linked no consumers exception.
- testClients.testWithAssertions(testProps, AMQNoConsumersException.class);
+ sequencer.sequenceTest(testCircuit, assertionList(testCircuit.getPublisher().noConsumersAssertion()), testProps);
}
- /** Check that an immediate message results in no consumers code, not using transactions, when no consumer is connected. */
- public void test_QPID_517_ImmediateFailsNoRouteNoTxPubSub() throws Exception
+ /** Check that an immediate message results in no route code, not using transactions, when no outgoing route is connected. */
+ public void test_QPID_517_ImmediateFailsNoRouteNoTxPubSub()
{
// Ensure transactional sessions are off.
testProps.setProperty(TRANSACTED_PROPNAME, false);
testProps.setProperty(PUBSUB_PROPNAME, true);
- // Set up the messaging topology so that only the publishers producer is bound (do not set up the receiver to
+ // Set up the messaging topology so that only the publishers producer is bound (do not set up the receivers to
// collect its messages).
testProps.setProperty(RECEIVER_CONSUMER_BIND_PROPNAME, false);
- PublisherReceiver testClients = PublisherReceiverImpl.connectClients(testProps);
-
- // Send one message and get a linked no consumers exception.
- testClients.testWithAssertions(testProps, AMQNoRouteException.class);
+ // Send one message and get a linked no route exception.
+ TestCaseSequencer sequencer = getTestSequencer();
+ Circuit testCircuit = sequencer.createCircuit(testProps);
+ sequencer.sequenceTest(testCircuit, assertionList(testCircuit.getPublisher().noRouteAssertion()), testProps);
}
- /** Check that an immediate message results in no consumers code, upon transaction commit, when a consumer is connected. */
- public void test_QPID_517_ImmediateFailsNoRouteTxPubSub() throws Exception
+ /** Check that an immediate message results in no route code, upon transaction commit, when no outgoing route is connected. */
+ public void test_QPID_517_ImmediateFailsNoRouteTxPubSub()
{
// Ensure transactional sessions are on.
testProps.setProperty(TRANSACTED_PROPNAME, true);
testProps.setProperty(PUBSUB_PROPNAME, true);
- // Set up the messaging topology so that only the publishers producer is bound (do not set up the receiver to
+ // Set up the messaging topology so that only the publishers producer is bound (do not set up the receivers to
// collect its messages).
testProps.setProperty(RECEIVER_CONSUMER_BIND_PROPNAME, false);
- PublisherReceiver testClients = PublisherReceiverImpl.connectClients(testProps);
-
- // Send one message and get a linked no consumers exception.
- testClients.testWithAssertions(testProps, AMQNoRouteException.class);
+ // Send one message and get a linked no route exception.
+ TestCaseSequencer sequencer = getTestSequencer();
+ Circuit testCircuit = sequencer.createCircuit(testProps);
+ sequencer.sequenceTest(testCircuit, assertionList(testCircuit.getPublisher().noRouteAssertion()), testProps);
}
protected void setUp() throws Exception
{
- NDC.push(getName());
+ super.setUp();
testProps = TestContextProperties.getInstance(MessagingTestConfigProperties.defaults);
/** All these tests should have the immediate flag on. */
testProps.setProperty(IMMEDIATE_PROPNAME, true);
+ testProps.setProperty(MANDATORY_PROPNAME, false);
/** Bind the receivers consumer by default. */
testProps.setProperty(RECEIVER_CONSUMER_BIND_PROPNAME, true);
-
- // Ensure that the in-vm broker is created.
- TransportConnection.createVMBroker(1);
- }
-
- protected void tearDown() throws Exception
- {
- try
- {
- // Ensure that the in-vm broker is cleaned up so that the next test starts afresh.
- TransportConnection.killVMBroker(1);
- ApplicationRegistry.remove(1);
- }
- finally
- {
- NDC.pop();
- }
- }
-
- /*
- * Stuff below:
- *
- * This will get tidied into some sort on JMS convenience framework, through which practically any usefull test
- * topology can be created. This will become a replacement for PingPongProducer.
- *
- * Base everything on standard connection properties defined in PingPongProducer. Split JMS and AMQP-only properties.
- *
- * Integrate with ConversationFactory, so that it will work with prod/con pairs.
- *
- * Support pub/rec pairs.
- * Support m*n pub/rec setups. All pubs/recs on one machine.
- *
- * Support bounce back clients, with configurable bounce back behavior. All, one in X, round robin one in m, etc.
- *
- * Support pairing of m*n pub/rec setups with bounce back clients. JVM running a test, can simulate m publishers,
- * will receive (a known subset of) all messages sent, bounced back to n receivers. Co-location of pub/rec will be
- * the normal model to allow accurate timings to be taken.
- *
- * Support creation of pub or rec only.
- * Support clock synching of pub/rec on different JVMs, by calculating clock offsets. Must also provide an accuracy
- * estimate to +- the results.
- *
- * Augment the interop Coordinator, to become a full distributed test coordinator. Capable of querying available
- * tests machines, looking at test parameters and farming out tests onto the test machines, passing all test
- * parameters, standard naming of pub/rec config parameters used to set up m*n test topologies, run test cases,
- * report results, tear down m*n topologies. Need to split the re-usable general purpose distributed test coordinator
- * from the Qpid specific test framework for creating test-topoloigies and passing Qpid specific parameters.
- *
- * Write all tests against pub/rec pairs, without coding to the fact that the topology may be anything from 1:1 in
- * JVM to m*n with bounce back clients accross many machines. That is, make the test topology orthogonal to the test
- * case.
- */
-
- private static class ExceptionMonitor implements ExceptionListener
- {
- List<JMSException> exceptions = new ArrayList<JMSException>();
-
- public void onException(JMSException e)
- {
- log.debug("ExceptionMonitor got JMSException: ", e);
-
- exceptions.add(e);
- }
-
- public boolean assertNoExceptions()
- {
- return exceptions.isEmpty();
- }
-
- public boolean assertOneJMSException()
- {
- return exceptions.size() == 1;
- }
-
- public boolean assertOneJMSExceptionWithLinkedCause(Class aClass)
- {
- if (exceptions.size() == 1)
- {
- JMSException e = exceptions.get(0);
-
- Exception linkedCause = e.getLinkedException();
-
- if ((linkedCause != null) && aClass.isInstance(linkedCause))
- {
- return true;
- }
- }
-
- return false;
- }
-
- /**
- * Reports the number of exceptions held by this monitor.
- *
- * @return The number of exceptions held by this monitor.
- */
- public int size()
- {
- return exceptions.size();
- }
-
- public void reset()
- {
- exceptions = new ArrayList();
- }
-
- /**
- * Provides a dump of the stack traces of all exceptions that this exception monitor was notified of. Mainly
- * use for debugging/test failure reporting purposes.
- *
- * @return A string containing a dump of the stack traces of all exceptions.
- */
- public String toString()
- {
- String result = "ExceptionMonitor: holds " + exceptions.size() + " exceptions.\n\n";
-
- for (JMSException ex : exceptions)
- {
- result += getStackTrace(ex) + "\n";
- }
-
- return result;
- }
-
- /**
- * Prints an exception stack trace into a string.
- *
- * @param t The throwable to get the stack trace from.
- *
- * @return A string containing the throwables stack trace.
- */
- public static String getStackTrace(Throwable t)
- {
- StringWriter sw = new StringWriter();
- PrintWriter pw = new PrintWriter(sw, true);
- t.printStackTrace(pw);
- pw.flush();
- sw.flush();
-
- return sw.toString();
- }
- }
-
- public static class MessageMonitor implements MessageListener
- {
- public void onMessage(Message message)
- {
- log.debug("public void onMessage(Message message): called");
- }
- }
-
- /**
- * Establishes a JMS connection using a properties file and qpids built in JNDI implementation. This is a simple
- * convenience method for code that does anticipate handling connection failures. All exceptions that indicate
- * that the connection has failed, are wrapped as rutime exceptions, preumably handled by a top level failure
- * handler.
- *
- * @param messagingProps Any additional connection properties.
- *
- * @return A JMS conneciton.
- *
- * @todo Move this to a Utils library class or base test class. Also move the copy in interop.TestClient too.
- *
- * @todo Make in VM broker creation step optional on whether one is to be used or not.
- */
- public static Connection createConnection(ParsedProperties messagingProps)
- {
- log.debug("public static Connection createConnection(Properties messagingProps = " + messagingProps + "): called");
-
- try
- {
- // Extract the configured connection properties from the test configuration.
- String conUsername = messagingProps.getProperty(USERNAME_PROPNAME);
- String conPassword = messagingProps.getProperty(PASSWORD_PROPNAME);
- String virtualHost = messagingProps.getProperty(VIRTUAL_HOST_PROPNAME);
- String brokerUrl = messagingProps.getProperty(BROKER_PROPNAME);
-
- // Set up the broker connection url.
- String connectionString =
- "amqp://" + conUsername + ":" + conPassword + "/" + ((virtualHost != null) ? virtualHost : "")
- + "?brokerlist='" + brokerUrl + "'";
-
- // messagingProps.setProperty(CONNECTION_PROPNAME, connectionString);
-
- Context ctx = new InitialContext(messagingProps);
-
- ConnectionFactory cf = (ConnectionFactory) ctx.lookup(CONNECTION_NAME);
- Connection connection = cf.createConnection();
-
- return connection;
- }
- catch (NamingException e)
- {
- log.debug("Got NamingException: ", e);
- throw new RuntimeException("Got JNDI NamingException whilst looking up the connection factory.", e);
- }
- catch (JMSException e)
- {
- log.debug("Got JMSException: ", e);
- throw new RuntimeException("Could not establish connection due to JMSException.", e);
- }
- }
-
- /**
- * Creates a publisher and a receiver on the same connection, configured according the to specified standard
- * properties.
- *
- * @param messagingProps The connection properties.
- *
- * @return A publisher/receiver client pair.
- */
- public static PublisherReceiver createPublisherReceiverPairSharedConnection(ParsedProperties messagingProps)
- {
- try
- {
- // Get a unique offset to append to destination names to make them unique to the connection.
- long uniqueId = uniqueDestsId.incrementAndGet();
-
- // Extract the standard test configuration parameters relevant to the connection.
- String destinationSendRoot = messagingProps.getProperty(SEND_DESTINATION_NAME_ROOT_PROPNAME) + "_" + uniqueId;
- String destinationReceiveRoot =
- messagingProps.getProperty(RECEIVE_DESTINATION_NAME_ROOT_PROPNAME) + "_" + uniqueId;
- boolean createPublisherProducer = messagingProps.getPropertyAsBoolean(PUBLISHER_PRODUCER_BIND_PROPNAME);
- boolean createPublisherConsumer = messagingProps.getPropertyAsBoolean(PUBLISHER_CONSUMER_BIND_PROPNAME);
- boolean createReceiverProducer = messagingProps.getPropertyAsBoolean(RECEIVER_PRODUCER_BIND_PROPNAME);
- boolean createReceiverConsumer = messagingProps.getPropertyAsBoolean(RECEIVER_CONSUMER_BIND_PROPNAME);
-
- // Check which JMS flags and options are to be set.
- int ackMode = messagingProps.getPropertyAsInteger(ACK_MODE_PROPNAME);
- boolean useTopics = messagingProps.getPropertyAsBoolean(PUBSUB_PROPNAME);
- boolean transactional = messagingProps.getPropertyAsBoolean(TRANSACTED_PROPNAME);
- boolean durableSubscription = messagingProps.getPropertyAsBoolean(DURABLE_SUBSCRIPTION_PROPNAME);
-
- // Check if any Qpid/AMQP specific flags or options need to be set.
- boolean immediate = messagingProps.getPropertyAsBoolean(IMMEDIATE_PROPNAME);
- boolean mandatory = messagingProps.getPropertyAsBoolean(MANDATORY_PROPNAME);
- boolean needsQpidOptions = immediate | mandatory;
-
- /*log.debug("ackMode = " + ackMode);
- log.debug("useTopics = " + useTopics);
- log.debug("destinationSendRoot = " + destinationSendRoot);
- log.debug("destinationReceiveRoot = " + destinationReceiveRoot);
- log.debug("createPublisherProducer = " + createPublisherProducer);
- log.debug("createPublisherConsumer = " + createPublisherConsumer);
- log.debug("createReceiverProducer = " + createReceiverProducer);
- log.debug("createReceiverConsumer = " + createReceiverConsumer);
- log.debug("transactional = " + transactional);
- log.debug("immediate = " + immediate);
- log.debug("mandatory = " + mandatory);
- log.debug("needsQpidOptions = " + needsQpidOptions);*/
-
- // Create connection, sessions and producer/consumer pairs on each session.
- Connection connection = createConnection(messagingProps);
-
- // Add the connection exception listener to assert on exception conditions with.
- ExceptionMonitor exceptionMonitor = new ExceptionMonitor();
- connection.setExceptionListener(exceptionMonitor);
-
- Session publisherSession = connection.createSession(transactional, ackMode);
- Session receiverSession = connection.createSession(transactional, ackMode);
-
- Destination publisherProducerDestination =
- useTopics ? (Destination) publisherSession.createTopic(destinationSendRoot)
- : publisherSession.createQueue(destinationSendRoot);
-
- MessageProducer publisherProducer =
- createPublisherProducer
- ? (needsQpidOptions
- ? ((AMQSession) publisherSession).createProducer(publisherProducerDestination, mandatory, immediate)
- : publisherSession.createProducer(publisherProducerDestination)) : null;
-
- MessageConsumer publisherConsumer =
- createPublisherConsumer
- ? publisherSession.createConsumer(publisherSession.createQueue(destinationReceiveRoot)) : null;
-
- if (publisherConsumer != null)
- {
- publisherConsumer.setMessageListener(new MessageMonitor());
- }
-
- MessageProducer receiverProducer =
- createReceiverProducer ? receiverSession.createProducer(receiverSession.createQueue(destinationReceiveRoot))
- : null;
-
- Destination receiverConsumerDestination =
- useTopics ? (Destination) receiverSession.createTopic(destinationSendRoot)
- : receiverSession.createQueue(destinationSendRoot);
-
- MessageConsumer receiverConsumer =
- createReceiverConsumer
- ? ((durableSubscription && useTopics)
- ? receiverSession.createDurableSubscriber((Topic) receiverConsumerDestination, "testsub")
- : receiverSession.createConsumer(receiverConsumerDestination)) : null;
-
- if (receiverConsumer != null)
- {
- receiverConsumer.setMessageListener(new MessageMonitor());
- }
-
- // Start listening for incoming messages.
- connection.start();
-
- // Package everything up.
- ProducerConsumerPair publisher =
- new ProducerConsumerPairImpl(publisherProducer, publisherConsumer, publisherSession);
- ProducerConsumerPair receiver =
- new ProducerConsumerPairImpl(receiverProducer, receiverConsumer, receiverSession);
-
- PublisherReceiver result = new PublisherReceiverImpl(publisher, receiver, connection, exceptionMonitor);
-
- return result;
- }
- catch (JMSException e)
- {
- log.debug("Got JMSException: ", e);
- throw new RuntimeException("Could not create publisher/receiver pair due to a JMSException.", e);
- }
- }
-
- public static Message createTestMessage(ProducerConsumerPair client, ParsedProperties testProps) throws JMSException
- {
- return client.getSession().createTextMessage("Hello");
- // return client.getSession().createMessage();
- }
-
- /**
- * A ProducerConsumerPair is a pair consisting of one message producer and one message consumer. It is a standard
- * unit of connectivity allowing a full-duplex conversation to be held, provided both the consumer and producer
- * are instantiated and configured.
- *
- * In some situations a test, or piece of application code will be written with differing numbers of publishers
- * and receivers in different roles, where one role produces only and one consumes only. This messaging topology
- * can still make use of producer/consumer pairs as standard building blocks, combined into publisher/receiver
- * units to fulfill the different messaging roles, with the publishers consumer uninstantiated and the receivers
- * producer uninstantiated. Use a {@link PublisherReceiver} for this.
- *
- * <p/><table id="crc"><caption>CRC Card</caption>
- * <tr><th> Responsibilities
- * <tr><td> Provide a message producer for sending messages.
- * <tr><td> Provide a message consumer for receiving messages.
- * </table>
- *
- * @todo Update the {@link org.apache.qpid.util.ConversationFactory} so that it accepts these as the basic
- * conversation connection units.
- */
- public static interface ProducerConsumerPair
- {
- public MessageProducer getProducer();
-
- public MessageConsumer getConsumer();
-
- public void send(Message message) throws JMSException;
-
- public Session getSession();
-
- public void close() throws JMSException;
- }
-
- /**
- * A single producer and consumer.
- */
- public static class ProducerConsumerPairImpl implements ProducerConsumerPair
- {
- MessageProducer producer;
-
- MessageConsumer consumer;
-
- Session session;
-
- public ProducerConsumerPairImpl(MessageProducer producer, MessageConsumer consumer, Session session)
- {
- this.producer = producer;
- this.consumer = consumer;
- this.session = session;
- }
-
- public MessageProducer getProducer()
- {
- return producer;
- }
-
- public MessageConsumer getConsumer()
- {
- return consumer;
- }
-
- public void send(Message message) throws JMSException
- {
- producer.send(message);
- }
-
- public Session getSession()
- {
- return session;
- }
-
- public void close() throws JMSException
- {
- if (producer != null)
- {
- producer.close();
- }
-
- if (consumer != null)
- {
- consumer.close();
- }
- }
- }
-
- /**
- * Multiple producers and consumers made to look like a single producer and consumer. All methods repeated accross
- * all producers and consumers.
- */
- public static class MultiProducerConsumerPairImpl implements ProducerConsumerPair
- {
- public MessageProducer getProducer()
- {
- throw new RuntimeException("Not implemented.");
- }
-
- public MessageConsumer getConsumer()
- {
- throw new RuntimeException("Not implemented.");
- }
-
- public void send(Message message) throws JMSException
- {
- throw new RuntimeException("Not implemented.");
- }
-
- public Session getSession()
- {
- throw new RuntimeException("Not implemented.");
- }
-
- public void close()
- {
- throw new RuntimeException("Not implemented.");
- }
- }
-
- /**
- * A PublisherReceiver consists of two sets of producer/consumer pairs, one for an 'instigating' publisher
- * role, and one for a more 'passive' receiver role.
- *
- * <p/>A set of publishers and receivers forms a typical test configuration where both roles are to be controlled
- * from within a single JVM. This is not a particularly usefull arrangement for applications which want to place
- * these roles on physically seperate machines and pass messages between them. It is a faily normal arrangement for
- * test code though, either to publish and receive messages through an in-VM message broker in order to test its
- * expected behaviour, or to publish and receive (possibly bounced back) messages through a seperate broker instance
- * in order to take performance timings. In the case of performance timings, the co-location of the publisher and
- * receiver means that the timings are taken on the same machine for accurate timing without the need for clock
- * synchronization.
- *
- * <p/><table id="crc"><caption>CRC Card</caption>
- * <tr><th> Responsibilities
- * <tr><td> Manage an m*n array of publisher and recievers.
- * </table>
- */
- public static interface PublisherReceiver
- {
- public ProducerConsumerPair getPublisher();
-
- public ProducerConsumerPair getReceiver();
-
- public void start();
-
- public void send(ParsedProperties testProps, int numMessages);
-
- public ExceptionMonitor getConnectionExceptionMonitor();
-
- public ExceptionMonitor getExceptionMonitor();
-
- public void testWithAssertions(ParsedProperties testProps, Class aClass /*, assertions */);
-
- public void testNoExceptions(ParsedProperties testProps);
-
- public void close();
- }
-
- public static class PublisherReceiverImpl implements PublisherReceiver
- {
- private ProducerConsumerPair publisher;
- private ProducerConsumerPair receiver;
- private Connection connection;
- private ExceptionMonitor connectionExceptionMonitor;
- private ExceptionMonitor exceptionMonitor;
-
- public PublisherReceiverImpl(ProducerConsumerPair publisher, ProducerConsumerPair receiver, Connection connection,
- ExceptionMonitor connectionExceptionMonitor)
- {
- this.publisher = publisher;
- this.receiver = receiver;
- this.connection = connection;
- this.connectionExceptionMonitor = connectionExceptionMonitor;
- this.exceptionMonitor = new ExceptionMonitor();
- }
-
- public ProducerConsumerPair getPublisher()
- {
- return publisher;
- }
-
- public ProducerConsumerPair getReceiver()
- {
- return receiver;
- }
-
- public void start()
- { }
-
- public void close()
- {
- try
- {
- publisher.close();
- receiver.close();
- connection.close();
- }
- catch (JMSException e)
- {
- throw new RuntimeException("Got JMSException during close.", e);
- }
- }
-
- public ExceptionMonitor getConnectionExceptionMonitor()
- {
- return connectionExceptionMonitor;
- }
-
- public ExceptionMonitor getExceptionMonitor()
- {
- return exceptionMonitor;
- }
-
- public void send(ParsedProperties testProps, int numMessages)
- {
- boolean transactional = testProps.getPropertyAsBoolean(TRANSACTED_PROPNAME);
-
- // Send an immediate message through the publisher and ensure that it results in a JMSException.
- try
- {
- getPublisher().send(createTestMessage(getPublisher(), testProps));
-
- if (transactional)
- {
- getPublisher().getSession().commit();
- }
- }
- catch (JMSException e)
- {
- log.debug("Got JMSException: ", e);
- exceptionMonitor.onException(e);
- }
- }
-
- public void testWithAssertions(ParsedProperties testProps, Class aClass /*, assertions */)
- {
- start();
- send(testProps, 1);
- pause(1000L);
-
- String errors = "";
-
- ExceptionMonitor connectionExceptionMonitor = getConnectionExceptionMonitor();
- if (!connectionExceptionMonitor.assertOneJMSExceptionWithLinkedCause(aClass))
- {
- errors += "Was expecting linked exception type " + aClass.getName() + " on the connection.\n";
- errors +=
- (connectionExceptionMonitor.size() > 0)
- ? ("Actually got the following exceptions on the connection, " + connectionExceptionMonitor)
- : "Got no exceptions on the connection.";
- }
-
- // Clean up the publisher/receiver client pair.
- close();
-
- assertEquals(errors, "", errors);
- }
-
- /**
- */
- public void testNoExceptions(ParsedProperties testProps)
- {
- start();
- send(testProps, 1);
- pause(1000L);
-
- String errors = "";
-
- if (!getConnectionExceptionMonitor().assertNoExceptions())
- {
- errors += "Was expecting no exceptions.\n";
- errors += "Got the following exceptions on the connection, " + getConnectionExceptionMonitor();
- }
-
- if (!getExceptionMonitor().assertNoExceptions())
- {
- errors += "Was expecting no exceptions.\n";
- errors += "Got the following exceptions on the producer, " + getExceptionMonitor();
- }
-
- // Clean up the publisher/receiver client pair.
- close();
-
- assertEquals(errors, "", errors);
- }
-
- public static PublisherReceiver connectClients(ParsedProperties testProps)
- {
- // Create a standard publisher/receiver test client pair on a shared connection, individual sessions.
- return createPublisherReceiverPairSharedConnection(testProps);
- }
- }
-
- /**
- * Pauses for the specified length of time. In the event of failing to pause for at least that length of time
- * due to interuption of the thread, a RutimeException is raised to indicate the failure. The interupted status
- * of the thread is restores in that case. This method should only be used when it is expected that the pause
- * will be succesfull, for example in test code that relies on inejecting a pause.
- *
- * @param t The minimum time to pause for in milliseconds.
- */
- public static void pause(long t)
- {
- try
- {
- Thread.sleep(t);
- }
- catch (InterruptedException e)
- {
- // Restore the interrupted status
- Thread.currentThread().interrupt();
-
- throw new RuntimeException("Failed to generate the requested pause length.", e);
- }
}
}
diff --git a/java/systests/src/main/java/org/apache/qpid/server/exchange/MandatoryMessageTest.java b/java/systests/src/main/java/org/apache/qpid/server/exchange/MandatoryMessageTest.java
index 09a32aa3eb..94a33806d0 100644
--- a/java/systests/src/main/java/org/apache/qpid/server/exchange/MandatoryMessageTest.java
+++ b/java/systests/src/main/java/org/apache/qpid/server/exchange/MandatoryMessageTest.java
@@ -20,17 +20,11 @@
*/
package org.apache.qpid.server.exchange;
-import junit.framework.TestCase;
-
-import org.apache.log4j.NDC;
-
-import org.apache.qpid.client.AMQNoRouteException;
-import org.apache.qpid.client.transport.TransportConnection;
-import static org.apache.qpid.server.exchange.MessagingTestConfigProperties.*;
-import org.apache.qpid.server.registry.ApplicationRegistry;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
+import org.apache.qpid.test.framework.sequencers.TestCaseSequencer;
+import org.apache.qpid.test.framework.Circuit;
+import org.apache.qpid.test.framework.FrameworkBaseCase;
+import org.apache.qpid.test.framework.MessagingTestConfigProperties;
+import static org.apache.qpid.test.framework.MessagingTestConfigProperties.*;
import uk.co.thebadgerset.junit.extensions.util.ParsedProperties;
import uk.co.thebadgerset.junit.extensions.util.TestContextProperties;
@@ -43,52 +37,70 @@ import uk.co.thebadgerset.junit.extensions.util.TestContextProperties;
*
* <p><table id="crc"><caption>CRC Card</caption>
* <tr><th> Responsibilities <th> Collaborations
- * <tr><td> Check that a mandatory message is sent succesfully not using transactions when a consumer is connected.
- * <tr><td> Check that a mandatory message is committed succesfully in a transaction when a consumer is connected.
- * <tr><td> Check that a mandatory message results in no route code, not using transactions, when no consumer is
+ * <tr><td> Check that an mandatory message is sent succesfully not using transactions when a consumer is connected.
+ * <tr><td> Check that an mandatory message is committed succesfully in a transaction when a consumer is connected.
+ * <tr><td> Check that a mandatory message is sent succesfully, not using transactions, when a consumer is disconnected
+ * but the route exists.
+ * <tr><td> Check that a mandatory message is sent succesfully, in a transaction, when a consumer is disconnected but
+ * the route exists.
+ * <tr><td> Check that an mandatory message results in no route code, not using transactions, when no consumer is
+ * connected.
+ * <tr><td> Check that an mandatory message results in no route code, upon transaction commit, when a consumer is
* connected.
- * <tr><td> Check that a mandatory message results in no route code, upon transaction commit, when a consumer is
+ * <tr><td> Check that an mandatory message is sent succesfully not using transactions when a consumer is connected.
+ * <tr><td> Check that an mandatory message is committed succesfully in a transaction when a consumer is connected.
+ * <tr><td> Check that a mandatory message is sent succesfully, not using transactions, when a consumer is disconnected
+ * but the route exists.
+ * <tr><td> Check that a mandatory message is sent succesfully, in a transaction, when a consumer is disconnected but
+ * the route exists.
+ * <tr><td> Check that an mandatory message results in no route code, not using transactions, when no consumer is
+ * connected.
+ * <tr><td> Check that an mandatory message results in no route code, upon transaction commit, when a consumer is
* connected.
- * <tr><td> Check that a mandatory message is sent succesfully, not using transactions, when a consumer is
- * disconnected but the route exists.
- * <tr><dt> Check that a mandatory message is send successfully, in a transactions, when a consumer is
- * disconnected but when the route exists.
* </table>
+ *
+ * @todo All of these test cases will be generated by a test generator that thoroughly tests all combinations of test
+ * circuits.
*/
-public class MandatoryMessageTest extends TestCase
+public class MandatoryMessageTest extends FrameworkBaseCase
{
- /** Used for debugging. */
- private static final Logger log = LoggerFactory.getLogger(MandatoryMessageTest.class);
-
/** Used to read the tests configurable properties through. */
ParsedProperties testProps;
+ /**
+ * Creates a new test case with the specified name.
+ *
+ * @param name The test case name.
+ */
+ public MandatoryMessageTest(String name)
+ {
+ super(name);
+ }
+
/** Check that an mandatory message is sent succesfully not using transactions when a consumer is connected. */
- public void test_QPID_508_MandatoryOkNoTxP2P() throws Exception
+ public void test_QPID_508_MandatoryOkNoTxP2P()
{
// Ensure transactional sessions are off.
testProps.setProperty(TRANSACTED_PROPNAME, false);
testProps.setProperty(PUBSUB_PROPNAME, false);
- ImmediateMessageTest.PublisherReceiver testClients =
- ImmediateMessageTest.PublisherReceiverImpl.connectClients(testProps);
-
- // Send one message with no errors.
- testClients.testNoExceptions(testProps);
+ // Run the default test sequence over the test circuit checking for no errors.
+ TestCaseSequencer sequencer = getTestSequencer();
+ Circuit testCircuit = sequencer.createCircuit(testProps);
+ sequencer.sequenceTest(testCircuit, assertionList(testCircuit.getPublisher().noExceptionsAssertion()), testProps);
}
/** Check that an mandatory message is committed succesfully in a transaction when a consumer is connected. */
- public void test_QPID_508_MandatoryOkTxP2P() throws Exception
+ public void test_QPID_508_MandatoryOkTxP2P()
{
// Ensure transactional sessions are off.
testProps.setProperty(TRANSACTED_PROPNAME, true);
testProps.setProperty(PUBSUB_PROPNAME, false);
- ImmediateMessageTest.PublisherReceiver testClients =
- ImmediateMessageTest.PublisherReceiverImpl.connectClients(testProps);
-
- // Send one message with no errors.
- testClients.testNoExceptions(testProps);
+ // Run the default test sequence over the test circuit checking for no errors.
+ TestCaseSequencer sequencer = getTestSequencer();
+ Circuit testCircuit = sequencer.createCircuit(testProps);
+ sequencer.sequenceTest(testCircuit, assertionList(testCircuit.getPublisher().noExceptionsAssertion()), testProps);
}
/**
@@ -101,14 +113,14 @@ public class MandatoryMessageTest extends TestCase
testProps.setProperty(TRANSACTED_PROPNAME, false);
testProps.setProperty(PUBSUB_PROPNAME, false);
- ImmediateMessageTest.PublisherReceiver testClients =
- ImmediateMessageTest.PublisherReceiverImpl.connectClients(testProps);
+ TestCaseSequencer sequencer = getTestSequencer();
+ Circuit testCircuit = sequencer.createCircuit(testProps);
// Disconnect the consumer.
- testClients.getReceiver().getConsumer().close();
+ testCircuit.getReceiver().getConsumer().close();
// Send one message with no errors.
- testClients.testNoExceptions(testProps);
+ sequencer.sequenceTest(testCircuit, assertionList(testCircuit.getPublisher().noExceptionsAssertion()), testProps);
}
/**
@@ -121,78 +133,74 @@ public class MandatoryMessageTest extends TestCase
testProps.setProperty(TRANSACTED_PROPNAME, true);
testProps.setProperty(PUBSUB_PROPNAME, false);
- ImmediateMessageTest.PublisherReceiver testClients =
- ImmediateMessageTest.PublisherReceiverImpl.connectClients(testProps);
+ TestCaseSequencer sequencer = getTestSequencer();
+ Circuit testCircuit = sequencer.createCircuit(testProps);
// Disconnect the consumer.
- testClients.getReceiver().getConsumer().close();
+ testCircuit.getReceiver().getConsumer().close();
// Send one message with no errors.
- testClients.testNoExceptions(testProps);
+ sequencer.sequenceTest(testCircuit, assertionList(testCircuit.getPublisher().noExceptionsAssertion()), testProps);
}
/** Check that an mandatory message results in no route code, not using transactions, when no consumer is connected. */
- public void test_QPID_508_MandatoryFailsNoRouteNoTxP2P() throws Exception
+ public void test_QPID_508_MandatoryFailsNoRouteNoTxP2P()
{
// Ensure transactional sessions are off.
testProps.setProperty(TRANSACTED_PROPNAME, false);
testProps.setProperty(PUBSUB_PROPNAME, false);
- // Set up the messaging topology so that only the publishers producer is bound (do not set up the receiver to
+ // Set up the messaging topology so that only the publishers producer is bound (do not set up the receivers to
// collect its messages).
testProps.setProperty(RECEIVER_CONSUMER_BIND_PROPNAME, false);
- ImmediateMessageTest.PublisherReceiver testClients =
- ImmediateMessageTest.PublisherReceiverImpl.connectClients(testProps);
-
- // Send one message and get a linked no consumers exception.
- testClients.testWithAssertions(testProps, AMQNoRouteException.class);
+ // Send one message and get a linked no route exception.
+ TestCaseSequencer sequencer = getTestSequencer();
+ Circuit testCircuit = sequencer.createCircuit(testProps);
+ sequencer.sequenceTest(testCircuit, assertionList(testCircuit.getPublisher().noRouteAssertion()), testProps);
}
/** Check that an mandatory message results in no route code, upon transaction commit, when a consumer is connected. */
- public void test_QPID_508_MandatoryFailsNoRouteTxP2P() throws Exception
+ public void test_QPID_508_MandatoryFailsNoRouteTxP2P()
{
// Ensure transactional sessions are on.
testProps.setProperty(TRANSACTED_PROPNAME, true);
testProps.setProperty(PUBSUB_PROPNAME, false);
- // Set up the messaging topology so that only the publishers producer is bound (do not set up the receiver to
+ // Set up the messaging topology so that only the publishers producer is bound (do not set up the receivers to
// collect its messages).
testProps.setProperty(RECEIVER_CONSUMER_BIND_PROPNAME, false);
- ImmediateMessageTest.PublisherReceiver testClients =
- ImmediateMessageTest.PublisherReceiverImpl.connectClients(testProps);
-
- // Send one message and get a linked no consumers exception.
- testClients.testWithAssertions(testProps, AMQNoRouteException.class);
+ // Send one message and get a linked no route exception.
+ TestCaseSequencer sequencer = getTestSequencer();
+ Circuit testCircuit = sequencer.createCircuit(testProps);
+ sequencer.sequenceTest(testCircuit, assertionList(testCircuit.getPublisher().noRouteAssertion()), testProps);
}
/** Check that an mandatory message is sent succesfully not using transactions when a consumer is connected. */
- public void test_QPID_508_MandatoryOkNoTxPubSub() throws Exception
+ public void test_QPID_508_MandatoryOkNoTxPubSub()
{
// Ensure transactional sessions are off.
testProps.setProperty(TRANSACTED_PROPNAME, false);
testProps.setProperty(PUBSUB_PROPNAME, true);
- ImmediateMessageTest.PublisherReceiver testClients =
- ImmediateMessageTest.PublisherReceiverImpl.connectClients(testProps);
-
- // Send one message with no errors.
- testClients.testNoExceptions(testProps);
+ // Run the default test sequence over the test circuit checking for no errors.
+ TestCaseSequencer sequencer = getTestSequencer();
+ Circuit testCircuit = sequencer.createCircuit(testProps);
+ sequencer.sequenceTest(testCircuit, assertionList(testCircuit.getPublisher().noExceptionsAssertion()), testProps);
}
/** Check that an mandatory message is committed succesfully in a transaction when a consumer is connected. */
- public void test_QPID_508_MandatoryOkTxPubSub() throws Exception
+ public void test_QPID_508_MandatoryOkTxPubSub()
{
- // Ensure transactional sessions are off.
+ // Ensure transactional sessions are on.
testProps.setProperty(TRANSACTED_PROPNAME, true);
testProps.setProperty(PUBSUB_PROPNAME, true);
- ImmediateMessageTest.PublisherReceiver testClients =
- ImmediateMessageTest.PublisherReceiverImpl.connectClients(testProps);
-
- // Send one message with no errors.
- testClients.testNoExceptions(testProps);
+ // Run the default test sequence over the test circuit checking for no errors.
+ TestCaseSequencer sequencer = getTestSequencer();
+ Circuit testCircuit = sequencer.createCircuit(testProps);
+ sequencer.sequenceTest(testCircuit, assertionList(testCircuit.getPublisher().noExceptionsAssertion()), testProps);
}
/**
@@ -208,14 +216,14 @@ public class MandatoryMessageTest extends TestCase
// Use durable subscriptions, so that the route remains open with no subscribers.
testProps.setProperty(DURABLE_SUBSCRIPTION_PROPNAME, true);
- ImmediateMessageTest.PublisherReceiver testClients =
- ImmediateMessageTest.PublisherReceiverImpl.connectClients(testProps);
+ TestCaseSequencer sequencer = getTestSequencer();
+ Circuit testCircuit = sequencer.createCircuit(testProps);
// Disconnect the consumer.
- testClients.getReceiver().getConsumer().close();
+ testCircuit.getReceiver().getConsumer().close();
// Send one message with no errors.
- testClients.testNoExceptions(testProps);
+ sequencer.sequenceTest(testCircuit, assertionList(testCircuit.getPublisher().noExceptionsAssertion()), testProps);
}
/**
@@ -231,79 +239,61 @@ public class MandatoryMessageTest extends TestCase
// Use durable subscriptions, so that the route remains open with no subscribers.
testProps.setProperty(DURABLE_SUBSCRIPTION_PROPNAME, true);
- ImmediateMessageTest.PublisherReceiver testClients =
- ImmediateMessageTest.PublisherReceiverImpl.connectClients(testProps);
+ TestCaseSequencer sequencer = getTestSequencer();
+ Circuit testCircuit = sequencer.createCircuit(testProps);
// Disconnect the consumer.
- testClients.getReceiver().getConsumer().close();
+ testCircuit.getReceiver().getConsumer().close();
// Send one message with no errors.
- testClients.testNoExceptions(testProps);
+ sequencer.sequenceTest(testCircuit, assertionList(testCircuit.getPublisher().noExceptionsAssertion()), testProps);
}
/** Check that an mandatory message results in no route code, not using transactions, when no consumer is connected. */
- public void test_QPID_508_MandatoryFailsNoRouteNoTxPubSub() throws Exception
+ public void test_QPID_508_MandatoryFailsNoRouteNoTxPubSub()
{
// Ensure transactional sessions are off.
testProps.setProperty(TRANSACTED_PROPNAME, false);
testProps.setProperty(PUBSUB_PROPNAME, true);
- // Set up the messaging topology so that only the publishers producer is bound (do not set up the receiver to
+ // Set up the messaging topology so that only the publishers producer is bound (do not set up the receivers to
// collect its messages).
testProps.setProperty(RECEIVER_CONSUMER_BIND_PROPNAME, false);
- ImmediateMessageTest.PublisherReceiver testClients =
- ImmediateMessageTest.PublisherReceiverImpl.connectClients(testProps);
-
- // Send one message and get a linked no consumers exception.
- testClients.testWithAssertions(testProps, AMQNoRouteException.class);
+ // Send one message and get a linked no route exception.
+ TestCaseSequencer sequencer = getTestSequencer();
+ Circuit testCircuit = sequencer.createCircuit(testProps);
+ sequencer.sequenceTest(testCircuit, assertionList(testCircuit.getPublisher().noRouteAssertion()), testProps);
}
/** Check that an mandatory message results in no route code, upon transaction commit, when a consumer is connected. */
- public void test_QPID_508_MandatoryFailsNoRouteTxPubSub() throws Exception
+ public void test_QPID_508_MandatoryFailsNoRouteTxPubSub()
{
// Ensure transactional sessions are on.
testProps.setProperty(TRANSACTED_PROPNAME, true);
testProps.setProperty(PUBSUB_PROPNAME, true);
- // Set up the messaging topology so that only the publishers producer is bound (do not set up the receiver to
+ // Set up the messaging topology so that only the publishers producer is bound (do not set up the receivers to
// collect its messages).
testProps.setProperty(RECEIVER_CONSUMER_BIND_PROPNAME, false);
- ImmediateMessageTest.PublisherReceiver testClients =
- ImmediateMessageTest.PublisherReceiverImpl.connectClients(testProps);
-
- // Send one message and get a linked no consumers exception.
- testClients.testWithAssertions(testProps, AMQNoRouteException.class);
+ // Send one message and get a linked no route exception.
+ TestCaseSequencer sequencer = getTestSequencer();
+ Circuit testCircuit = sequencer.createCircuit(testProps);
+ sequencer.sequenceTest(testCircuit, assertionList(testCircuit.getPublisher().noRouteAssertion()), testProps);
}
protected void setUp() throws Exception
{
- NDC.push(getName());
+ super.setUp();
testProps = TestContextProperties.getInstance(MessagingTestConfigProperties.defaults);
/** All these tests should have the mandatory flag on. */
+ testProps.setProperty(IMMEDIATE_PROPNAME, false);
testProps.setProperty(MANDATORY_PROPNAME, true);
/** Bind the receivers consumer by default. */
testProps.setProperty(RECEIVER_CONSUMER_BIND_PROPNAME, true);
-
- // Ensure that the in-vm broker is created.
- TransportConnection.createVMBroker(1);
- }
-
- protected void tearDown() throws Exception
- {
- try
- {
- // Ensure that the in-vm broker is cleaned up so that the next test starts afresh.
- TransportConnection.killVMBroker(1);
- ApplicationRegistry.remove(1);
- }
- finally
- {
- NDC.pop();
- }
}
}
diff --git a/java/systests/src/main/java/org/apache/qpid/server/exchange/ReturnUnroutableMandatoryMessageTest.java b/java/systests/src/main/java/org/apache/qpid/server/exchange/ReturnUnroutableMandatoryMessageTest.java
index a6a2bbb80f..191f38f1b2 100644
--- a/java/systests/src/main/java/org/apache/qpid/server/exchange/ReturnUnroutableMandatoryMessageTest.java
+++ b/java/systests/src/main/java/org/apache/qpid/server/exchange/ReturnUnroutableMandatoryMessageTest.java
@@ -126,8 +126,8 @@ public class ReturnUnroutableMandatoryMessageTest extends TestCase implements Ex
con.start();
TextMessage tm = (TextMessage) consumer.receive(1000L);
- assertTrue("No message routed to receiver", tm != null);
- assertTrue("Wrong message routed to receiver: " + tm.getText(), "msg3".equals(tm.getText()));
+ assertTrue("No message routed to receivers", tm != null);
+ assertTrue("Wrong message routed to receivers: " + tm.getText(), "msg3".equals(tm.getText()));
try
{
@@ -193,8 +193,8 @@ public class ReturnUnroutableMandatoryMessageTest extends TestCase implements Ex
con.start();
TextMessage tm = (TextMessage) consumer.receive(1000L);
- assertTrue("No message routed to receiver", tm != null);
- assertTrue("Wrong message routed to receiver: " + tm.getText(), "msg1".equals(tm.getText()));
+ assertTrue("No message routed to receivers", tm != null);
+ assertTrue("Wrong message routed to receivers: " + tm.getText(), "msg1".equals(tm.getText()));
try
{
@@ -259,8 +259,8 @@ public class ReturnUnroutableMandatoryMessageTest extends TestCase implements Ex
con.start();
TextMessage tm = (TextMessage) consumer.receive(1000L);
- assertTrue("No message routed to receiver", tm != null);
- assertTrue("Wrong message routed to receiver: " + tm.getText(), "msg1".equals(tm.getText()));
+ assertTrue("No message routed to receivers", tm != null);
+ assertTrue("Wrong message routed to receivers: " + tm.getText(), "msg1".equals(tm.getText()));
try
{
diff --git a/java/systests/src/main/java/org/apache/qpid/server/protocol/AMQProtocolSessionMBeanTest.java b/java/systests/src/main/java/org/apache/qpid/server/protocol/AMQProtocolSessionMBeanTest.java
index 6f14956cc4..14d45807dd 100644
--- a/java/systests/src/main/java/org/apache/qpid/server/protocol/AMQProtocolSessionMBeanTest.java
+++ b/java/systests/src/main/java/org/apache/qpid/server/protocol/AMQProtocolSessionMBeanTest.java
@@ -1,18 +1,21 @@
/*
*
- * Copyright (c) 2006 The Apache Software Foundation
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
*
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
+ * http://www.apache.org/licenses/LICENSE-2.0
*
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT 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;
diff --git a/java/systests/src/main/java/org/apache/qpid/server/protocol/MaxChannelsTest.java b/java/systests/src/main/java/org/apache/qpid/server/protocol/MaxChannelsTest.java
index dc1f592679..b507bee16e 100644
--- a/java/systests/src/main/java/org/apache/qpid/server/protocol/MaxChannelsTest.java
+++ b/java/systests/src/main/java/org/apache/qpid/server/protocol/MaxChannelsTest.java
@@ -1,18 +1,21 @@
/*
*
- * Copyright (c) 2006 The Apache Software Foundation
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
*
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
+ * http://www.apache.org/licenses/LICENSE-2.0
*
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT 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;
diff --git a/java/systests/src/main/java/org/apache/qpid/server/queue/PersistentTestManual.java b/java/systests/src/main/java/org/apache/qpid/server/queue/PersistentTestManual.java
index 5abbbd2aae..d01284cb8a 100644
--- a/java/systests/src/main/java/org/apache/qpid/server/queue/PersistentTestManual.java
+++ b/java/systests/src/main/java/org/apache/qpid/server/queue/PersistentTestManual.java
@@ -1,39 +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
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
*
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT 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.client.AMQConnection;
-import org.apache.qpid.client.AMQSession;
-import org.apache.qpid.AMQException;
+import org.apache.log4j.Logger;
+
import org.apache.qpid.AMQChannelClosedException;
import org.apache.qpid.AMQConnectionClosedException;
-import org.apache.qpid.util.CommandLineParser;
+import org.apache.qpid.AMQException;
+import org.apache.qpid.client.AMQConnection;
+import org.apache.qpid.client.AMQSession;
import org.apache.qpid.url.URLSyntaxException;
-import org.apache.log4j.Logger;
+import org.apache.qpid.util.CommandLineParser;
-import javax.jms.Session;
import javax.jms.JMSException;
-import javax.jms.Queue;
import javax.jms.MessageProducer;
+import javax.jms.Queue;
+import javax.jms.Session;
import javax.jms.TextMessage;
+
import java.io.IOException;
import java.util.Properties;
@@ -41,7 +43,6 @@ public class PersistentTestManual
{
private static final Logger _logger = Logger.getLogger(PersistentTestManual.class);
-
private static final String QUEUE = "direct://amq.direct//PersistentTest-Queue2?durable='true',exclusive='true'";
protected AMQConnection _connection;
@@ -89,7 +90,7 @@ public class PersistentTestManual
public void test() throws AMQException, URLSyntaxException
{
- //Create the Durable Queue
+ // Create the Durable Queue
try
{
_session.createConsumer(_session.createQueue(QUEUE)).close();
@@ -121,16 +122,17 @@ public class PersistentTestManual
System.out.println("Continuing....");
}
- //Test queue is still there.
- AMQConnection connection = new AMQConnection(_brokerDetails, _username, _password, "DifferentClientID", _virtualpath);
+ // Test queue is still there.
+ AMQConnection connection =
+ new AMQConnection(_brokerDetails, _username, _password, "DifferentClientID", _virtualpath);
AMQSession session = (AMQSession) connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
try
{
session.createConsumer(session.createQueue(QUEUE));
- _logger.error("Create consumer succeeded." +
- " This shouldn't be allowed as this means the queue didn't exist when it should");
+ _logger.error("Create consumer succeeded."
+ + " This shouldn't be allowed as this means the queue didn't exist when it should");
connection.close();
@@ -189,6 +191,7 @@ public class PersistentTestManual
{
//
}
+
System.exit(0);
}
@@ -196,7 +199,7 @@ public class PersistentTestManual
{
String TEST_TEXT = "init";
- //Create a new session to send producer
+ // Create a new session to send producer
Session session = _connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
Queue q = session.createQueue(QUEUE);
@@ -204,10 +207,9 @@ public class PersistentTestManual
producer.send(session.createTextMessage(TEST_TEXT));
- //create a new consumer on the original session
+ // create a new consumer on the original session
TextMessage m = (TextMessage) _session.createConsumer(q).receive();
-
if ((m != null) && m.getText().equals(TEST_TEXT))
{
return true;
@@ -216,6 +218,7 @@ public class PersistentTestManual
{
_logger.error("Incorrect values returned from Queue Test:" + m);
System.exit(0);
+
return false;
}
}
@@ -259,8 +262,8 @@ public class PersistentTestManual
{
PersistentTestManual test;
- Properties options = CommandLineParser.processCommandLine(args, new CommandLineParser(new String[][]{}));
-
+ Properties options =
+ CommandLineParser.processCommandLine(args, new CommandLineParser(new String[][] {}), System.getProperties());
test = new PersistentTestManual(options);
try
diff --git a/java/systests/src/main/java/org/apache/qpid/test/VMTestCase.java b/java/systests/src/main/java/org/apache/qpid/test/VMTestCase.java
index 540c91ddaf..9629f87d46 100644
--- a/java/systests/src/main/java/org/apache/qpid/test/VMTestCase.java
+++ b/java/systests/src/main/java/org/apache/qpid/test/VMTestCase.java
@@ -1,4 +1,5 @@
/*
+ *
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
@@ -20,29 +21,32 @@
package org.apache.qpid.test;
import junit.extensions.TestSetup;
+
import junit.framework.Test;
import junit.framework.TestCase;
import org.apache.qpid.client.transport.TransportConnection;
import org.apache.qpid.jndi.PropertiesFileInitialContextFactory;
+import org.apache.qpid.server.registry.ApplicationRegistry;
-import javax.naming.Context;
-import javax.naming.spi.InitialContextFactory;
-import javax.jms.Queue;
-import javax.jms.ConnectionFactory;
-import javax.jms.Session;
import javax.jms.Connection;
+import javax.jms.ConnectionFactory;
import javax.jms.MessageProducer;
+import javax.jms.Queue;
+import javax.jms.Session;
+import javax.naming.Context;
+import javax.naming.spi.InitialContextFactory;
+
+import java.util.HashMap;
import java.util.Hashtable;
-import java.util.List;
import java.util.LinkedList;
+import java.util.List;
import java.util.Map;
-import java.util.HashMap;
public class VMTestCase extends TestCase
{
- protected long RECEIVE_TIMEOUT = 1000l; // 1 sec
- protected long CLOSE_TIMEOUT = 10000l; // 10 secs
+ protected long RECEIVE_TIMEOUT = 1000L; // 1 sec
+ protected long CLOSE_TIMEOUT = 10000L; // 10 secs
protected Context _context;
protected String _clientID;
@@ -84,8 +88,8 @@ public class VMTestCase extends TestCase
_brokerlist = "vm://:1";
}
- env.put("connectionfactory.connection", "amqp://guest:guest@" +
- _clientID + _virtualhost + "?brokerlist='" + _brokerlist + "'");
+ env.put("connectionfactory.connection", "amqp://guest:guest@" + _clientID + _virtualhost + "?brokerlist='"
+ + _brokerlist + "'");
for (Map.Entry<String, String> c : _connections.entrySet())
{
@@ -112,6 +116,8 @@ public class VMTestCase extends TestCase
protected void tearDown() throws Exception
{
TransportConnection.killVMBroker(1);
+ ApplicationRegistry.remove(1);
+
super.tearDown();
}
diff --git a/java/systests/src/main/java/org/apache/qpid/test/framework/Assertion.java b/java/systests/src/main/java/org/apache/qpid/test/framework/Assertion.java
new file mode 100644
index 0000000000..75c1c97999
--- /dev/null
+++ b/java/systests/src/main/java/org/apache/qpid/test/framework/Assertion.java
@@ -0,0 +1,39 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.qpid.test.framework;
+
+/**
+ * Assertion models an assertion on a test {@link Circuit}.
+ *
+ * <p/><table id="crc"><caption>CRC Card</caption>
+ * <tr><th> Responsibilities
+ * <tr><td> Indicate whether or not the assertion passes when applied.
+ * </table>
+ */
+public interface Assertion
+{
+ /**
+ * Applies the assertion.
+ *
+ * @return <tt>true</tt> if the assertion passes, <tt>false</tt> if it fails.
+ */
+ public boolean apply();
+}
diff --git a/java/systests/src/main/java/org/apache/qpid/test/framework/AssertionBase.java b/java/systests/src/main/java/org/apache/qpid/test/framework/AssertionBase.java
new file mode 100644
index 0000000000..3d83224513
--- /dev/null
+++ b/java/systests/src/main/java/org/apache/qpid/test/framework/AssertionBase.java
@@ -0,0 +1,66 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT 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.framework;
+
+import java.util.LinkedList;
+import java.util.List;
+
+/**
+ * AssertionBase is a base class for implenmenting assertions. It provides a mechanism to store error messages, and
+ * report all error messages when its {@link #toString()} method is called.
+ *
+ * <p/><table id="crc"><caption>CRC Card</caption>
+ * <tr><th> Responsibilities <th> Collaborations
+ * <tr><td> Collect error messages.
+ * </table>
+ */
+public abstract class AssertionBase implements Assertion
+{
+ /** Holds the error messages. */
+ List<String> errors = new LinkedList<String>();
+
+ /**
+ * Adds an error message to the assertion.
+ *
+ * @param error An error message to add to the assertion.
+ */
+ public void addError(String error)
+ {
+ errors.add(error);
+ }
+
+ /**
+ * Prints all of the error messages in the assertion into a string.
+ *
+ * @return All of the error messages in the assertion as a string.
+ */
+ public String toString()
+ {
+ String result = "";
+
+ for (String error : errors)
+ {
+ result += error;
+ }
+
+ return result;
+ }
+}
diff --git a/java/systests/src/main/java/org/apache/qpid/test/framework/Circuit.java b/java/systests/src/main/java/org/apache/qpid/test/framework/Circuit.java
new file mode 100644
index 0000000000..d665acb62c
--- /dev/null
+++ b/java/systests/src/main/java/org/apache/qpid/test/framework/Circuit.java
@@ -0,0 +1,109 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT 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.framework;
+
+import java.util.List;
+
+/**
+ * A Circuit is the basic test unit against which test cases are to be written. A circuit consists of two 'ends', an
+ * instigating 'publisher' end and a more passive 'receivers' end.
+ *
+ * <p/>Once created, the life-cycle of a circuit may be controlled by {@link #start()}ing it, or {@link #close()}ing it.
+ * Once started, the circuit is ready to send messages over. Once closed the circuit can no longer be used.
+ *
+ * <p/>The state of the circuit may be taken with the {@link #check()} method, and asserted against by the
+ * {@link #applyAssertions(java.util.List)} method.
+ *
+ * <p/>There is a default test procedure which may be performed against the circuit. The outline of this procedure is:
+ *
+ * <p/><pre>
+ * Start the circuit.
+ * Send test messages.
+ * Request a status report.
+ * Assert conditions on the publishing end of the circuit.
+ * Assert conditions on the receiving end of the circuit.
+ * Close the circuit.
+ * Pass with no failed assertions or fail with a list of failed assertions.
+ * </pre>
+ *
+ * <p/><table id="crc"><caption>CRC Card</caption>
+ * <tr><th> Responsibilities
+ * <tr><td> Supply the publishing and receiving ends of a test messaging circuit.
+ * <tr><td> Start the circuit running.
+ * <tr><td> Close the circuit down.
+ * <tr><td> Take a reading of the circuits state.
+ * <tr><td> Apply assertions against the circuits state.
+ * <tr><td> Send test messages over the circuit.
+ * <tr><td> Perform the default test procedue on the circuit.
+ * </table>
+ */
+public interface Circuit
+{
+ /**
+ * Gets the interface on the publishing end of the circuit.
+ *
+ * @return The publishing end of the circuit.
+ */
+ public Publisher getPublisher();
+
+ /**
+ * Gets the interface on the receiving end of the circuit.
+ *
+ * @return The receiving end of the circuit.
+ */
+ public Receiver getReceiver();
+
+ /**
+ * Connects and starts the circuit. After this method is called the circuit is ready to send messages.
+ */
+ public void start();
+
+ /**
+ * Checks the test circuit. The effect of this is to gather the circuits state, for both ends of the circuit,
+ * into a report, against which assertions may be checked.
+ */
+ public void check();
+
+ /**
+ * Closes the circuit. All associated resources are closed.
+ */
+ public void close();
+
+ /**
+ * Applied a list of assertions against the test circuit. The {@link #check()} method should be called before doing
+ * this, to ensure that the circuit has gathered its state into a report to assert against.
+ *
+ * @param assertions The list of assertions to apply to the circuit.
+ *
+ * @return Any assertions that failed.
+ */
+ public List<Assertion> applyAssertions(List<Assertion> assertions);
+
+ /**
+ * Runs the default test procedure against the circuit, and checks that all of the specified assertions hold.
+ *
+ * @param numMessages The number of messages to send using the default test procedure.
+ * @param assertions The list of assertions to apply.
+ *
+ * @return Any assertions that failed.
+ */
+ public List<Assertion> test(int numMessages, List<Assertion> assertions);
+}
diff --git a/java/systests/src/main/java/org/apache/qpid/test/framework/CircuitEnd.java b/java/systests/src/main/java/org/apache/qpid/test/framework/CircuitEnd.java
new file mode 100644
index 0000000000..43c3fa4c66
--- /dev/null
+++ b/java/systests/src/main/java/org/apache/qpid/test/framework/CircuitEnd.java
@@ -0,0 +1,77 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT 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.framework;
+
+import javax.jms.*;
+
+/**
+ * A CircuitEnd is a pair consisting of one message producer and one message consumer, that represents one end of a
+ * test circuit. It is a standard unit of connectivity allowing a full-duplex conversation to be held, provided both
+ * the consumer and producer are instantiated and configured.
+ *
+ * <p/><table id="crc"><caption>CRC Card</caption>
+ * <tr><th> Responsibilities
+ * <tr><td> Provide a message producer for sending messages.
+ * <tr><td> Provide a message consumer for receiving messages.
+ * </table>
+ *
+ * @todo Update the {@link org.apache.qpid.util.ConversationFactory} so that it accepts these as the basic conversation
+ * connection units.
+ */
+public interface CircuitEnd
+{
+ /**
+ * Gets the message producer at this circuit end point.
+ *
+ * @return The message producer at with this circuit end point.
+ */
+ public MessageProducer getProducer();
+
+ /**
+ * Gets the message consumer at this circuit end point.
+ *
+ * @return The message consumer at this circuit end point.
+ */
+ public MessageConsumer getConsumer();
+
+ /**
+ * Send the specified message over the producer at this end point.
+ *
+ * @param message The message to send.
+ *
+ * @throws JMSException Any JMS exception occuring during the send is allowed to fall through.
+ */
+ public void send(Message message) throws JMSException;
+
+ /**
+ * Gets the JMS Session associated with this circuit end point.
+ *
+ * @return The JMS Session associated with this circuit end point.
+ */
+ public Session getSession();
+
+ /**
+ * Closes the message producers and consumers and the sessions, associated with this circuit end point.
+ *
+ * @throws JMSException Any JMSExceptions occurring during the close are allowed to fall through.
+ */
+ public void close() throws JMSException;
+}
diff --git a/java/systests/src/main/java/org/apache/qpid/test/framework/CircuitEndBase.java b/java/systests/src/main/java/org/apache/qpid/test/framework/CircuitEndBase.java
new file mode 100644
index 0000000000..54a30d9c6e
--- /dev/null
+++ b/java/systests/src/main/java/org/apache/qpid/test/framework/CircuitEndBase.java
@@ -0,0 +1,119 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT 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.framework;
+
+import javax.jms.*;
+
+/**
+ * A CircuitEndBase is a pair consisting of one message producer and one message consumer, that represents one end of a
+ * test circuit. It is a standard unit of connectivity allowing a full-duplex conversation to be held, provided both
+ * the consumer and producer are instantiated and configured.
+ *
+ * <p/><table id="crc"><caption>CRC Card</caption>
+ * <tr><th> Responsibilities
+ * <tr><td> Provide a message producer for sending messages.
+ * <tr><td> Provide a message consumer for receiving messages.
+ * </table>
+ */
+public class CircuitEndBase implements CircuitEnd
+{
+ /** Holds the single message producer. */
+ MessageProducer producer;
+
+ /** Holds the single message consumer. */
+ MessageConsumer consumer;
+
+ /** Holds the session for the circuit end. */
+ Session session;
+
+ /**
+ * Creates a circuit end point on the specified producer, consumer and session.
+ *
+ * @param producer The message producer for the circuit end point.
+ * @param consumer The message consumer for the circuit end point.
+ * @param session The session for the circuit end point.
+ */
+ public CircuitEndBase(MessageProducer producer, MessageConsumer consumer, Session session)
+ {
+ this.producer = producer;
+ this.consumer = consumer;
+ this.session = session;
+ }
+
+ /**
+ * Gets the message producer at this circuit end point.
+ *
+ * @return The message producer at with this circuit end point.
+ */
+ public MessageProducer getProducer()
+ {
+ return producer;
+ }
+
+ /**
+ * Gets the message consumer at this circuit end point.
+ *
+ * @return The message consumer at this circuit end point.
+ */
+ public MessageConsumer getConsumer()
+ {
+ return consumer;
+ }
+
+ /**
+ * Send the specified message over the producer at this end point.
+ *
+ * @param message The message to send.
+ * @throws javax.jms.JMSException Any JMS exception occuring during the send is allowed to fall through.
+ */
+ public void send(Message message) throws JMSException
+ {
+ producer.send(message);
+ }
+
+ /**
+ * Gets the JMS Session associated with this circuit end point.
+ *
+ * @return The JMS Session associated with this circuit end point.
+ */
+ public Session getSession()
+ {
+ return session;
+ }
+
+ /**
+ * Closes the message producers and consumers and the sessions, associated with this circuit end point.
+ *
+ * @throws javax.jms.JMSException Any JMSExceptions occurring during the close are allowed to fall through.
+ */
+ public void close() throws JMSException
+ {
+ if (producer != null)
+ {
+ producer.close();
+ }
+
+ if (consumer != null)
+ {
+ consumer.close();
+ }
+ }
+}
diff --git a/java/systests/src/main/java/org/apache/qpid/test/framework/DropInTest.java b/java/systests/src/main/java/org/apache/qpid/test/framework/DropInTest.java
new file mode 100644
index 0000000000..12cf0d79d5
--- /dev/null
+++ b/java/systests/src/main/java/org/apache/qpid/test/framework/DropInTest.java
@@ -0,0 +1,51 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.qpid.test.framework;
+
+import javax.jms.JMSException;
+import javax.jms.Message;
+
+/**
+ * A DropIn test is a test case that can accept late joining test clients into a running test. This can be usefull,
+ * for interactive experimentation.
+ *
+ * <p/><table id="crc"><caption>CRC Card</caption>
+ * <tr><th> Responsibilities
+ * <tr><td> Accept late joining test clients.
+ * </table>
+ */
+public interface DropInTest
+{
+ /**
+ * Should accept a late joining client into a running test case. The client will be enlisted with a control message
+ * with the 'CONTROL_TYPE' field set to the value 'LATEJOIN'. It should also provide values for the fields:
+ *
+ * <p/><table>
+ * <tr><td> CLIENT_NAME <td> A unique name for the new client.
+ * <tr><td> CLIENT_PRIVATE_CONTROL_KEY <td> The key for the route on which the client receives its control messages.
+ * </table>
+ *
+ * @param message The late joiners join message.
+ *
+ * @throws JMSException Any JMS Exception are allowed to fall through, indicating that the join failed.
+ */
+ public void lateJoin(Message message) throws JMSException;
+}
diff --git a/java/systests/src/main/java/org/apache/qpid/test/framework/ExceptionMonitor.java b/java/systests/src/main/java/org/apache/qpid/test/framework/ExceptionMonitor.java
new file mode 100644
index 0000000000..606f2eabda
--- /dev/null
+++ b/java/systests/src/main/java/org/apache/qpid/test/framework/ExceptionMonitor.java
@@ -0,0 +1,151 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.qpid.test.framework;
+
+import javax.jms.ExceptionListener;
+import javax.jms.JMSException;
+
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * An exception monitor, listens for JMS exception on a connection or consumer. It record all exceptions that it receives
+ * and provides methods to test the number and type of exceptions received.
+ *
+ * <p/><table id="crc"><caption>CRC Card</caption>
+ * <tr><th> Responsibilities <th> Collaborations
+ * <tr><td> Record all exceptions received. <td> {@link ExceptionListener}
+ * </table>
+ */
+public class ExceptionMonitor implements ExceptionListener
+{
+ /** Holds the received exceptions. */
+ List<JMSException> exceptions = new ArrayList<JMSException>();
+
+ /**
+ * Receives incoming exceptions.
+ *
+ * @param e The exception to record.
+ */
+ public void onException(JMSException e)
+ {
+ exceptions.add(e);
+ }
+
+ /**
+ * Checks that no exceptions have been received.
+ *
+ * @return <tt>true</tt> if no exceptions have been received, <tt>false</tt> otherwise.
+ */
+ public boolean assertNoExceptions()
+ {
+ return exceptions.isEmpty();
+ }
+
+ /**
+ * Checks that exactly one exception has been received.
+ *
+ * @return <tt>true</tt> if exactly one exception been received, <tt>false</tt> otherwise.
+ */
+ public boolean assertOneJMSException()
+ {
+ return exceptions.size() == 1;
+ }
+
+ /**
+ * Checks that exactly one exception, with a linked cause of the specified type, has been received.
+ *
+ * @return <tt>true</tt> if exactly one exception, with a linked cause of the specified type, been received,
+ * <tt>false</tt> otherwise.
+ */
+ public boolean assertOneJMSExceptionWithLinkedCause(Class aClass)
+ {
+ if (exceptions.size() == 1)
+ {
+ JMSException e = exceptions.get(0);
+
+ Exception linkedCause = e.getLinkedException();
+
+ if ((linkedCause != null) && aClass.isInstance(linkedCause))
+ {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ /**
+ * Reports the number of exceptions held by this monitor.
+ *
+ * @return The number of exceptions held by this monitor.
+ */
+ public int size()
+ {
+ return exceptions.size();
+ }
+
+ /**
+ * Clears the record of received exceptions.
+ */
+ public void reset()
+ {
+ exceptions = new ArrayList();
+ }
+
+ /**
+ * Provides a dump of the stack traces of all exceptions that this exception monitor was notified of. Mainly
+ * use for debugging/test failure reporting purposes.
+ *
+ * @return A string containing a dump of the stack traces of all exceptions.
+ */
+ public String toString()
+ {
+ String result = "ExceptionMonitor: holds " + exceptions.size() + " exceptions.\n\n";
+
+ for (JMSException ex : exceptions)
+ {
+ result += getStackTrace(ex) + "\n";
+ }
+
+ return result;
+ }
+
+ /**
+ * Prints an exception stack trace into a string.
+ *
+ * @param t The throwable to get the stack trace from.
+ *
+ * @return A string containing the throwables stack trace.
+ */
+ public static String getStackTrace(Throwable t)
+ {
+ StringWriter sw = new StringWriter();
+ PrintWriter pw = new PrintWriter(sw, true);
+ t.printStackTrace(pw);
+ pw.flush();
+ sw.flush();
+
+ return sw.toString();
+ }
+}
diff --git a/java/systests/src/main/java/org/apache/qpid/test/framework/FrameworkBaseCase.java b/java/systests/src/main/java/org/apache/qpid/test/framework/FrameworkBaseCase.java
new file mode 100644
index 0000000000..d6cb0cad13
--- /dev/null
+++ b/java/systests/src/main/java/org/apache/qpid/test/framework/FrameworkBaseCase.java
@@ -0,0 +1,207 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT 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.framework;
+
+import junit.framework.TestCase;
+
+import org.apache.log4j.NDC;
+
+import org.apache.qpid.client.transport.TransportConnection;
+import org.apache.qpid.test.framework.sequencers.TestCaseSequencer;
+import org.apache.qpid.server.registry.ApplicationRegistry;
+import org.apache.qpid.test.framework.localcircuit.CircuitImpl;
+
+import uk.co.thebadgerset.junit.extensions.util.ParsedProperties;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Properties;
+
+/**
+ * FrameworkBaseCase provides a starting point for writing test cases against the test framework. Its main purpose is
+ * to provide some convenience methods for testing.
+ *
+ * <p/><table id="crc"><caption>CRC Card</caption>
+ * <tr><th> Responsibilities <th> Collaborations
+ * <tr><td> Create and clean up in-vm brokers on every test case.
+ * <tr><td> Produce lists of assertions from assertion creation calls.
+ * <tr><td> Produce JUnit failures from assertion failures.
+ * <tr><td> Convert failed assertions to error messages.
+ * </table>
+ */
+public class FrameworkBaseCase extends TestCase
+{
+ /** Holds the test sequencer to create and run test circuits with. */
+ protected TestCaseSequencer testSequencer = new DefaultTestSequencer();
+
+ /**
+ * Creates a new test case with the specified name.
+ *
+ * @param name The test case name.
+ */
+ public FrameworkBaseCase(String name)
+ {
+ super(name);
+ }
+
+ /**
+ * Returns the test case sequencer that provides test circuit, and test sequence implementations. The sequencer
+ * that this base case returns by default is suitable for running a test circuit with both circuit ends colocated
+ * on the same JVM.
+ *
+ * @return The test case sequencer.
+ */
+ protected TestCaseSequencer getTestSequencer()
+ {
+ return testSequencer;
+ }
+
+ /**
+ * Overrides the default test sequencer. Test decorators can use this to supply distributed test sequencers or other
+ * test sequencer specializations.
+ *
+ * @param sequencer The new test sequencer.
+ */
+ public void setTestSequencer(TestCaseSequencer sequencer)
+ {
+ this.testSequencer = sequencer;
+ }
+
+ /**
+ * Creates a list of assertions.
+ *
+ * @param asserts The assertions to compile in a list.
+ *
+ * @return A list of assertions.
+ */
+ protected List<Assertion> assertionList(Assertion... asserts)
+ {
+ List<Assertion> result = new ArrayList<Assertion>();
+
+ for (Assertion assertion : asserts)
+ {
+ result.add(assertion);
+ }
+
+ return result;
+ }
+
+ /**
+ * Generates a JUnit assertion exception (failure) if any assertions are passed into this method, also concatenating
+ * all of the error messages in the assertions together to form an error message to diagnose the test failure with.
+ *
+ * @param asserts The list of failed assertions.
+ */
+ protected void assertNoFailures(List<Assertion> asserts)
+ {
+ // Check if there are no assertion failures, and return without doing anything if so.
+ if ((asserts == null) || asserts.isEmpty())
+ {
+ return;
+ }
+
+ // Compile all of the assertion failure messages together.
+ String errorMessage = assertionsToString(asserts);
+
+ // Fail with the error message from all of the assertions.
+ fail(errorMessage);
+ }
+
+ /**
+ * Converts a list of failed assertions into an error message.
+ *
+ * @param asserts The failed assertions.
+ *
+ * @return The error message.
+ */
+ protected String assertionsToString(List<Assertion> asserts)
+ {
+ String errorMessage = "";
+
+ for (Assertion assertion : asserts)
+ {
+ errorMessage += assertion.toString() + "\n";
+ }
+
+ return errorMessage;
+ }
+
+ /**
+ * Ensures that the in-vm broker is created and initialized.
+ *
+ * @throws Exception Any exceptions allowed to fall through and fail the test.
+ */
+ protected void setUp() throws Exception
+ {
+ NDC.push(getName());
+
+ // Ensure that the in-vm broker is created.
+ TransportConnection.createVMBroker(1);
+ }
+
+ /**
+ * Ensures that the in-vm broker is cleaned up after each test run.
+ */
+ protected void tearDown()
+ {
+ try
+ {
+ // Ensure that the in-vm broker is cleaned up so that the next test starts afresh.
+ TransportConnection.killVMBroker(1);
+ ApplicationRegistry.remove(1);
+ }
+ finally
+ {
+ NDC.pop();
+ }
+ }
+
+ /**
+ * DefaultTestSequencer is a test sequencer that creates test circuits with publishing and receiving ends rooted
+ * on the same JVM.
+ */
+ public class DefaultTestSequencer implements TestCaseSequencer
+ {
+ /**
+ * Holds a test coordinating conversation with the test clients. This should consist of assigning the test roles,
+ * begining the test and gathering the test reports from the participants.
+ *
+ * @param testCircuit The test circuit.
+ * @param assertions The list of assertions to apply to the test circuit.
+ * @param testProperties The test case definition.
+ */
+ public void sequenceTest(Circuit testCircuit, List<Assertion> assertions, Properties testProperties)
+ {
+ assertNoFailures(testCircuit.test(1, assertions));
+ }
+
+ /**
+ * Creates a test circuit for the test, configered by the test parameters specified.
+ *
+ * @param testProperties The test parameters.
+ * @return A test circuit.
+ */
+ public Circuit createCircuit(ParsedProperties testProperties)
+ {
+ return CircuitImpl.createCircuit(testProperties);
+ }
+ }
+}
diff --git a/java/systests/src/main/java/org/apache/qpid/test/framework/MessageMonitor.java b/java/systests/src/main/java/org/apache/qpid/test/framework/MessageMonitor.java
new file mode 100644
index 0000000000..873f876012
--- /dev/null
+++ b/java/systests/src/main/java/org/apache/qpid/test/framework/MessageMonitor.java
@@ -0,0 +1,46 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT 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.framework;
+
+import javax.jms.Message;
+import javax.jms.MessageListener;
+
+/**
+ * MessageMonitor is used to record information about messages received. This will provide methods to check various
+ * properties, such as the type, number and content of messages received in order to verify the correct behaviour of
+ * tests.
+ *
+ * <p/>At the moment this monitor does not do anything.
+ *
+ * <p/><table id="crc"><caption>CRC Card</caption>
+ * <tr><th> Responsibilities <th> Collaborations
+ * </table>
+ */
+public class MessageMonitor implements MessageListener
+{
+ /**
+ * Handles received messages. Does Nothing.
+ *
+ * @param message The message. Ignored.
+ */
+ public void onMessage(Message message)
+ { }
+}
diff --git a/java/systests/src/main/java/org/apache/qpid/server/exchange/MessagingTestConfigProperties.java b/java/systests/src/main/java/org/apache/qpid/test/framework/MessagingTestConfigProperties.java
index b584c8c80b..3cc4a92886 100644
--- a/java/systests/src/main/java/org/apache/qpid/server/exchange/MessagingTestConfigProperties.java
+++ b/java/systests/src/main/java/org/apache/qpid/test/framework/MessagingTestConfigProperties.java
@@ -18,7 +18,7 @@
* under the License.
*
*/
-package org.apache.qpid.server.exchange;
+package org.apache.qpid.test.framework;
import org.apache.qpid.jms.Session;
@@ -48,7 +48,7 @@ import uk.co.thebadgerset.junit.extensions.util.ParsedProperties;
* <tr><td> destinationCount <td> 1 <td> The number of receivers listening to the pings.
* <tr><td> timeout <td> 30000 <td> In milliseconds. The timeout to stop waiting for replies.
* <tr><td> commitBatchSize <td> 1 <td> The number of messages per transaction in transactional mode.
- * <tr><td> uniqueDests <td> true <td> Whether each receiver only listens to one ping destination or all.
+ * <tr><td> uniqueDests <td> true <td> Whether each receivers only listens to one ping destination or all.
* <tr><td> durableDests <td> false <td> Whether or not durable destinations are used.
* <tr><td> ackMode <td> AUTO_ACK <td> The message acknowledgement mode. Possible values are:
* 0 - SESSION_TRANSACTED
@@ -81,12 +81,6 @@ public class MessagingTestConfigProperties
/** Defines the class to use as the initial context factory by default. */
public static final String INITIAL_CONTEXT_FACTORY_DEFAULT = "org.apache.qpid.jndi.PropertiesFileInitialContextFactory";
- /** Holds the name of the default connection factory configuration property. */
- public static final String CONNECTION_PROPNAME = "connectionfactory.broker";
-
- /** Defeins the default connection configuration. */
- public static final String CONNECTION_DEFAULT = "amqp://guest:guest@clientid/?brokerlist='vm://:1'";
-
/** Holds the name of the property to get the test broker url from. */
public static final String BROKER_PROPNAME = "qpid.test.broker";
@@ -125,16 +119,16 @@ public class MessagingTestConfigProperties
/** Holds the default value of the publisher consumer flag. */
public static final boolean PUBLISHER_CONSUMER_BIND_DEFAULT = false;
- /** Holds the name of the property to get the bind receiver procuder flag from. */
+ /** Holds the name of the property to get the bind receivers procuder flag from. */
public static final String RECEIVER_PRODUCER_BIND_PROPNAME = "receiverProducerBind";
- /** Holds the default value of the receiver producer flag. */
+ /** Holds the default value of the receivers producer flag. */
public static final boolean RECEIVER_PRODUCER_BIND_DEFAULT = false;
- /** Holds the name of the property to get the bind receiver procuder flag from. */
+ /** Holds the name of the property to get the bind receivers procuder flag from. */
public static final String RECEIVER_CONSUMER_BIND_PROPNAME = "receiverConsumerBind";
- /** Holds the default value of the receiver consumer flag. */
+ /** Holds the default value of the receivers consumer flag. */
public static final boolean RECEIVER_CONSUMER_BIND_DEFAULT = true;
/** Holds the name of the property to get the destination name root from. */
@@ -275,7 +269,7 @@ public class MessagingTestConfigProperties
static
{
defaults.setPropertyIfNull(INITIAL_CONTEXT_FACTORY_PROPNAME, INITIAL_CONTEXT_FACTORY_DEFAULT);
- defaults.setPropertyIfNull(CONNECTION_PROPNAME, CONNECTION_DEFAULT);
+ // defaults.setPropertyIfNull(CONNECTION_PROPNAME, CONNECTION_DEFAULT);
defaults.setPropertyIfNull(MESSAGE_SIZE_PROPNAME, MESSAGE_SIZE_DEAFULT);
defaults.setPropertyIfNull(PUBLISHER_PRODUCER_BIND_PROPNAME, PUBLISHER_PRODUCER_BIND_DEFAULT);
defaults.setPropertyIfNull(PUBLISHER_CONSUMER_BIND_PROPNAME, PUBLISHER_CONSUMER_BIND_DEFAULT);
diff --git a/java/systests/src/main/java/org/apache/qpid/test/framework/Publisher.java b/java/systests/src/main/java/org/apache/qpid/test/framework/Publisher.java
new file mode 100644
index 0000000000..59aa9065dd
--- /dev/null
+++ b/java/systests/src/main/java/org/apache/qpid/test/framework/Publisher.java
@@ -0,0 +1,56 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.qpid.test.framework;
+
+/**
+ * A Publisher is a {@link CircuitEnd} that represents one end of a test circuit. Its main purpose is to
+ * provide assertions that can be applied to test the behaviour of the publisher.
+ *
+ * <p/><table id="crc"><caption>CRC Card</caption>
+ * <tr><th> Responsibilities
+ * <tr><td> Provide assertion that the publisher received no exceptions.
+ * <tr><td> Provide assertion that the publisher received a no consumers error code.
+ * <tr><td> Provide assertion that the publisher received a no route error code.
+ * </table>
+ */
+public interface Publisher extends CircuitEnd
+{
+ /**
+ * Provides an assertion that the publisher encountered no exceptions.
+ *
+ * @return An assertion that the publisher encountered no exceptions.
+ */
+ public Assertion noExceptionsAssertion();
+
+ /**
+ * Provides an assertion that the publisher got a no consumers exception on every message.
+ *
+ * @return An assertion that the publisher got a no consumers exception on every message.
+ */
+ public Assertion noConsumersAssertion();
+
+ /**
+ * Provides an assertion that the publisher got a no rout exception on every message.
+ *
+ * @return An assertion that the publisher got a no rout exception on every message.
+ */
+ public Assertion noRouteAssertion();
+}
diff --git a/java/systests/src/main/java/org/apache/qpid/test/framework/Receiver.java b/java/systests/src/main/java/org/apache/qpid/test/framework/Receiver.java
new file mode 100644
index 0000000000..6e01a7ea4f
--- /dev/null
+++ b/java/systests/src/main/java/org/apache/qpid/test/framework/Receiver.java
@@ -0,0 +1,48 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT 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.framework;
+
+/**
+ * A Receiver is a {@link CircuitEnd} that represents one end of a test circuit. Its main purpose is to
+ * provide assertions that can be applied to test the behaviour of the receivers.
+ *
+ * <p/><table id="crc"><caption>CRC Card</caption>
+ * <tr><th> Responsibilities
+ * <tr><td> Provide assertion that the receivers received no exceptions.
+ * <tr><td> Provide assertion that the receivers received all test messages sent to it.
+ * </table>
+ */
+public interface Receiver extends CircuitEnd
+{
+ /**
+ * Provides an assertion that the receivers encountered no exceptions.
+ *
+ * @return An assertion that the receivers encountered no exceptions.
+ */
+ public Assertion noExceptionsAssertion();
+
+ /**
+ * Provides an assertion that the receivers got all messages that were sent to it.
+ *
+ * @return An assertion that the receivers got all messages that were sent to it.
+ */
+ public Assertion allMessagesAssertion();
+}
diff --git a/java/integrationtests/src/main/java/org/apache/qpid/interop/coordinator/TestClientDetails.java b/java/systests/src/main/java/org/apache/qpid/test/framework/TestClientDetails.java
index c4a9d39cd8..1e5807cba8 100644
--- a/java/integrationtests/src/main/java/org/apache/qpid/interop/coordinator/TestClientDetails.java
+++ b/java/systests/src/main/java/org/apache/qpid/test/framework/TestClientDetails.java
@@ -18,11 +18,15 @@
* under the License.
*
*/
-package org.apache.qpid.interop.coordinator;
+package org.apache.qpid.test.framework;
/**
+ * TestClientDetails is used to encapsulate information about an interop test client. It pairs together the unique
+ * name of the client, and the route on which it listens to its control messages.
+ *
* <p><table id="crc"><caption>CRC Card</caption>
* <tr><th> Responsibilities <th> Collaborations
+ * <tr><td> Record test clients control addresses together with their names.
* </table>
*/
public class TestClientDetails
@@ -56,13 +60,8 @@ public class TestClientDetails
final TestClientDetails testClientDetails = (TestClientDetails) o;
- if ((clientName != null) ? (!clientName.equals(testClientDetails.clientName))
- : (testClientDetails.clientName != null))
- {
- return false;
- }
-
- return true;
+ return !((clientName != null) ? (!clientName.equals(testClientDetails.clientName))
+ : (testClientDetails.clientName != null));
}
/**
diff --git a/java/systests/src/main/java/org/apache/qpid/test/framework/TestUtils.java b/java/systests/src/main/java/org/apache/qpid/test/framework/TestUtils.java
new file mode 100644
index 0000000000..8b3e72ef08
--- /dev/null
+++ b/java/systests/src/main/java/org/apache/qpid/test/framework/TestUtils.java
@@ -0,0 +1,156 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT 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.framework;
+
+import org.apache.log4j.Logger;
+
+import static org.apache.qpid.test.framework.MessagingTestConfigProperties.*;
+
+import uk.co.thebadgerset.junit.extensions.util.ParsedProperties;
+
+import javax.jms.Connection;
+import javax.jms.ConnectionFactory;
+import javax.jms.JMSException;
+import javax.jms.Message;
+import javax.naming.Context;
+import javax.naming.InitialContext;
+import javax.naming.NamingException;
+
+import java.util.Properties;
+import java.util.Map;
+
+/**
+ * TestUtils provides static helper methods that are usefull for writing tests against QPid.
+ *
+ * <p/><table id="crc"><caption>CRC Card</caption>
+ * <tr><th> Responsibilities <th> Collaborations
+ * <tr><td> Create connections from test properties. <td> {@link MessagingTestConfigProperties}
+ * <tr><td> Inject a short pause in a test.
+ * </table>
+ */
+public class TestUtils
+{
+ /** Used for debugging. */
+ private static Logger log = Logger.getLogger(TestUtils.class);
+
+ /**
+ * Establishes a JMS connection using a set of properties and qpids built in JNDI implementation. This is a simple
+ * convenience method for code that does not anticipate handling connection failures. All exceptions that indicate
+ * that the connection has failed, are wrapped as rutime exceptions, presumably handled by a top level failure
+ * handler.
+ *
+ * <p/>This utility makes use of the following test parameters from {@link MessagingTestConfigProperties} to control
+ * the connection creation:
+ *
+ * <p/><table>
+ * <tr><td> {@link MessagingTestConfigProperties#USERNAME_PROPNAME} <td> The username.
+ * <tr><td> {@link MessagingTestConfigProperties#PASSWORD_PROPNAME} <td> The password.
+ * <tr><td> {@link MessagingTestConfigProperties#VIRTUAL_HOST_PROPNAME} <td> The virtual host name.
+ * <tr><td> {@link MessagingTestConfigProperties#BROKER_PROPNAME} <td> The broker URL.
+ * <tr><td> {@link MessagingTestConfigProperties#CONNECTION_NAME} <td> The broker name in the initial context.
+ *
+ * @param messagingProps Connection properties as defined in {@link MessagingTestConfigProperties}.
+ *
+ * @return A JMS conneciton.
+ */
+ public static Connection createConnection(ParsedProperties messagingProps)
+ {
+ log.debug("public static Connection createConnection(ParsedProperties messagingProps = " + messagingProps
+ + "): called");
+
+ try
+ {
+ // Extract the configured connection properties from the test configuration.
+ String conUsername = messagingProps.getProperty(USERNAME_PROPNAME);
+ String conPassword = messagingProps.getProperty(PASSWORD_PROPNAME);
+ String virtualHost = messagingProps.getProperty(VIRTUAL_HOST_PROPNAME);
+ String brokerUrl = messagingProps.getProperty(BROKER_PROPNAME);
+
+ // Create the broker connection url.
+ String connectionString =
+ "amqp://" + conUsername + ":" + conPassword + "@clientid/" + ((virtualHost != null) ? virtualHost : "")
+ + "?brokerlist='" + brokerUrl + "'";
+
+ // Create properties to create the initial context from, and inject the connection factory configuration
+ // for the defined connection name into it.
+ messagingProps.setProperty("connectionfactory." + CONNECTION_NAME, connectionString);
+
+ Context ctx = new InitialContext(messagingProps);
+
+ ConnectionFactory cf = (ConnectionFactory) ctx.lookup(CONNECTION_NAME);
+ Connection connection = cf.createConnection();
+
+ return connection;
+ }
+ catch (NamingException e)
+ {
+ throw new RuntimeException("Got JNDI NamingException whilst looking up the connection factory.", e);
+ }
+ catch (JMSException e)
+ {
+ throw new RuntimeException("Could not establish connection due to JMSException.", e);
+ }
+ }
+
+ /**
+ * Pauses for the specified length of time. In the event of failing to pause for at least that length of time
+ * due to interuption of the thread, a RutimeException is raised to indicate the failure. The interupted status
+ * of the thread is restores in that case. This method should only be used when it is expected that the pause
+ * will be succesfull, for example in test code that relies on inejecting a pause.
+ *
+ * @param t The minimum time to pause for in milliseconds.
+ */
+ public static void pause(long t)
+ {
+ try
+ {
+ Thread.sleep(t);
+ }
+ catch (InterruptedException e)
+ {
+ // Restore the interrupted status
+ Thread.currentThread().interrupt();
+
+ throw new RuntimeException("Failed to generate the requested pause length.", e);
+ }
+ }
+
+ /**
+ * Sets properties of different types on a JMS Message.
+ *
+ * @param message The message to set properties on.
+ * @param properties The property name/value pairs to set.
+ *
+ * @throws javax.jms.JMSException All underlying JMSExceptions are allowed to fall through.
+ *
+ * @todo Move this helper method somewhere else. For example, TestUtils.
+ */
+ public static void setPropertiesOnMessage(Message message, Map<Object, Object> properties) throws JMSException
+ {
+ for (Map.Entry<Object, Object> entry : properties.entrySet())
+ {
+ String name = entry.getKey().toString();
+ Object value = entry.getValue();
+
+ message.setObjectProperty(name, value);
+ }
+ }
+}
diff --git a/java/systests/src/main/java/org/apache/qpid/test/framework/distributedcircuit/DistributedCircuitImpl.java b/java/systests/src/main/java/org/apache/qpid/test/framework/distributedcircuit/DistributedCircuitImpl.java
new file mode 100644
index 0000000000..aadd378aed
--- /dev/null
+++ b/java/systests/src/main/java/org/apache/qpid/test/framework/distributedcircuit/DistributedCircuitImpl.java
@@ -0,0 +1,116 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT 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.framework.distributedcircuit;
+
+import org.apache.qpid.test.framework.Assertion;
+import org.apache.qpid.test.framework.Circuit;
+import org.apache.qpid.test.framework.Publisher;
+import org.apache.qpid.test.framework.Receiver;
+
+import java.util.List;
+
+/**
+ * DistributedCircuitImpl is a distributed implementation of the test {@link Circuit}. Many publishers and receivers
+ * accross multiple machines may be combined to form a single test circuit. The test circuit extracts reports from
+ * all of its publishers and receivers, and applies its assertions to these reports.
+ *
+ * <p/><table id="crc"><caption>CRC Card</caption>
+ * <tr><th> Responsibilities <th> Collaborations
+ * <tr><td> Supply the publishing and receiving ends of a test messaging circuit.
+ * <tr><td> Start the circuit running.
+ * <tr><td> Close the circuit down.
+ * <tr><td> Take a reading of the circuits state.
+ * <tr><td> Apply assertions against the circuits state.
+ * <tr><td> Send test messages over the circuit.
+ * <tr><td> Perform the default test procedue on the circuit.
+ * </table>
+ */
+public class DistributedCircuitImpl implements Circuit
+{
+ /**
+ * Gets the interface on the publishing end of the circuit.
+ *
+ * @return The publishing end of the circuit.
+ */
+ public Publisher getPublisher()
+ {
+ throw new RuntimeException("Not Implemented.");
+ }
+
+ /**
+ * Gets the interface on the receiving end of the circuit.
+ *
+ * @return The receiving end of the circuit.
+ */
+ public Receiver getReceiver()
+ {
+ throw new RuntimeException("Not Implemented.");
+ }
+
+ /**
+ * Connects and starts the circuit. After this method is called the circuit is ready to send messages.
+ */
+ public void start()
+ {
+ throw new RuntimeException("Not Implemented.");
+ }
+
+ /**
+ * Checks the test circuit. The effect of this is to gather the circuits state, for both ends of the circuit,
+ * into a report, against which assertions may be checked.
+ */
+ public void check()
+ {
+ throw new RuntimeException("Not Implemented.");
+ }
+
+ /**
+ * Closes the circuit. All associated resources are closed.
+ */
+ public void close()
+ {
+ throw new RuntimeException("Not Implemented.");
+ }
+
+ /**
+ * Applied a list of assertions against the test circuit. The {@link #check()} method should be called before doing
+ * this, to ensure that the circuit has gathered its state into a report to assert against.
+ *
+ * @param assertions The list of assertions to apply.
+ * @return Any assertions that failed.
+ */
+ public List<Assertion> applyAssertions(List<Assertion> assertions)
+ {
+ throw new RuntimeException("Not Implemented.");
+ }
+
+ /**
+ * Runs the default test procedure against the circuit, and checks that all of the specified assertions hold.
+ *
+ * @param numMessages The number of messages to send using the default test procedure.
+ * @param assertions The list of assertions to apply.
+ * @return Any assertions that failed.
+ */
+ public List<Assertion> test(int numMessages, List<Assertion> assertions)
+ {
+ throw new RuntimeException("Not Implemented.");
+ }
+}
diff --git a/java/integrationtests/src/main/java/org/apache/qpid/interop/coordinator/Coordinator.java b/java/systests/src/main/java/org/apache/qpid/test/framework/distributedtesting/Coordinator.java
index 6eec20769a..7d28aee432 100644
--- a/java/integrationtests/src/main/java/org/apache/qpid/interop/coordinator/Coordinator.java
+++ b/java/systests/src/main/java/org/apache/qpid/test/framework/distributedtesting/Coordinator.java
@@ -18,28 +18,34 @@
* under the License.
*
*/
-package org.apache.qpid.interop.coordinator;
+package org.apache.qpid.test.framework.distributedtesting;
-import java.io.*;
-import java.util.*;
-import java.util.concurrent.LinkedBlockingQueue;
-import javax.jms.*;
import junit.framework.Test;
import junit.framework.TestResult;
import junit.framework.TestSuite;
+
import org.apache.log4j.Logger;
-import org.apache.qpid.interop.coordinator.testcases.CoordinatingTestCase1DummyRun;
-import org.apache.qpid.interop.coordinator.testcases.CoordinatingTestCase2BasicP2P;
-import org.apache.qpid.interop.coordinator.testcases.CoordinatingTestCase3BasicPubSub;
-import org.apache.qpid.interop.testclient.TestClient;
-import org.apache.qpid.util.CommandLineParser;
+
+import org.apache.qpid.test.framework.MessagingTestConfigProperties;
+import org.apache.qpid.test.framework.TestUtils;
+import org.apache.qpid.test.framework.TestClientDetails;
+import org.apache.qpid.test.framework.listeners.XMLTestListener;
import org.apache.qpid.util.ConversationFactory;
import org.apache.qpid.util.PrettyPrintingUtils;
+
import uk.co.thebadgerset.junit.extensions.TKTestResult;
import uk.co.thebadgerset.junit.extensions.TKTestRunner;
import uk.co.thebadgerset.junit.extensions.WrappedSuiteTestDecorator;
+import uk.co.thebadgerset.junit.extensions.util.CommandLineParser;
+import uk.co.thebadgerset.junit.extensions.util.ParsedProperties;
import uk.co.thebadgerset.junit.extensions.util.TestContextProperties;
+import javax.jms.*;
+
+import java.io.*;
+import java.util.*;
+import java.util.concurrent.LinkedBlockingQueue;
+
/**
* <p/>Implements the coordinator client described in the interop testing specification
* (http://cwiki.apache.org/confluence/display/qpid/Interop+Testing+Specification). This coordinator is built on
@@ -48,16 +54,41 @@ import uk.co.thebadgerset.junit.extensions.util.TestContextProperties;
* <p><table id="crc"><caption>CRC Card</caption>
* <tr><th> Responsibilities <th> Collaborations
* <tr><td> Find out what test clients are available. <td> {@link ConversationFactory}
- * <tr><td> Decorate available tests to run all available clients. <td> {@link InvitingTestDecorator}
+ * <tr><td> Decorate available tests to run all available clients. <td> {@link DistributedTestDecorator}
* <tr><td> Attach XML test result logger.
* <tr><td> Terminate the interop testing framework.
* </table>
+ *
+ * @todo Should accumulate failures over all tests, and return with success or fail code based on all results. May need
+ * to write a special TestResult to do this properly. At the moment only the last one used will be tested for
+ * errors, as the start method creates a fresh one for each test case run.
+ *
+ * @todo Remove hard coding of test cases and put on command line instead.
*/
public class Coordinator extends TKTestRunner
{
+ /** Used for debugging. */
private static final Logger log = Logger.getLogger(Coordinator.class);
- public static final String DEFAULT_CONNECTION_PROPS_RESOURCE = "org/apache/qpid/interop/connection.properties";
+ /** Used for reporting to the console. */
+ private static final Logger console = Logger.getLogger("CONSOLE");
+
+ /** Defines the possible distributed test engines available to run coordinated test cases with. */
+ public enum TestEngine
+ {
+ /** Specifies the interop test engine. This tests all available clients in pairs. */
+ INTEROP,
+
+ /** Specifies the fanout test engine. This sets up one publisher role, and many reciever roles. */
+ FANOUT
+ }
+
+ /**
+ * Holds the test context properties that provides the default test parameters, plus command line overrides.
+ * This is initialized with the default test parameters, to which command line overrides may be applied.
+ */
+ protected static ParsedProperties testContextProperties =
+ TestContextProperties.getInstance(MessagingTestConfigProperties.defaults);
/** Holds the URL of the broker to coordinate the tests on. */
protected String brokerUrl;
@@ -81,21 +112,32 @@ public class Coordinator extends TKTestRunner
protected String currentTestClassName;
/** Holds the path of the directory to output test results too, if one is defined. */
- protected static String _reportDir;
+ protected String reportDir;
+
+ /** Holds the coordinating test engine type to run the tests through. */
+ protected TestEngine engine;
+
+ /** Flag that indicates that all test clients should be terminated upon completion of the test cases. */
+ protected boolean terminate;
/**
* Creates an interop test coordinator on the specified broker and virtual host.
*
* @param brokerUrl The URL of the broker to connect to.
* @param virtualHost The virtual host to run all tests on. Optional, may be <tt>null</tt>.
+ * @param reportDir The directory to write out test results to.
+ * @param engine The distributed test engine type to run the tests with.
*/
- public Coordinator(String brokerUrl, String virtualHost)
+ public Coordinator(String brokerUrl, String virtualHost, String reportDir, TestEngine engine, boolean terminate)
{
log.debug("Coordinator(String brokerUrl = " + brokerUrl + ", String virtualHost = " + virtualHost + "): called");
// Retain the connection parameters.
this.brokerUrl = brokerUrl;
this.virtualHost = virtualHost;
+ this.reportDir = reportDir;
+ this.engine = engine;
+ this.terminate = terminate;
}
/**
@@ -104,50 +146,101 @@ public class Coordinator extends TKTestRunner
* <p/><table>
* <tr><td> -b <td> The broker URL. <td> Mandatory.
* <tr><td> -h <td> The virtual host. <td> Optional.
- * <tr><td> name=value <td> Trailing argument define name/value pairs. Added to system properties. <td> Optional.
+ * <tr><td> -o <td> The directory to output test results to. <td> Optional.
+ * <tr><td> -e <td> The type of test distribution engine to use. <td> Optional. One of: interop, fanout.
+ * <tr><td> ... <td> Free arguments. The distributed test cases to run.
+ * <td> Mandatory. At least one must be defined.
+ * <tr><td> name=value <td> Trailing argument define name/value pairs. Added to the test contenxt properties.
+ * <td> Optional.
* </table>
*
* @param args The command line arguments.
*/
public static void main(String[] args)
{
+ console.info("Qpid Distributed Test Coordinator.");
+
+ // Override the default broker url to be localhost:5672.
+ testContextProperties.setProperty(MessagingTestConfigProperties.BROKER_PROPNAME, "tcp://localhost:5672");
+
try
{
// Use the command line parser to evaluate the command line with standard handling behaviour (print errors
- // and usage then exit if there are errors).
- Properties options =
- CommandLineParser.processCommandLine(args,
- new CommandLineParser(
- new String[][]
- {
- {"b", "The broker URL.", "broker", "false"},
- {"h", "The virtual host to use.", "virtual host", "false"},
- {"o", "The name of the directory to output test timings to.", "dir", "false"}
- }));
+ // and usage then exist if there are errors).
+ // Any options and trailing name=value pairs are also injected into the test context properties object,
+ // to override any defaults that may have been set up.
+ ParsedProperties options =
+ new ParsedProperties(CommandLineParser.processCommandLine(args,
+ new CommandLineParser(
+ new String[][]
+ {
+ { "b", "The broker URL.", "broker", "false" },
+ { "h", "The virtual host to use.", "virtual host", "false" },
+ { "o", "The name of the directory to output test timings to.", "dir", "false" },
+ {
+ "e", "The test execution engine to use. Default is interop.", "engine", "interop",
+ "^interop$|^fanout$", "true"
+ },
+ { "t", "Terminate test clients on completion of tests.", "flag", "false" }
+ }), testContextProperties));
// Extract the command line options.
String brokerUrl = options.getProperty("b");
String virtualHost = options.getProperty("h");
- _reportDir = options.getProperty("o");
- _reportDir = (_reportDir == null) ? "." : _reportDir;
+ String reportDir = options.getProperty("o");
+ reportDir = (reportDir == null) ? "." : reportDir;
+ String testEngine = options.getProperty("e");
+ TestEngine engine = "fanout".equals(testEngine) ? TestEngine.FANOUT : TestEngine.INTEROP;
+ boolean terminate = options.getPropertyAsBoolean("t");
+
+ // If broker or virtual host settings were specified as command line options, override the defaults in the
+ // test context properties with them.
+
+ // Collection all of the test cases to be run.
+ Collection<Class<? extends DistributedTestCase>> testCaseClasses =
+ new ArrayList<Class<? extends DistributedTestCase>>();
// Scan for available test cases using a classpath scanner.
- Collection<Class<? extends CoordinatingTestCase>> testCaseClasses =
- new ArrayList<Class<? extends CoordinatingTestCase>>();
- // ClasspathScanner.getMatches(CoordinatingTestCase.class, "^Test.*", true);
+ // ClasspathScanner.getMatches(InteropTestCase.class, "^Test.*", true);
+
// Hard code the test classes till the classpath scanner is fixed.
- Collections.addAll(testCaseClasses,
- CoordinatingTestCase1DummyRun.class,
- CoordinatingTestCase2BasicP2P.class,
- CoordinatingTestCase3BasicPubSub.class);
+ // Collections.addAll(testCaseClasses, InteropTestCase1DummyRun.class, InteropTestCase2BasicP2P.class,
+ // InteropTestCase3BasicPubSub.class);
+
+ // Parse all of the free arguments as test cases to run.
+ for (int i = 1; true; i++)
+ {
+ String nextFreeArg = options.getProperty(Integer.toString(i));
+
+ // Terminate the loop once all free arguments have been consumed.
+ if (nextFreeArg == null)
+ {
+ break;
+ }
+
+ try
+ {
+ Class nextClass = Class.forName(nextFreeArg);
+
+ if (DistributedTestCase.class.isAssignableFrom(nextClass))
+ {
+ testCaseClasses.add(nextClass);
+ console.info("Found distributed test case: " + nextFreeArg);
+ }
+ }
+ catch (ClassNotFoundException e)
+ {
+ console.info("Unable to instantiate the test case: " + nextFreeArg + ".");
+ }
+ }
// Check that some test classes were actually found.
if (testCaseClasses.isEmpty())
{
- throw new RuntimeException(
- "No test classes implementing CoordinatingTestCase were found on the class path.");
+ throw new RuntimeException("No test cases implementing InteropTestCase were specified on the command line.");
}
+ // Extract the names of all the test classes, to pass to the start method.
int i = 0;
String[] testClassNames = new String[testCaseClasses.size()];
@@ -157,13 +250,12 @@ public class Coordinator extends TKTestRunner
}
// Create a coordinator and begin its test procedure.
- Coordinator coordinator = new Coordinator(brokerUrl, virtualHost);
-
- boolean failure = false;
+ Coordinator coordinator = new Coordinator(brokerUrl, virtualHost, reportDir, engine, terminate);
TestResult testResult = coordinator.start(testClassNames);
- if (failure)
+ // Return different error codes, depending on whether or not there were test failures.
+ if (testResult.failureCount() > 0)
{
System.exit(FAILURE_EXIT);
}
@@ -174,14 +266,14 @@ public class Coordinator extends TKTestRunner
}
catch (Exception e)
{
- System.err.println(e.getMessage());
- log.error("Top level handler caught execption.", e);
+ log.debug("Top level handler caught execption.", e);
+ console.info(e.getMessage());
System.exit(EXCEPTION_EXIT);
}
}
/**
- * Starts all of the test classes to be run by this coordinator running.
+ * Starts all of the test classes to be run by this coordinator.
*
* @param testClassNames An array of all the coordinating test case implementations.
*
@@ -192,10 +284,10 @@ public class Coordinator extends TKTestRunner
public TestResult start(String[] testClassNames) throws Exception
{
log.debug("public TestResult start(String[] testClassNames = " + PrettyPrintingUtils.printArray(testClassNames)
- + ": called");
+ + ": called");
// Connect to the broker.
- connection = TestClient.createConnection(DEFAULT_CONNECTION_PROPS_RESOURCE, brokerUrl, virtualHost);
+ connection = TestUtils.createConnection(TestContextProperties.getInstance());
Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
Destination controlTopic = session.createTopic("iop.control");
@@ -226,14 +318,18 @@ public class Coordinator extends TKTestRunner
// Record the current test class, so that the test results can be output to a file incorporating this name.
this.currentTestClassName = testClassName;
- result = super.start(new String[]{testClassName});
+ result = super.start(new String[] { testClassName });
}
- // At this point in time, all tests have completed. Broadcast the shutdown message.
- Message terminate = session.createMessage();
- terminate.setStringProperty("CONTROL_TYPE", "TERMINATE");
+ // At this point in time, all tests have completed. Broadcast the shutdown message, if the termination option
+ // was set on the command line.
+ if (terminate)
+ {
+ Message terminate = session.createMessage();
+ terminate.setStringProperty("CONTROL_TYPE", "TERMINATE");
- conversation.send(controlTopic, terminate);
+ conversation.send(controlTopic, terminate);
+ }
return result;
}
@@ -250,7 +346,7 @@ public class Coordinator extends TKTestRunner
public static Set<TestClientDetails> extractEnlists(Collection<Message> enlists) throws JMSException
{
log.debug("public static Set<TestClientDetails> extractEnlists(Collection<Message> enlists = " + enlists
- + "): called");
+ + "): called");
Set<TestClientDetails> enlistedClients = new HashSet<TestClientDetails>();
@@ -299,17 +395,17 @@ public class Coordinator extends TKTestRunner
Test nextTest = suite.testAt(i);
log.debug("suite.testAt(" + i + ") = " + nextTest);
- if (nextTest instanceof CoordinatingTestCase)
+ if (nextTest instanceof DistributedTestCase)
{
- log.debug("nextTest is a CoordinatingTestCase");
+ log.debug("nextTest is a DistributedTestCase");
}
}
targetTest = new WrappedSuiteTestDecorator(suite);
log.debug("Wrapped with a WrappedSuiteTestDecorator.");
}
- // Wrap the tests in an inviting test decorator, to perform the invite/test cycle.
+ // Wrap the tests in a suitable distributed test decorator, to perform the invite/test cycle.
targetTest = newTestDecorator(targetTest, enlistedClients, conversationFactory, connection);
TestSuite suite = new TestSuite();
@@ -321,9 +417,28 @@ public class Coordinator extends TKTestRunner
return super.doRun(suite, wait);
}
- protected WrappedSuiteTestDecorator newTestDecorator(WrappedSuiteTestDecorator targetTest, Set<TestClientDetails> enlistedClients, ConversationFactory conversationFactory, Connection connection)
+ /**
+ * Creates a wrapped test decorator, that is capable of inviting enlisted clients to participate in a specified
+ * test. This is the test engine that sets up the roles and sequences a distributed test case.
+ *
+ * @param targetTest The test decorator to wrap.
+ * @param enlistedClients The enlisted clients available to run the test.
+ * @param conversationFactory The conversation factory used to build conversation helper over the specified connection.
+ * @param connection The connection to talk to the enlisted clients over.
+ *
+ * @return An invititing test decorator, that invites all the enlisted clients to participate in tests, in pairs.
+ */
+ protected DistributedTestDecorator newTestDecorator(WrappedSuiteTestDecorator targetTest,
+ Set<TestClientDetails> enlistedClients, ConversationFactory conversationFactory, Connection connection)
{
- return new InvitingTestDecorator(targetTest, enlistedClients, conversationFactory, connection);
+ switch (engine)
+ {
+ case FANOUT:
+ return new FanOutTestDecorator(targetTest, enlistedClients, conversationFactory, connection);
+ case INTEROP:
+ default:
+ return new InteropTestDecorator(targetTest, enlistedClients, conversationFactory, connection);
+ }
}
/**
@@ -338,18 +453,18 @@ public class Coordinator extends TKTestRunner
TKTestResult result = new TKTestResult(fPrinter.getWriter(), delay, verbose, testCaseName);
// Check if a directory to output reports to has been specified and attach test listeners if so.
- if (_reportDir != null)
+ if (reportDir != null)
{
// Create the report directory if it does not already exist.
- File reportDirFile = new File(_reportDir);
+ File reportDirFile = new File(reportDir);
if (!reportDirFile.exists())
{
reportDirFile.mkdir();
}
- // Create the timings file (make the name of this configurable as a command line parameter).
- Writer timingsWriter = null;
+ // Create the results file (make the name of this configurable as a command line parameter).
+ Writer timingsWriter;
try
{
@@ -361,7 +476,7 @@ public class Coordinator extends TKTestRunner
throw new RuntimeException("Unable to create the log file to write test results to: " + e, e);
}
- // Set up a CSV results listener to output the timings to the results file.
+ // Set up an XML results listener to output the timings to the results file.
XMLTestListener listener = new XMLTestListener(timingsWriter, currentTestClassName);
result.addListener(listener);
result.addTKTestListener(listener);
@@ -380,9 +495,4 @@ public class Coordinator extends TKTestRunner
return result;
}
-
- public void setReportDir(String reportDir)
- {
- _reportDir = reportDir;
- }
}
diff --git a/java/systests/src/main/java/org/apache/qpid/test/framework/distributedtesting/DistributedTestCase.java b/java/systests/src/main/java/org/apache/qpid/test/framework/distributedtesting/DistributedTestCase.java
new file mode 100644
index 0000000000..c47650ba1c
--- /dev/null
+++ b/java/systests/src/main/java/org/apache/qpid/test/framework/distributedtesting/DistributedTestCase.java
@@ -0,0 +1,81 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT 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.framework.distributedtesting;
+
+import org.apache.log4j.Logger;
+
+import org.apache.qpid.test.framework.sequencers.DistributedTestSequencer;
+import org.apache.qpid.test.framework.FrameworkBaseCase;
+
+/**
+ * DistributedTestCase provides a base class implementation of the {@link org.apache.qpid.test.framework.sequencers.DistributedTestSequencer}, taking care of its
+ * more mundane aspects, such as recording the test pariticipants.
+ *
+ * <p/><table id="crc"><caption>CRC Card</caption>
+ * <tr><th> Responsibilities <th> Collaborations
+ * <tr><td> Accept notification of test case participants.
+ * <td> {@link DistributedTestDecorator}
+ * <tr><td> Accept JMS Connection to carry out the coordination over.
+ * </table>
+ */
+public abstract class DistributedTestCase extends FrameworkBaseCase
+{
+ /** Used for debugging. */
+ private final Logger log = Logger.getLogger(DistributedTestCase.class);
+
+ /**
+ * Creates a new test case with the specified name.
+ *
+ * @param name The test case name.
+ */
+ public DistributedTestCase(String name)
+ {
+ super(name);
+ }
+
+ /**
+ * Gets the test sequencer for this distributed test, cast as a {@link DistributedTestSequencer}, provided that it
+ * is one. If the test sequencer is not distributed, this returns null.
+ */
+ public DistributedTestSequencer getDistributedTestSequencer()
+ {
+ try
+ {
+ return (DistributedTestSequencer) testSequencer;
+ }
+ catch (ClassCastException e)
+ {
+ return null;
+ }
+ }
+
+ /**
+ * Should provide a translation from the junit method name of a test to its test case name as known to the test
+ * clients that will run the test. The purpose of this is to convert the JUnit method name into the correct test
+ * case name to place into the test invite. For example the method "testP2P" might map onto the interop test case
+ * name "TC2_BasicP2P".
+ *
+ * @param methodName The name of the JUnit test method.
+ *
+ * @return The name of the corresponding interop test case.
+ */
+ public abstract String getTestCaseNameForTestMethod(String methodName);
+}
diff --git a/java/systests/src/main/java/org/apache/qpid/test/framework/distributedtesting/DistributedTestDecorator.java b/java/systests/src/main/java/org/apache/qpid/test/framework/distributedtesting/DistributedTestDecorator.java
new file mode 100644
index 0000000000..bcc409dff9
--- /dev/null
+++ b/java/systests/src/main/java/org/apache/qpid/test/framework/distributedtesting/DistributedTestDecorator.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.test.framework.distributedtesting;
+
+import junit.framework.TestResult;
+
+import org.apache.log4j.Logger;
+
+import org.apache.qpid.test.framework.sequencers.DistributedTestSequencer;
+import org.apache.qpid.test.framework.TestClientDetails;
+import org.apache.qpid.util.ConversationFactory;
+
+import uk.co.thebadgerset.junit.extensions.WrappedSuiteTestDecorator;
+
+import javax.jms.Connection;
+import javax.jms.Destination;
+import javax.jms.JMSException;
+import javax.jms.Message;
+
+import java.util.*;
+
+/**
+ * DistributedTestDecorator is a base class for writing test decorators that invite test clients to participate in
+ * distributed test cases. It provides a helper method, {@link #signupClients}, that broadcasts an invitation and
+ * returns the set of test clients that are available to particiapte in the test.
+ *
+ * <p/>When used to wrap a {@link org.apache.qpid.test.framework.FrameworkBaseCase} test, it replaces the default
+ * {@link org.apache.qpid.test.framework.sequencers.TestCaseSequencer} implementations with a suitable
+ * {@link org.apache.qpid.test.framework.sequencers.DistributedTestSequencer}. Concrete implementations
+ * can use this to configure the sending and receiving roles on the test.
+ *
+ * <p><table id="crc"><caption>CRC Card</caption>
+ * <tr><th> Responsibilities <th> Collaborations
+ * <tr><td> Broadcast test invitations and collect enlists. <td> {@link ConversationFactory}.
+ * </table>
+ */
+public abstract class DistributedTestDecorator extends WrappedSuiteTestDecorator
+{
+ /** Used for debugging. */
+ private static final Logger log = Logger.getLogger(DistributedTestDecorator.class);
+
+ /** Holds the contact information for all test clients that are available and that may take part in the test. */
+ Set<TestClientDetails> allClients;
+
+ /** Holds the conversation helper for the control level conversation for coordinating the test through. */
+ ConversationFactory conversationFactory;
+
+ /** Holds the connection that the control conversation is held over. */
+ Connection connection;
+
+ /** Holds the underlying {@link DistributedTestCase}s that this decorator wraps. */
+ WrappedSuiteTestDecorator testSuite;
+
+ /** Holds the control topic, on which test invitations are broadcast. */
+ protected Destination controlTopic;
+
+ /**
+ * Creates a wrapped suite test decorator from another one.
+ *
+ * @param suite The test suite.
+ * @param availableClients The list of all clients that responded to the compulsory invite.
+ * @param controlConversation The conversation helper for the control level, test coordination conversation.
+ * @param controlConnection The connection that the coordination messages are sent over.
+ */
+ public DistributedTestDecorator(WrappedSuiteTestDecorator suite, Set<TestClientDetails> availableClients,
+ ConversationFactory controlConversation, Connection controlConnection)
+ {
+ super(suite);
+
+ log.debug("public DistributedTestDecorator(WrappedSuiteTestDecorator suite, Set<TestClientDetails> allClients = "
+ + availableClients + ", ConversationHelper controlConversation = " + controlConversation + "): called");
+
+ testSuite = suite;
+ allClients = availableClients;
+ conversationFactory = controlConversation;
+ connection = controlConnection;
+
+ // Set up the test control topic.
+ try
+ {
+ controlTopic = conversationFactory.getSession().createTopic("iop.control");
+ }
+ catch (JMSException e)
+ {
+ throw new RuntimeException("Unable to create the coordinating control topic to broadcast test invites on.", e);
+ }
+ }
+
+ /**
+ * Should run all of the tests in the wrapped test suite.
+ *
+ * @param testResult The the results object to monitor the test results with.
+ */
+ public abstract void run(TestResult testResult);
+
+ /**
+ * Should provide the distributed test sequencer to pass to {@link org.apache.qpid.test.framework.FrameworkBaseCase}
+ * tests.
+ *
+ * @return A distributed test sequencer.
+ */
+ public abstract DistributedTestSequencer getDistributedTestSequencer();
+
+ /**
+ * Broadcasts an invitation to participate in a coordinating test case to find out what clients are available to
+ * run the test case.
+ *
+ * @param coordTest The coordinating test case to broadcast an inviate for.
+ *
+ * @return A set of test clients that accepted the invitation.
+ */
+ protected Set<TestClientDetails> signupClients(DistributedTestCase coordTest)
+ {
+ // Broadcast the invitation to find out what clients are available to test.
+ Set<TestClientDetails> enlists;
+ try
+ {
+ Message invite = conversationFactory.getSession().createMessage();
+
+ ConversationFactory.Conversation conversation = conversationFactory.startConversation();
+
+ invite.setStringProperty("CONTROL_TYPE", "INVITE");
+ invite.setStringProperty("TEST_NAME", coordTest.getTestCaseNameForTestMethod(coordTest.getName()));
+
+ conversation.send(controlTopic, invite);
+
+ // Wait for a short time, to give test clients an opportunity to reply to the invitation.
+ Collection<Message> replies = conversation.receiveAll(allClients.size(), 3000);
+ enlists = Coordinator.extractEnlists(replies);
+ }
+ catch (JMSException e)
+ {
+ throw new RuntimeException("There was a JMSException during the invite/enlist conversation.", e);
+ }
+
+ return enlists;
+ }
+
+ /**
+ * Prints a string summarizing this test decorator, mainly for debugging purposes.
+ *
+ * @return String representation for debugging purposes.
+ */
+ public String toString()
+ {
+ return "DistributedTestDecorator: [ testSuite = " + testSuite + " ]";
+ }
+}
diff --git a/java/systests/src/main/java/org/apache/qpid/test/framework/distributedtesting/FanOutTestDecorator.java b/java/systests/src/main/java/org/apache/qpid/test/framework/distributedtesting/FanOutTestDecorator.java
new file mode 100644
index 0000000000..83d6602e57
--- /dev/null
+++ b/java/systests/src/main/java/org/apache/qpid/test/framework/distributedtesting/FanOutTestDecorator.java
@@ -0,0 +1,201 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT 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.framework.distributedtesting;
+
+import junit.framework.Test;
+import junit.framework.TestResult;
+
+import org.apache.log4j.Logger;
+
+import org.apache.qpid.test.framework.sequencers.DistributedTestSequencer;
+import org.apache.qpid.test.framework.sequencers.FanOutTestSequencer;
+import org.apache.qpid.test.framework.DropInTest;
+import org.apache.qpid.util.ConversationFactory;
+import org.apache.qpid.test.framework.TestClientDetails;
+
+import uk.co.thebadgerset.junit.extensions.WrappedSuiteTestDecorator;
+
+import javax.jms.Connection;
+import javax.jms.JMSException;
+import javax.jms.Message;
+import javax.jms.MessageListener;
+
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.Set;
+
+/**
+ * FanOutTestDecorator is an {@link DistributedTestDecorator} that runs one test client in the sender role, and the remainder
+ * in the receivers role. It also has the capability to listen for new test cases joining the test beyond the initial start
+ * point. This feature can be usefull when experimenting with adding more load, in the form of more test clients, to assess
+ * its impact on a running test.
+ *
+ * <p><table id="crc"><caption>CRC Card</caption>
+ * <tr><th> Responsibilities <th> Collaborations
+ * <tr><td> Execute coordinated test cases. <td> {@link DistributedTestCase}
+ * <tr><td> Accept test clients joining a running test.
+ * </table>
+ */
+public class FanOutTestDecorator extends DistributedTestDecorator implements MessageListener
+{
+ /** Used for debugging. */
+ private static final Logger log = Logger.getLogger(FanOutTestDecorator.class);
+
+ /** Holds the currently running test case. */
+ DistributedTestCase currentTest = null;
+
+ /**
+ * Creates a wrapped suite test decorator from another one.
+ *
+ * @param suite The test suite.
+ * @param availableClients The list of all clients that responded to the compulsory invite.
+ * @param controlConversation The conversation helper for the control level, test coordination conversation.
+ * @param controlConnection The connection that the coordination messages are sent over.
+ */
+ public FanOutTestDecorator(WrappedSuiteTestDecorator suite, Set<TestClientDetails> availableClients,
+ ConversationFactory controlConversation, Connection controlConnection)
+ {
+ super(suite, availableClients, controlConversation, controlConnection);
+
+ log.debug("public DistributedTestDecorator(WrappedSuiteTestDecorator suite, Set<TestClientDetails> allClients = "
+ + availableClients + ", ConversationHelper controlConversation = " + controlConversation + "): called");
+
+ testSuite = suite;
+ allClients = availableClients;
+ conversationFactory = controlConversation;
+ connection = controlConnection;
+ }
+
+ /**
+ * Broadcasts a test invitation and accepts enlists from participating clients. The wrapped test cases are run
+ * with one test client in the sender role, and the remaining test clients in the receiving role.
+ *
+ * <p/>Any JMSExceptions during the invite/enlist conversation will be allowed to fall through as runtime
+ * exceptions, resulting in the non-completion of the test run.
+ *
+ * @param testResult The the results object to monitor the test results with.
+ *
+ * @todo Better error recovery for failure of the invite/enlist conversation could be added.
+ */
+ public void run(TestResult testResult)
+ {
+ log.debug("public void run(TestResult testResult): called");
+
+ Collection<Test> tests = testSuite.getAllUnderlyingTests();
+
+ // Listen for late joiners on the control topic.
+ try
+ {
+ conversationFactory.getSession().createConsumer(controlTopic).setMessageListener(this);
+ }
+ catch (JMSException e)
+ {
+ throw new RuntimeException("Unable to set up the message listener on the control topic.", e);
+ }
+
+ // Run all of the test cases in the test suite.
+ for (Test test : tests)
+ {
+ DistributedTestCase coordTest = (DistributedTestCase) test;
+
+ // Get all of the clients able to participate in the test.
+ Set<TestClientDetails> enlists = signupClients(coordTest);
+
+ // Check that there were some clients available.
+ if (enlists.size() == 0)
+ {
+ throw new RuntimeException("No clients to test with");
+ }
+
+ // Create a distributed test sequencer for the test.
+ DistributedTestSequencer sequencer = getDistributedTestSequencer();
+
+ // Set up the first client in the sender role, and the remainder in the receivers role.
+ Iterator<TestClientDetails> clients = enlists.iterator();
+ sequencer.setSender(clients.next());
+
+ while (clients.hasNext())
+ {
+ // Set the sending and receiving client details on the test case.
+ sequencer.setReceiver(clients.next());
+ }
+
+ // Pass down the connection to hold the coordinating conversation over.
+ sequencer.setConversationFactory(conversationFactory);
+
+ // If the current test case is a drop-in test, set it up as the currently running test for late joiners to
+ // add in to. Otherwise the current test field is set to null, to indicate that late joiners are not allowed.
+ currentTest = (coordTest instanceof DropInTest) ? coordTest : null;
+
+ // Execute the test case.
+ coordTest.setTestSequencer(sequencer);
+ coordTest.run(testResult);
+
+ currentTest = null;
+ }
+ }
+
+ /**
+ * Should provide the distributed test sequencer to pass to {@link org.apache.qpid.test.framework.FrameworkBaseCase}
+ * tests.
+ *
+ * @return A distributed test sequencer.
+ */
+ public DistributedTestSequencer getDistributedTestSequencer()
+ {
+ return new FanOutTestSequencer();
+ }
+
+ /**
+ * Listens to incoming messages on the control topic. If the messages are 'join' messages, signalling a new
+ * test client wishing to join the current test, then the new client will be added to the current test in the
+ * receivers role.
+ *
+ * @param message The incoming control message.
+ */
+ public void onMessage(Message message)
+ {
+ try
+ {
+ // Check if the message is from a test client attempting to join a running test, and join it to the current
+ // test case if so.
+ if (message.getStringProperty("CONTROL_TYPE").equals("JOIN") && (currentTest != null))
+ {
+ ((DropInTest) currentTest).lateJoin(message);
+ }
+ }
+ // There is not a lot can be done with this error, so it is deliberately ignored.
+ catch (JMSException e)
+ {
+ log.debug("Unable to process message:" + message);
+ }
+ }
+
+ /**
+ * Prints a string summarizing this test decorator, mainly for debugging purposes.
+ *
+ * @return String representation for debugging purposes.
+ */
+ public String toString()
+ {
+ return "FanOutTestDecorator: [ testSuite = " + testSuite + " ]";
+ }
+}
diff --git a/java/integrationtests/src/main/java/org/apache/qpid/interop/coordinator/InvitingTestDecorator.java b/java/systests/src/main/java/org/apache/qpid/test/framework/distributedtesting/InteropTestDecorator.java
index 8695f7f66f..7743d2bba3 100644
--- a/java/integrationtests/src/main/java/org/apache/qpid/interop/coordinator/InvitingTestDecorator.java
+++ b/java/systests/src/main/java/org/apache/qpid/test/framework/distributedtesting/InteropTestDecorator.java
@@ -18,47 +18,44 @@
* under the License.
*
*/
-package org.apache.qpid.interop.coordinator;
-
-import java.util.*;
-
-import javax.jms.Connection;
-import javax.jms.Destination;
-import javax.jms.JMSException;
-import javax.jms.Message;
+package org.apache.qpid.test.framework.distributedtesting;
import junit.framework.Test;
import junit.framework.TestResult;
import org.apache.log4j.Logger;
+import org.apache.qpid.test.framework.sequencers.DistributedTestSequencer;
+import org.apache.qpid.test.framework.sequencers.InteropTestSequencer;
+import org.apache.qpid.test.framework.TestClientDetails;
import org.apache.qpid.util.ConversationFactory;
import uk.co.thebadgerset.junit.extensions.WrappedSuiteTestDecorator;
+import javax.jms.Connection;
+
+import java.util.*;
+
/**
+ * DistributedTestDecorator is a test decorator, written to implement the interop test specification. Given a list
+ * of enlisted test clients, that are available to run interop tests, this decorator invites them to participate
+ * in each test in the wrapped test suite. Amongst all the clients that respond to the invite, all pairs are formed,
+ * and each pairing (in both directions, but excluding the reflexive pairings) is split into a sender and receivers
+ * role and a test case run between them. Any enlisted combinations that do not accept a test invite are automatically
+ * failed.
+ *
* <p><table id="crc"><caption>CRC Card</caption>
* <tr><th> Responsibilities <th> Collaborations
- * <tr><td> Broadcast test invitations and collect enlists. <td> {@link ConversationFactory}.
+ * <tr><td> Broadcast test invitations and collect enlists. <td> {@link org.apache.qpid.util.ConversationFactory}.
* <tr><td> Output test failures for clients unwilling to run the test case. <td> {@link Coordinator}
- * <tr><td> Execute coordinated test cases. <td> {@link CoordinatingTestCase}
+ * <tr><td> Execute distributed test cases. <td> {@link DistributedTestCase}
+ * <tr><td> Fail non participating pairings. <td> {@link OptOutTestCase}
* </table>
*/
-public class InvitingTestDecorator extends WrappedSuiteTestDecorator
+public class InteropTestDecorator extends DistributedTestDecorator
{
- private static final Logger log = Logger.getLogger(InvitingTestDecorator.class);
-
- /** Holds the contact information for all test clients that are available and that may take part in the test. */
- Set<TestClientDetails> allClients;
-
- /** Holds the conversation helper for the control level conversation for coordinating the test through. */
- ConversationFactory conversationFactory;
-
- /** Holds the connection that the control conversation is held over. */
- Connection connection;
-
- /** Holds the underlying {@link CoordinatingTestCase}s that this decorator wraps. */
- WrappedSuiteTestDecorator testSuite;
+ /** Used for debugging. */
+ private static final Logger log = Logger.getLogger(InteropTestDecorator.class);
/**
* Creates a wrapped suite test decorator from another one.
@@ -68,24 +65,16 @@ public class InvitingTestDecorator extends WrappedSuiteTestDecorator
* @param controlConversation The conversation helper for the control level, test coordination conversation.
* @param controlConnection The connection that the coordination messages are sent over.
*/
- public InvitingTestDecorator(WrappedSuiteTestDecorator suite, Set<TestClientDetails> availableClients,
+ public InteropTestDecorator(WrappedSuiteTestDecorator suite, Set<TestClientDetails> availableClients,
ConversationFactory controlConversation, Connection controlConnection)
{
- super(suite);
-
- log.debug("public InvitingTestDecorator(WrappedSuiteTestDecorator suite, Set<TestClientDetails> allClients = "
- + availableClients + ", ConversationHelper controlConversation = " + controlConversation + "): called");
-
- testSuite = suite;
- allClients = availableClients;
- conversationFactory = controlConversation;
- connection = controlConnection;
+ super(suite, availableClients, controlConversation, controlConnection);
}
/**
* Broadcasts a test invitation and accetps enlisting from participating clients. The wrapped test case is
* then repeated for every combination of test clients (provided the wrapped test case extends
- * {@link CoordinatingTestCase}.
+ * {@link DistributedTestCase}.
*
* <p/>Any JMSExceptions during the invite/enlist conversation will be allowed to fall through as runtime exceptions,
* resulting in the non-completion of the test run.
@@ -102,29 +91,10 @@ public class InvitingTestDecorator extends WrappedSuiteTestDecorator
for (Test test : tests)
{
- CoordinatingTestCase coordTest = (CoordinatingTestCase) test;
+ DistributedTestCase coordTest = (DistributedTestCase) test;
// Broadcast the invitation to find out what clients are available to test.
- Set<TestClientDetails> enlists;
- try
- {
- Message invite = conversationFactory.getSession().createMessage();
- Destination controlTopic = conversationFactory.getSession().createTopic("iop.control");
- ConversationFactory.Conversation conversation = conversationFactory.startConversation();
-
- invite.setStringProperty("CONTROL_TYPE", "INVITE");
- invite.setStringProperty("TEST_NAME", coordTest.getTestCaseNameForTestMethod(coordTest.getName()));
-
- conversation.send(controlTopic, invite);
-
- // Wait for a short time, to give test clients an opportunity to reply to the invitation.
- Collection<Message> replies = conversation.receiveAll(allClients.size(), 3000);
- enlists = Coordinator.extractEnlists(replies);
- }
- catch (JMSException e)
- {
- throw new RuntimeException("There was a JMSException during the invite/enlist conversation.", e);
- }
+ Set<TestClientDetails> enlists = signupClients(coordTest);
// Compare the list of willing clients to the list of all available.
Set<TestClientDetails> optOuts = new HashSet<TestClientDetails>(allClients);
@@ -135,9 +105,14 @@ public class InvitingTestDecorator extends WrappedSuiteTestDecorator
for (List<TestClientDetails> failPair : failPairs)
{
- CoordinatingTestCase failTest = new OptOutTestCase("testOptOut");
- failTest.setSender(failPair.get(0));
- failTest.setReceiver(failPair.get(1));
+ // Create a distributed test sequencer for the test.
+ DistributedTestSequencer sequencer = getDistributedTestSequencer();
+
+ // Create an automatic failure test for the opted out test pair.
+ DistributedTestCase failTest = new OptOutTestCase("testOptOut");
+ sequencer.setSender(failPair.get(0));
+ sequencer.setReceiver(failPair.get(1));
+ failTest.setTestSequencer(sequencer);
failTest.run(testResult);
}
@@ -147,27 +122,32 @@ public class InvitingTestDecorator extends WrappedSuiteTestDecorator
for (List<TestClientDetails> enlistedPair : enlistedPairs)
{
- // Set the sending and receiving client details on the test case.
- coordTest.setSender(enlistedPair.get(0));
- coordTest.setReceiver(enlistedPair.get(1));
+ // Create a distributed test sequencer for the test.
+ DistributedTestSequencer sequencer = getDistributedTestSequencer();
+
+ // Set the sending and receiving client details on the test sequencer.
+ sequencer.setSender(enlistedPair.get(0));
+ sequencer.setReceiver(enlistedPair.get(1));
// Pass down the connection to hold the coordination conversation over.
- coordTest.setConversationFactory(conversationFactory);
+ sequencer.setConversationFactory(conversationFactory);
// Execute the test case.
+ coordTest.setTestSequencer(sequencer);
coordTest.run(testResult);
}
}
}
/**
- * Prints a string summarizing this test decorator, mainly for debugging purposes.
+ * Should provide the distributed test sequencer to pass to {@link org.apache.qpid.test.framework.FrameworkBaseCase}
+ * tests.
*
- * @return String representation for debugging purposes.
+ * @return A distributed test sequencer.
*/
- public String toString()
+ public DistributedTestSequencer getDistributedTestSequencer()
{
- return "InvitingTestDecorator: [ testSuite = " + testSuite + " ]";
+ return new InteropTestSequencer();
}
/**
@@ -177,6 +157,7 @@ public class InvitingTestDecorator extends WrappedSuiteTestDecorator
*
* @param left The left set.
* @param right The right set.
+ * @param <E> The type of the content of the pairs.
*
* @return All pairs formed from the permutations of all elements of the left and right sets.
*/
@@ -210,6 +191,12 @@ public class InvitingTestDecorator extends WrappedSuiteTestDecorator
*/
private class Pair<T> extends ArrayList<T>
{
+ /**
+ * Creates a new pair of elements.
+ *
+ * @param first The first element.
+ * @param second The second element.
+ */
public Pair(T first, T second)
{
super();
diff --git a/java/integrationtests/src/main/java/org/apache/qpid/interop/coordinator/OptOutTestCase.java b/java/systests/src/main/java/org/apache/qpid/test/framework/distributedtesting/OptOutTestCase.java
index 42a382a898..83ec12ad56 100644
--- a/java/integrationtests/src/main/java/org/apache/qpid/interop/coordinator/OptOutTestCase.java
+++ b/java/systests/src/main/java/org/apache/qpid/test/framework/distributedtesting/OptOutTestCase.java
@@ -18,21 +18,21 @@
* under the License.
*
*/
-package org.apache.qpid.interop.coordinator;
+package org.apache.qpid.test.framework.distributedtesting;
-import junit.framework.Assert;
+import org.apache.qpid.test.framework.sequencers.DistributedTestSequencer;
/**
* An OptOutTestCase is a test case that automatically fails. It is used when a list of test clients has been generated
* from a compulsory invite, but only some of those clients have responded to a specific test case invite. The clients
- * that did not respond, are automatically given a fail for the test.
+ * that did not respond, may automatically be given a fail for some tests.
*
* <p><table id="crc"><caption>CRC Card</caption>
* <tr><th> Responsibilities <th> Collaborations
* <tr><td> Fail the test with a suitable reason.
* </table>
*/
-public class OptOutTestCase extends CoordinatingTestCase
+public class OptOutTestCase extends DistributedTestCase
{
/**
* Creates a new coordinating test case with the specified name.
@@ -47,7 +47,10 @@ public class OptOutTestCase extends CoordinatingTestCase
/** Generates an appropriate test failure assertion. */
public void testOptOut()
{
- Assert.fail("One of " + getSender() + " and " + getReceiver() + " opted out of the test.");
+ DistributedTestSequencer sequencer = getDistributedTestSequencer();
+
+ fail("One of " + sequencer.getSender() + " and " + getDistributedTestSequencer().getReceivers()
+ + " opted out of the test.");
}
/**
diff --git a/java/integrationtests/src/main/java/org/apache/qpid/interop/coordinator/XMLTestListener.java b/java/systests/src/main/java/org/apache/qpid/test/framework/listeners/XMLTestListener.java
index 747ba0dd0b..ee274a1e01 100644
--- a/java/integrationtests/src/main/java/org/apache/qpid/interop/coordinator/XMLTestListener.java
+++ b/java/systests/src/main/java/org/apache/qpid/test/framework/listeners/XMLTestListener.java
@@ -18,13 +18,7 @@
* under the License.
*
*/
-
-package org.apache.qpid.interop.coordinator;
-
-import java.io.IOException;
-import java.io.PrintWriter;
-import java.io.Writer;
-import java.util.*;
+package org.apache.qpid.test.framework.listeners;
import junit.framework.AssertionFailedError;
import junit.framework.Test;
@@ -34,6 +28,11 @@ import org.apache.log4j.Logger;
import uk.co.thebadgerset.junit.extensions.listeners.TKTestListener;
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.io.Writer;
+import java.util.*;
+
/**
* Listens for test results for a named test and outputs these in the standard JUnit XML format to the specified
* writer.
@@ -50,6 +49,12 @@ import uk.co.thebadgerset.junit.extensions.listeners.TKTestListener;
*
* <p><table id="crc"><caption>CRC Card</caption>
* <tr><th> Responsibilities <th> Collaborations
+ * <tr><td> Listen to test lifecycle notifications.
+ * <tr><td> Listen to test errors and failures.
+ * <tr><td> Listen to test timings.
+ * <tr><td> Listen to test memory usages.
+ * <tr><td> Listen to parameterized test parameters.
+ * <tr><th> Responsibilities
* </table>
*
* @todo Merge this class with CSV test listener, making the collection of results common to both, and only factoring
@@ -97,7 +102,8 @@ public class XMLTestListener implements TKTestListener
/**
* Creates a new XML results output listener that writes to the specified location.
*
- * @param writer The location to write results to.
+ * @param writer The location to write results to.
+ * @param testClassName The name of the test class to include in the test results.
*/
public XMLTestListener(Writer writer, String testClassName)
{
@@ -126,7 +132,9 @@ public class XMLTestListener implements TKTestListener
}
/**
- * A test started.
+ * Notification that a test started.
+ *
+ * @param test The test that started.
*/
public void startTest(Test test)
{
@@ -189,7 +197,9 @@ public class XMLTestListener implements TKTestListener
{ }
/**
- * A test ended.
+ * Notification that a test ended.
+ *
+ * @param test The test that ended.
*/
public void endTest(Test test)
{
@@ -225,6 +235,9 @@ public class XMLTestListener implements TKTestListener
/**
* An error occurred.
+ *
+ * @param test The test in which the error occurred.
+ * @param t The throwable that resulted from the error.
*/
public void addError(Test test, Throwable t)
{
@@ -237,6 +250,9 @@ public class XMLTestListener implements TKTestListener
/**
* A failure occurred.
+ *
+ * @param test The test in which the failure occurred.
+ * @param t The JUnit assertions that led to the failure.
*/
public void addFailure(Test test, AssertionFailedError t)
{
@@ -339,13 +355,10 @@ public class XMLTestListener implements TKTestListener
*/
protected static class Result
{
- public Result(String testClass, String testName)
- {
- this.testClass = testClass;
- this.testName = testName;
- }
-
+ /** Holds the name of the test class. */
public String testClass;
+
+ /** Holds the name of the test method. */
public String testName;
/** Holds the exception that caused error in this test. */
@@ -354,49 +367,16 @@ public class XMLTestListener implements TKTestListener
/** Holds the assertion exception that caused failure in this test. */
public AssertionFailedError failure;
- /** Holds the error count for this test. */
- // public int errors = 0;
-
- /** Holds the failure count for this tests. */
- // public int failures = 0;
-
- /** Holds the overall tests run count for this test. */
- // public int runs = 0;
-
- /*public boolean equals(Object o)
+ /**
+ * Creates a placeholder for the results of a test.
+ *
+ * @param testClass The test class.
+ * @param testName The name of the test that was run.
+ */
+ public Result(String testClass, String testName)
{
- if (this == o)
- {
- return true;
- }
-
- if (!(o instanceof Result))
- {
- return false;
- }
-
- final Result result = (Result) o;
-
- if ((testClass != null) ? (!testClass.equals(result.testClass)) : (result.testClass != null))
- {
- return false;
- }
-
- if ((testName != null) ? (!testName.equals(result.testName)) : (result.testName != null))
- {
- return false;
- }
-
- return true;
+ this.testClass = testClass;
+ this.testName = testName;
}
-
- public int hashCode()
- {
- int result;
- result = ((testClass != null) ? testClass.hashCode() : 0);
- result = (29 * result) + ((testName != null) ? testName.hashCode() : 0);
-
- return result;
- }*/
}
}
diff --git a/java/systests/src/main/java/org/apache/qpid/test/framework/localcircuit/CircuitImpl.java b/java/systests/src/main/java/org/apache/qpid/test/framework/localcircuit/CircuitImpl.java
new file mode 100644
index 0000000000..3c678eef7d
--- /dev/null
+++ b/java/systests/src/main/java/org/apache/qpid/test/framework/localcircuit/CircuitImpl.java
@@ -0,0 +1,394 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT 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.framework.localcircuit;
+
+import org.apache.qpid.client.AMQSession;
+import org.apache.qpid.test.framework.*;
+
+import uk.co.thebadgerset.junit.extensions.util.ParsedProperties;
+
+import javax.jms.*;
+
+import java.util.LinkedList;
+import java.util.List;
+import java.util.concurrent.atomic.AtomicLong;
+
+/**
+ * CircuitImpl provides an implementation of the test circuit. This is a first prototype implementation and only supports
+ * a single producer/consumer on each end of the circuit, with both ends of the circuit on the same JVM.
+ *
+ * <p/><table id="crc"><caption>CRC Card</caption>
+ * <tr><th> Responsibilities <th> Collaborations
+ * <tr><td> Supply the publishing and receiving ends of a test messaging circuit.
+ * <td> {@link PublisherImpl}, {@link ReceiverImpl}
+ * <tr><td> Start the circuit running.
+ * <tr><td> Close the circuit down.
+ * <tr><td> Take a reading of the circuits state.
+ * <tr><td> Apply assertions against the circuits state. <td> {@link org.apache.qpid.test.framework.Assertion}
+ * <tr><td> Send test messages over the circuit.
+ * <tr><td> Perform the default test procedure on the circuit.
+ * <tr><td> Provide access to connection and session exception monitors <td> {@link org.apache.qpid.test.framework.ExceptionMonitor}
+ * </table>
+ *
+ * @todo Add ability to create routes with no consumers active on them. Immediate/Mandatory tests are closing consumers
+ * themsleves to create this scenario. Should make it part of the test configuration.
+ */
+public class CircuitImpl implements Circuit
+{
+ /** Used to create unique destination names for each test. */
+ private static AtomicLong uniqueDestsId = new AtomicLong();
+
+ /** Holds the test configuration for the circuit. */
+ private ParsedProperties testProps;
+
+ /** Holds the publishing end of the circuit. */
+ private PublisherImpl publisher;
+
+ /** Holds the receiving end of the circuit. */
+ private ReceiverImpl receiver;
+
+ /** Holds the connection for the publishing end of the circuit. */
+ private Connection connection;
+
+ /** Holds the exception listener for the connection on the publishing end of the circuit. */
+ private ExceptionMonitor connectionExceptionMonitor;
+
+ /** Holds the exception listener for the session on the publishing end of the circuit. */
+ private ExceptionMonitor exceptionMonitor;
+
+ /**
+ * Creates a test circuit using the specified test parameters. The publisher, receivers, connection and
+ * connection monitor must already have been created, to assemble the circuit.
+ *
+ * @param testProps The test parameters.
+ * @param publisher The test publisher.
+ * @param receiver The test receivers.
+ * @param connection The connection.
+ * @param connectionExceptionMonitor The connection exception monitor.
+ */
+ protected CircuitImpl(ParsedProperties testProps, PublisherImpl publisher, ReceiverImpl receiver, Connection connection,
+ ExceptionMonitor connectionExceptionMonitor)
+ {
+ this.testProps = testProps;
+ this.publisher = publisher;
+ this.receiver = receiver;
+ this.connection = connection;
+ this.connectionExceptionMonitor = connectionExceptionMonitor;
+ this.exceptionMonitor = new ExceptionMonitor();
+
+ // Set this as the parent circuit on the publisher and receivers.
+ publisher.setCircuit(this);
+ receiver.setCircuit(this);
+ }
+
+ /**
+ * Creates a test circuit from the specified test parameters.
+ *
+ * @param testProps The test parameters.
+ *
+ * @return A connected and ready to start, test circuit.
+ */
+ public static Circuit createCircuit(ParsedProperties testProps)
+ {
+ // Create a standard publisher/receivers test client pair on a shared connection, individual sessions.
+ try
+ {
+ // ParsedProperties testProps = new ParsedProperties(testProps);
+
+ // Get a unique offset to append to destination names to make them unique to the connection.
+ long uniqueId = uniqueDestsId.incrementAndGet();
+
+ // Extract the standard test configuration parameters relevant to the connection.
+ String destinationSendRoot =
+ testProps.getProperty(MessagingTestConfigProperties.SEND_DESTINATION_NAME_ROOT_PROPNAME) + "_" + uniqueId;
+ String destinationReceiveRoot =
+ testProps.getProperty(MessagingTestConfigProperties.RECEIVE_DESTINATION_NAME_ROOT_PROPNAME) + "_" + uniqueId;
+ boolean createPublisherProducer =
+ testProps.getPropertyAsBoolean(MessagingTestConfigProperties.PUBLISHER_PRODUCER_BIND_PROPNAME);
+ boolean createPublisherConsumer =
+ testProps.getPropertyAsBoolean(MessagingTestConfigProperties.PUBLISHER_CONSUMER_BIND_PROPNAME);
+ boolean createReceiverProducer =
+ testProps.getPropertyAsBoolean(MessagingTestConfigProperties.RECEIVER_PRODUCER_BIND_PROPNAME);
+ boolean createReceiverConsumer =
+ testProps.getPropertyAsBoolean(MessagingTestConfigProperties.RECEIVER_CONSUMER_BIND_PROPNAME);
+
+ // Check which JMS flags and options are to be set.
+ int ackMode = testProps.getPropertyAsInteger(MessagingTestConfigProperties.ACK_MODE_PROPNAME);
+ boolean useTopics = testProps.getPropertyAsBoolean(MessagingTestConfigProperties.PUBSUB_PROPNAME);
+ boolean transactional = testProps.getPropertyAsBoolean(MessagingTestConfigProperties.TRANSACTED_PROPNAME);
+ boolean durableSubscription =
+ testProps.getPropertyAsBoolean(MessagingTestConfigProperties.DURABLE_SUBSCRIPTION_PROPNAME);
+
+ // Check if any Qpid/AMQP specific flags or options need to be set.
+ boolean immediate = testProps.getPropertyAsBoolean(MessagingTestConfigProperties.IMMEDIATE_PROPNAME);
+ boolean mandatory = testProps.getPropertyAsBoolean(MessagingTestConfigProperties.MANDATORY_PROPNAME);
+ boolean needsQpidOptions = immediate | mandatory;
+
+ /*log.debug("ackMode = " + ackMode);
+ log.debug("useTopics = " + useTopics);
+ log.debug("destinationSendRoot = " + destinationSendRoot);
+ log.debug("destinationReceiveRoot = " + destinationReceiveRoot);
+ log.debug("createPublisherProducer = " + createPublisherProducer);
+ log.debug("createPublisherConsumer = " + createPublisherConsumer);
+ log.debug("createReceiverProducer = " + createReceiverProducer);
+ log.debug("createReceiverConsumer = " + createReceiverConsumer);
+ log.debug("transactional = " + transactional);
+ log.debug("immediate = " + immediate);
+ log.debug("mandatory = " + mandatory);
+ log.debug("needsQpidOptions = " + needsQpidOptions);*/
+
+ // Create connection, sessions and producer/consumer pairs on each session.
+ Connection connection = TestUtils.createConnection(testProps);
+
+ // Add the connection exception listener to assert on exception conditions with.
+ ExceptionMonitor exceptionMonitor = new ExceptionMonitor();
+ connection.setExceptionListener(exceptionMonitor);
+
+ Session publisherSession = connection.createSession(transactional, ackMode);
+ Session receiverSession = connection.createSession(transactional, ackMode);
+
+ Destination publisherProducerDestination =
+ useTopics ? publisherSession.createTopic(destinationSendRoot)
+ : publisherSession.createQueue(destinationSendRoot);
+
+ MessageProducer publisherProducer =
+ createPublisherProducer
+ ? (needsQpidOptions
+ ? ((AMQSession) publisherSession).createProducer(publisherProducerDestination, mandatory, immediate)
+ : publisherSession.createProducer(publisherProducerDestination)) : null;
+
+ MessageConsumer publisherConsumer =
+ createPublisherConsumer
+ ? publisherSession.createConsumer(publisherSession.createQueue(destinationReceiveRoot)) : null;
+
+ if (publisherConsumer != null)
+ {
+ publisherConsumer.setMessageListener(new MessageMonitor());
+ }
+
+ MessageProducer receiverProducer =
+ createReceiverProducer ? receiverSession.createProducer(receiverSession.createQueue(destinationReceiveRoot))
+ : null;
+
+ Destination receiverConsumerDestination =
+ useTopics ? receiverSession.createTopic(destinationSendRoot)
+ : receiverSession.createQueue(destinationSendRoot);
+
+ MessageConsumer receiverConsumer =
+ createReceiverConsumer
+ ? ((durableSubscription && useTopics)
+ ? receiverSession.createDurableSubscriber((Topic) receiverConsumerDestination, "testsub")
+ : receiverSession.createConsumer(receiverConsumerDestination)) : null;
+
+ if (receiverConsumer != null)
+ {
+ receiverConsumer.setMessageListener(new MessageMonitor());
+ }
+
+ // Start listening for incoming messages.
+ connection.start();
+
+ // Package everything up.
+ PublisherImpl publisher = new PublisherImpl(publisherProducer, publisherConsumer, publisherSession);
+ ReceiverImpl receiver = new ReceiverImpl(receiverProducer, receiverConsumer, receiverSession);
+
+ return new CircuitImpl(testProps, publisher, receiver, connection, exceptionMonitor);
+ }
+ catch (JMSException e)
+ {
+ throw new RuntimeException("Could not create publisher/receivers pair due to a JMSException.", e);
+ }
+ }
+
+ /**
+ * Gets the interface on the publishing end of the circuit.
+ *
+ * @return The publishing end of the circuit.
+ */
+ public Publisher getPublisher()
+ {
+ return publisher;
+ }
+
+ /**
+ * Gets the interface on the receiving end of the circuit.
+ *
+ * @return The receiving end of the circuit.
+ */
+ public Receiver getReceiver()
+ {
+ return receiver;
+ }
+
+ /**
+ * Checks the test circuit. The effect of this is to gather the circuits state, for both ends of the circuit,
+ * into a report, against which assertions may be checked.
+ */
+ public void check()
+ { }
+
+ /**
+ * Applied a list of assertions against the test circuit. The {@link #check()} method should be called before doing
+ * this, to ensure that the circuit has gathered its state into a report to assert against.
+ *
+ * @param assertions The list of assertions to apply.
+ * @return Any assertions that failed.
+ */
+ public List<Assertion> applyAssertions(List<Assertion> assertions)
+ {
+ List<Assertion> failures = new LinkedList<Assertion>();
+
+ for (Assertion assertion : assertions)
+ {
+ if (!assertion.apply())
+ {
+ failures.add(assertion);
+ }
+ }
+
+ return failures;
+ }
+
+ /**
+ * Connects and starts the circuit. After this method is called the circuit is ready to send messages.
+ */
+ public void start()
+ { }
+
+ /**
+ * Closes the circuit. All associated resources are closed.
+ */
+ public void close()
+ {
+ try
+ {
+ publisher.close();
+ receiver.close();
+ connection.close();
+ }
+ catch (JMSException e)
+ {
+ throw new RuntimeException("Got JMSException during close.", e);
+ }
+ }
+
+ /**
+ * Sends a message on the test circuit. The exact nature of the message sent is controlled by the test parameters.
+ */
+ public void send()
+ {
+ boolean transactional = testProps.getPropertyAsBoolean(MessagingTestConfigProperties.TRANSACTED_PROPNAME);
+
+ // Send an immediate message through the publisher and ensure that it results in a JMSException.
+ try
+ {
+ getPublisher().send(createTestMessage(getPublisher()));
+
+ if (transactional)
+ {
+ getPublisher().getSession().commit();
+ }
+ }
+ catch (JMSException e)
+ {
+ exceptionMonitor.onException(e);
+ }
+ }
+
+ /**
+ * Runs the default test procedure against the circuit, and checks that all of the specified assertions hold. The
+ * outline of the default test procedure is:
+ *
+ * <p/><pre>
+ * Start the circuit.
+ * Send test messages.
+ * Request a status report.
+ * Assert conditions on the publishing end of the circuit.
+ * Assert conditions on the receiving end of the circuit.
+ * Close the circuit.
+ * Pass with no failed assertions or fail with a list of failed assertions.
+ * </pre>
+ *
+ * @param numMessages The number of messages to send using the default test procedure.
+ * @param assertions The list of assertions to apply.
+ * @return Any assertions that failed.
+ */
+ public List<Assertion> test(int numMessages, List<Assertion> assertions)
+ {
+ // Start the test circuit.
+ start();
+
+ // Send the requested number of test messages.
+ for (int i = 0; i < numMessages; i++)
+ {
+ send();
+ }
+
+ // Inject a short pause to allow time for exceptions to come back asynchronously.
+ TestUtils.pause(100L);
+
+ // Request a status report.
+ check();
+
+ // Apply all of the requested assertions, keeping record of any that fail.
+ List<Assertion> failures = applyAssertions(assertions);
+
+ // Clean up the publisher/receivers/session/connections.
+ close();
+
+ // Return any failed assertions to the caller.
+ return failures;
+ }
+
+ /**
+ * Creates a message with the properties defined as per the test parameters.
+ *
+ * @param client The circuit end to create the message on.
+ *
+ * @return The test message.
+ *
+ * @throws JMSException Any JMSException occurring during creation of the message is allowed to fall through.
+ */
+ private Message createTestMessage(CircuitEnd client) throws JMSException
+ {
+ return client.getSession().createTextMessage("Hello");
+ }
+
+ /**
+ * Gets the exception monitor for the publishing ends connection.
+ *
+ * @return The exception monitor for the publishing ends connection.
+ */
+ public ExceptionMonitor getConnectionExceptionMonitor()
+ {
+ return connectionExceptionMonitor;
+ }
+
+ /**
+ * Gets the exception monitor for the publishing ends session.
+ *
+ * @return The exception monitor for the publishing ends session.
+ */
+ public ExceptionMonitor getExceptionMonitor()
+ {
+ return exceptionMonitor;
+ }
+}
diff --git a/java/systests/src/main/java/org/apache/qpid/test/framework/localcircuit/PublisherImpl.java b/java/systests/src/main/java/org/apache/qpid/test/framework/localcircuit/PublisherImpl.java
new file mode 100644
index 0000000000..5b63607867
--- /dev/null
+++ b/java/systests/src/main/java/org/apache/qpid/test/framework/localcircuit/PublisherImpl.java
@@ -0,0 +1,162 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT 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.framework.localcircuit;
+
+import org.apache.qpid.client.AMQNoConsumersException;
+import org.apache.qpid.client.AMQNoRouteException;
+import org.apache.qpid.test.framework.localcircuit.CircuitImpl;
+import org.apache.qpid.test.framework.*;
+
+import javax.jms.MessageConsumer;
+import javax.jms.MessageProducer;
+import javax.jms.Session;
+
+/**
+ * Provides an implementation of the {@link org.apache.qpid.test.framework.Publisher} interface that wraps a single message producer and consumer on
+ * a single session.
+ *
+ * <p/><table id="crc"><caption>CRC Card</caption>
+ * <tr><th> Responsibilities <th> Collaborations
+ * <tr><td> Provide a message producer for sending messages.
+ * <tr><td> Provide a message consumer for receiving messages.
+ * <tr><td> Provide assertion that the publisher received no exceptions.
+ * <tr><td> Provide assertion that the publisher received a no consumers error code.
+ * <tr><td> Provide assertion that the publisher received a no route error code.
+ * </table>
+ */
+public class PublisherImpl extends CircuitEndBase implements Publisher
+{
+ /** Holds a reference to the containing circuit. */
+ private CircuitImpl circuit;
+
+ /**
+ * Creates a circuit end point on the specified producer, consumer and session.
+ *
+ * @param producer The message producer for the circuit end point.
+ * @param consumer The message consumer for the circuit end point.
+ * @param session The session for the circuit end point.
+ */
+ public PublisherImpl(MessageProducer producer, MessageConsumer consumer, Session session)
+ {
+ super(producer, consumer, session);
+ }
+
+ /**
+ * Provides an assertion that the publisher encountered no exceptions.
+ *
+ * @return An assertion that the publisher encountered no exceptions.
+ */
+ public Assertion noExceptionsAssertion()
+ {
+ return new AssertionBase()
+ {
+ public boolean apply()
+ {
+ boolean passed = true;
+ ExceptionMonitor sessionExceptionMonitor = circuit.getExceptionMonitor();
+ ExceptionMonitor connectionExceptionMonitor = circuit.getConnectionExceptionMonitor();
+
+ if (!connectionExceptionMonitor.assertNoExceptions())
+ {
+ passed = false;
+ addError("Was expecting no exceptions.\n");
+ addError("Got the following exceptions on the connection, "
+ + circuit.getConnectionExceptionMonitor());
+ }
+
+ if (!sessionExceptionMonitor.assertNoExceptions())
+ {
+ passed = false;
+ addError("Was expecting no exceptions.\n");
+ addError("Got the following exceptions on the producer, " + circuit.getExceptionMonitor());
+ }
+
+ return passed;
+ }
+ };
+ }
+
+ /**
+ * Provides an assertion that the publisher got a no consumers exception on every message.
+ *
+ * @return An assertion that the publisher got a no consumers exception on every message.
+ */
+ public Assertion noConsumersAssertion()
+ {
+ return new AssertionBase()
+ {
+ public boolean apply()
+ {
+ boolean passed = true;
+ ExceptionMonitor connectionExceptionMonitor = circuit.getConnectionExceptionMonitor();
+
+ if (!connectionExceptionMonitor.assertOneJMSExceptionWithLinkedCause(AMQNoConsumersException.class))
+ {
+ addError("Was expecting linked exception type " + AMQNoConsumersException.class.getName()
+ + " on the connection.\n");
+ addError((connectionExceptionMonitor.size() > 0)
+ ? ("Actually got the following exceptions on the connection, " + connectionExceptionMonitor)
+ : "Got no exceptions on the connection.");
+ }
+
+ return passed;
+ }
+ };
+ }
+
+ /**
+ * Provides an assertion that the publisher got a no rout exception on every message.
+ *
+ * @return An assertion that the publisher got a no rout exception on every message.
+ */
+ public Assertion noRouteAssertion()
+ {
+ return new AssertionBase()
+ {
+ public boolean apply()
+ {
+ boolean passed = true;
+ ExceptionMonitor connectionExceptionMonitor = circuit.getConnectionExceptionMonitor();
+
+ if (!connectionExceptionMonitor.assertOneJMSExceptionWithLinkedCause(AMQNoRouteException.class))
+ {
+ addError("Was expecting linked exception type " + AMQNoRouteException.class.getName()
+ + " on the connection.\n");
+ addError((connectionExceptionMonitor.size() > 0)
+ ? ("Actually got the following exceptions on the connection, " + connectionExceptionMonitor)
+ : "Got no exceptions on the connection.");
+ }
+
+ return passed;
+ }
+ };
+ }
+
+ /**
+ * Sets the contianing circuit.
+ *
+ * @param circuit The containing circuit.
+ */
+ public void setCircuit(CircuitImpl circuit)
+ {
+ this.circuit = circuit;
+ }
+}
diff --git a/java/systests/src/main/java/org/apache/qpid/test/framework/localcircuit/ReceiverImpl.java b/java/systests/src/main/java/org/apache/qpid/test/framework/localcircuit/ReceiverImpl.java
new file mode 100644
index 0000000000..6dd7056806
--- /dev/null
+++ b/java/systests/src/main/java/org/apache/qpid/test/framework/localcircuit/ReceiverImpl.java
@@ -0,0 +1,90 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.qpid.test.framework.localcircuit;
+
+import org.apache.qpid.test.framework.localcircuit.CircuitImpl;
+import org.apache.qpid.test.framework.CircuitEndBase;
+import org.apache.qpid.test.framework.Receiver;
+import org.apache.qpid.test.framework.Assertion;
+
+import javax.jms.MessageConsumer;
+import javax.jms.MessageProducer;
+import javax.jms.Session;
+
+/**
+ * Provides an implementation of the {@link org.apache.qpid.test.framework.Receiver} interface that wraps a single message producer and consumer on
+ * a single session.
+ *
+ * <p/><table id="crc"><caption>CRC Card</caption>
+ * <tr><th> Responsibilities <th> Collaborations
+ * <tr><td> Provide a message producer for sending messages.
+ * <tr><td> Provide a message consumer for receiving messages.
+ * <tr><td> Provide assertion that the receivers received no exceptions.
+ * <tr><td> Provide assertion that the receivers received all test messages sent to it.
+ * </table>
+ */
+public class ReceiverImpl extends CircuitEndBase implements Receiver
+{
+ /** Holds a reference to the containing circuit. */
+ private CircuitImpl circuit;
+
+ /**
+ * Creates a circuit end point on the specified producer, consumer and session.
+ *
+ * @param producer The message producer for the circuit end point.
+ * @param consumer The message consumer for the circuit end point.
+ * @param session The session for the circuit end point.
+ */
+ public ReceiverImpl(MessageProducer producer, MessageConsumer consumer, Session session)
+ {
+ super(producer, consumer, session);
+ }
+
+ /**
+ * Provides an assertion that the receivers encountered no exceptions.
+ *
+ * @return An assertion that the receivers encountered no exceptions.
+ */
+ public Assertion noExceptionsAssertion()
+ {
+ return null;
+ }
+
+ /**
+ * Provides an assertion that the receivers got all messages that were sent to it.
+ *
+ * @return An assertion that the receivers got all messages that were sent to it.
+ */
+ public Assertion allMessagesAssertion()
+ {
+ return null;
+ }
+
+ /**
+ * Sets the contianing circuit.
+ *
+ * @param circuit The containing circuit.
+ */
+ public void setCircuit(CircuitImpl circuit)
+ {
+ this.circuit = circuit;
+ }
+}
diff --git a/java/systests/src/main/java/org/apache/qpid/test/framework/package.html b/java/systests/src/main/java/org/apache/qpid/test/framework/package.html
new file mode 100644
index 0000000000..f07a5118e7
--- /dev/null
+++ b/java/systests/src/main/java/org/apache/qpid/test/framework/package.html
@@ -0,0 +1,22 @@
+<html>
+<body>
+<p/>A framework for testing Qpid, built around a standard 'test circuit' design. The idea behind this framework is the
+use of a test circuit which is configured by a set of test parameters, that may be projected onto a topology of
+test nodes, with tests scripted to run over test circuits, making as few assumptions as possible about the underlying
+topology. The standardization of the design, whilst limiting in some respectes, allows a large variety of test
+scenarios to be written with minimal amounts of coding.
+
+<p/>The standard consruction block for a test, is a test circuit. This consists of a publisher, and a receiver. The
+publisher and receiver may reside on the same machine, or may be distributed. Will use a standard set of properties to
+define the desired circuit topology.
+
+<p/>Tests are always to be controlled from the publishing side only. The receiving end of the circuit is to be exposed
+to the test code through an interface, that abstracts as much as possible the receiving end of the test. The interface
+exposes a set of 'assertions' that may be applied to the receiving end of the test circuit.
+
+<p/>In the case where the receiving end of the circuit resides on the same JVM, the assertions will call the receivers
+code locally. Where the receiving end is distributed accross one or more machines, the assertions will be applied to a
+test report gethered from all of the receivers. Test code will be written to the assertions making as few assumptions
+as possible about the exact test topology.
+</body>
+</html> \ No newline at end of file
diff --git a/java/systests/src/main/java/org/apache/qpid/test/framework/sequencers/BaseDistributedTestSequencer.java b/java/systests/src/main/java/org/apache/qpid/test/framework/sequencers/BaseDistributedTestSequencer.java
new file mode 100644
index 0000000000..a0e3d3b4a6
--- /dev/null
+++ b/java/systests/src/main/java/org/apache/qpid/test/framework/sequencers/BaseDistributedTestSequencer.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.test.framework.sequencers;
+
+import org.apache.log4j.Logger;
+
+import org.apache.qpid.test.framework.distributedtesting.DistributedTestCase;
+import org.apache.qpid.test.framework.TestClientDetails;
+import org.apache.qpid.test.framework.Circuit;
+import org.apache.qpid.util.ConversationFactory;
+
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Properties;
+
+/**
+ * <p/><table id="crc"><caption>CRC Card</caption>
+ * <tr><th> Responsibilities <th> Collaborations
+ * <tr><td>
+ * </table>
+ */
+public abstract class BaseDistributedTestSequencer implements DistributedTestSequencer
+{
+ /** Used for debugging. */
+ private final Logger log = Logger.getLogger(DistributedTestCase.class);
+
+ /** Holds the contact details for the sending test client. */
+ protected TestClientDetails sender;
+
+ /** Holds the contact details for the receving test client. */
+ protected List<TestClientDetails> receivers = new LinkedList<TestClientDetails>();
+
+ /** Holds the conversation factory over which to coordinate the test. */
+ protected ConversationFactory conversationFactory;
+
+ /**
+ * Creates a test circuit for the test, configered by the test parameters specified.
+ *
+ * @param testProperties The test parameters.
+ * @return A test circuit.
+ */
+ public Circuit createCircuit(Properties testProperties)
+ {
+ throw new RuntimeException("Not implemented.");
+ }
+
+ /**
+ * Sets the sender test client to coordinate the test with.
+ *
+ * @param sender The contact details of the sending client in the test.
+ */
+ public void setSender(TestClientDetails sender)
+ {
+ log.debug("public void setSender(TestClientDetails sender = " + sender + "): called");
+
+ this.sender = sender;
+ }
+
+ /**
+ * Sets the receiving test client to coordinate the test with.
+ *
+ * @param receiver The contact details of the sending client in the test.
+ */
+ public void setReceiver(TestClientDetails receiver)
+ {
+ log.debug("public void setReceiver(TestClientDetails receivers = " + receiver + "): called");
+
+ this.receivers.add(receiver);
+ }
+
+ /**
+ * Supplies the sending test client.
+ *
+ * @return The sending test client.
+ */
+ public TestClientDetails getSender()
+ {
+ return sender;
+ }
+
+ /**
+ * Supplies the receiving test client.
+ *
+ * @return The receiving test client.
+ */
+ public List<TestClientDetails> getReceivers()
+ {
+ return receivers;
+ }
+
+ /**
+ * Accepts the conversation factory over which to hold the test coordinating conversation.
+ *
+ * @param conversationFactory The conversation factory to coordinate the test over.
+ */
+ public void setConversationFactory(ConversationFactory conversationFactory)
+ {
+ this.conversationFactory = conversationFactory;
+ }
+
+ /**
+ * Provides the conversation factory for providing the distributed test sequencing conversations over the test
+ * connection.
+ *
+ * @return The conversation factory to create test sequencing conversations with.
+ */
+ public ConversationFactory getConversationFactory()
+ {
+ return conversationFactory;
+ }
+}
diff --git a/java/systests/src/main/java/org/apache/qpid/test/framework/sequencers/DistributedTestSequencer.java b/java/systests/src/main/java/org/apache/qpid/test/framework/sequencers/DistributedTestSequencer.java
new file mode 100644
index 0000000000..73e61ec921
--- /dev/null
+++ b/java/systests/src/main/java/org/apache/qpid/test/framework/sequencers/DistributedTestSequencer.java
@@ -0,0 +1,75 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT 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.framework.sequencers;
+
+import org.apache.qpid.test.framework.TestClientDetails;
+import org.apache.qpid.util.ConversationFactory;
+
+import java.util.List;
+
+/**
+ * A DistributedTestSequencer is a test sequencer that coordinates activity amongst many
+ * {@link org.apache.qpid.test.framework.distributedtesting.TestClient}s.
+ *
+ * <p><table id="crc"><caption>CRC Card</caption>
+ * <tr><th> Responsibilities <th> Collaborations
+ * <tr><td> Accept notification of test case participants.
+ * <tr><td> Accept JMS Connection to carry out the coordination over.
+ * <tr><td> Coordinate a test sequence amongst participants. <td> {@link ConversationFactory}
+ * </table>
+ */
+public interface DistributedTestSequencer extends TestCaseSequencer
+{
+ /**
+ * Sets the sender test client to coordinate the test with.
+ *
+ * @param sender The contact details of the sending client in the test.
+ */
+ public void setSender(TestClientDetails sender);
+
+ /**
+ * Sets the receiving test client to coordinate the test with.
+ *
+ * @param receiver The contact details of the sending client in the test.
+ */
+ public void setReceiver(TestClientDetails receiver);
+
+ /**
+ * Supplies the sending test client.
+ *
+ * @return The sending test client.
+ */
+ public TestClientDetails getSender();
+
+ /**
+ * Supplies the receiving test client.
+ *
+ * @return The receiving test client.
+ */
+ public List<TestClientDetails> getReceivers();
+
+ /**
+ * Accepts the conversation factory over which to hold the test coordinating conversation.
+ *
+ * @param conversationFactory The conversation factory to coordinate the test over.
+ */
+ public void setConversationFactory(ConversationFactory conversationFactory);
+}
diff --git a/java/systests/src/main/java/org/apache/qpid/test/framework/sequencers/FanOutTestSequencer.java b/java/systests/src/main/java/org/apache/qpid/test/framework/sequencers/FanOutTestSequencer.java
new file mode 100644
index 0000000000..a116b23065
--- /dev/null
+++ b/java/systests/src/main/java/org/apache/qpid/test/framework/sequencers/FanOutTestSequencer.java
@@ -0,0 +1,171 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.qpid.test.framework.sequencers;
+
+import org.apache.log4j.Logger;
+
+import org.apache.qpid.test.framework.TestClientDetails;
+import org.apache.qpid.test.framework.Assertion;
+import org.apache.qpid.test.framework.Circuit;
+import org.apache.qpid.test.framework.TestUtils;
+import org.apache.qpid.util.ConversationFactory;
+
+import uk.co.thebadgerset.junit.extensions.util.ParsedProperties;
+
+import javax.jms.Destination;
+import javax.jms.JMSException;
+import javax.jms.Message;
+import javax.jms.Session;
+
+import java.util.List;
+import java.util.Properties;
+
+/**
+ * <p/><table id="crc"><caption>CRC Card</caption>
+ * <tr><th> Responsibilities <th> Collaborations
+ * <tr><td>
+ * </table>
+ */
+public class FanOutTestSequencer extends BaseDistributedTestSequencer
+{
+ /** Used for debugging. */
+ Logger log = Logger.getLogger(FanOutTestSequencer.class);
+
+ /**
+ * Holds a test coordinating conversation with the test clients. This should consist of assigning the test roles,
+ * begining the test, gathering the test reports from the participants, and checking for assertion failures against
+ * the test reports.
+ *
+ * @param testCircuit The test circuit.
+ * @param assertions The list of assertions to apply to the test circuit.
+ * @param testProperties The test case definition.
+ */
+ public void sequenceTest(Circuit testCircuit, List<Assertion> assertions, Properties testProperties)
+ {
+ log.debug("protected Message[] sequenceTest(Object... testProperties = " + testProperties + "): called");
+
+ TestClientDetails sender = getSender();
+ List<TestClientDetails> receivers = getReceivers();
+ ConversationFactory conversationFactory = getConversationFactory();
+
+ try
+ {
+ // Create a conversation on the sender clients private control rouete.
+ Session session = conversationFactory.getSession();
+ Destination senderControlTopic = session.createTopic(sender.privateControlKey);
+ ConversationFactory.Conversation senderConversation = conversationFactory.startConversation();
+
+ // Assign the sender role to the sending test client.
+ Message assignSender = conversationFactory.getSession().createMessage();
+ TestUtils.setPropertiesOnMessage(assignSender, testProperties);
+ assignSender.setStringProperty("CONTROL_TYPE", "ASSIGN_ROLE");
+ assignSender.setStringProperty("ROLE", "SENDER");
+ assignSender.setStringProperty("CLIENT_NAME", "Sustained_SENDER");
+
+ senderConversation.send(senderControlTopic, assignSender);
+
+ // Wait for the sender to confirm its role.
+ senderConversation.receive();
+
+ // Assign the receivers roles.
+ for (TestClientDetails receiver : receivers)
+ {
+ assignReceiverRole(receiver, testProperties, true);
+ }
+
+ // Start the test on the sender.
+ Message start = session.createMessage();
+ start.setStringProperty("CONTROL_TYPE", "START");
+
+ senderConversation.send(senderControlTopic, start);
+
+ // Wait for the test sender to return its report.
+ Message senderReport = senderConversation.receive();
+ TestUtils.pause(500);
+
+ // Ask the receivers for their reports.
+ Message statusRequest = session.createMessage();
+ statusRequest.setStringProperty("CONTROL_TYPE", "STATUS_REQUEST");
+
+ // Gather the reports from all of the receiving clients.
+
+ // Return all of the test reports, the senders report first.
+ // return new Message[] { senderReport };
+ }
+ catch (JMSException e)
+ {
+ throw new RuntimeException("Unhandled JMSException.");
+ }
+ }
+
+ /**
+ * Creates a test circuit for the test, configered by the test parameters specified.
+ *
+ * @param testProperties The test parameters.
+ * @return A test circuit.
+ */
+ public Circuit createCircuit(ParsedProperties testProperties)
+ {
+ throw new RuntimeException("Not implemented.");
+ }
+
+ /**
+ * Assigns the receivers role to the specified test client that is to act as a receivers during the test. This method
+ * does not always wait for the receiving clients to confirm their role assignments. This is because this method
+ * may be called from an 'onMessage' method, when a client is joining the test at a later point in time, and it
+ * is not possible to do a synchronous receive during an 'onMessage' method. There is a flag to indicate whether
+ * or not to wait for role confirmations.
+ *
+ * @param receiver The test client to assign the receivers role to.
+ * @param testProperties The test parameters.
+ * @param confirm Indicates whether role confirmation should be waited for.
+ *
+ * @throws JMSException Any JMSExceptions occurring during the conversation are allowed to fall through.
+ */
+ protected void assignReceiverRole(TestClientDetails receiver, Properties testProperties, boolean confirm)
+ throws JMSException
+ {
+ log.info("assignReceiverRole(TestClientDetails receivers = " + receiver + ", Map<String, Object> testProperties = "
+ + testProperties + "): called");
+
+ ConversationFactory conversationFactory = getConversationFactory();
+
+ // Create a conversation with the receiving test client.
+ Session session = conversationFactory.getSession();
+ Destination receiverControlTopic = session.createTopic(receiver.privateControlKey);
+ ConversationFactory.Conversation receiverConversation = conversationFactory.startConversation();
+
+ // Assign the receivers role to the receiving client.
+ Message assignReceiver = session.createMessage();
+ TestUtils.setPropertiesOnMessage(assignReceiver, testProperties);
+ assignReceiver.setStringProperty("CONTROL_TYPE", "ASSIGN_ROLE");
+ assignReceiver.setStringProperty("ROLE", "RECEIVER");
+ assignReceiver.setStringProperty("CLIENT_NAME", receiver.clientName);
+
+ receiverConversation.send(receiverControlTopic, assignReceiver);
+
+ // Wait for the role confirmation to come back.
+ if (confirm)
+ {
+ receiverConversation.receive();
+ }
+ }
+}
diff --git a/java/systests/src/main/java/org/apache/qpid/test/framework/sequencers/InteropTestSequencer.java b/java/systests/src/main/java/org/apache/qpid/test/framework/sequencers/InteropTestSequencer.java
new file mode 100644
index 0000000000..f2253d416b
--- /dev/null
+++ b/java/systests/src/main/java/org/apache/qpid/test/framework/sequencers/InteropTestSequencer.java
@@ -0,0 +1,137 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT 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.framework.sequencers;
+
+import org.apache.log4j.Logger;
+
+import org.apache.qpid.test.framework.TestClientDetails;
+import org.apache.qpid.test.framework.Assertion;
+import org.apache.qpid.test.framework.Circuit;
+import org.apache.qpid.test.framework.TestUtils;
+import org.apache.qpid.util.ConversationFactory;
+
+import uk.co.thebadgerset.junit.extensions.util.ParsedProperties;
+
+import javax.jms.Destination;
+import javax.jms.JMSException;
+import javax.jms.Message;
+import javax.jms.Session;
+
+import java.util.List;
+import java.util.Properties;
+
+/**
+ * <p/><table id="crc"><caption>CRC Card</caption>
+ * <tr><th> Responsibilities <th> Collaborations
+ * <tr><td>
+ * </table>
+ */
+public class InteropTestSequencer extends BaseDistributedTestSequencer
+{
+ /** Used for debugging. */
+ Logger log = Logger.getLogger(InteropTestSequencer.class);
+
+ /**
+ * Holds a test coordinating conversation with the test clients. This should consist of assigning the test roles,
+ * begining the test, gathering the test reports from the participants, and checking for assertion failures against
+ * the test reports.
+ *
+ * @param testCircuit The test circuit.
+ * @param assertions The list of assertions to apply to the test circuit.
+ * @param testProperties The test case definition.
+ */
+ public void sequenceTest(Circuit testCircuit, List<Assertion> assertions, Properties testProperties)
+ {
+ log.debug("protected Message[] sequenceTest(Object... testProperties = " + testProperties + "): called");
+
+ TestClientDetails sender = getSender();
+ List<TestClientDetails> receivers = getReceivers();
+ ConversationFactory conversationFactory = getConversationFactory();
+
+ try
+ {
+ Session session = conversationFactory.getSession();
+ Destination senderControlTopic = session.createTopic(sender.privateControlKey);
+ Destination receiverControlTopic = session.createTopic(receivers.get(0).privateControlKey);
+
+ ConversationFactory.Conversation senderConversation = conversationFactory.startConversation();
+ ConversationFactory.Conversation receiverConversation = conversationFactory.startConversation();
+
+ // Assign the sender role to the sending test client.
+ Message assignSender = conversationFactory.getSession().createMessage();
+ TestUtils.setPropertiesOnMessage(assignSender, testProperties);
+ assignSender.setStringProperty("CONTROL_TYPE", "ASSIGN_ROLE");
+ assignSender.setStringProperty("ROLE", "SENDER");
+
+ senderConversation.send(senderControlTopic, assignSender);
+
+ // Assign the receivers role the receiving client.
+ Message assignReceiver = session.createMessage();
+ TestUtils.setPropertiesOnMessage(assignReceiver, testProperties);
+ assignReceiver.setStringProperty("CONTROL_TYPE", "ASSIGN_ROLE");
+ assignReceiver.setStringProperty("ROLE", "RECEIVER");
+
+ receiverConversation.send(receiverControlTopic, assignReceiver);
+
+ // Wait for the senders and receivers to confirm their roles.
+ senderConversation.receive();
+ receiverConversation.receive();
+
+ // Start the test.
+ Message start = session.createMessage();
+ start.setStringProperty("CONTROL_TYPE", "START");
+
+ senderConversation.send(senderControlTopic, start);
+
+ // Wait for the test sender to return its report.
+ Message senderReport = senderConversation.receive();
+ TestUtils.pause(500);
+
+ // Ask the receivers for its report.
+ Message statusRequest = session.createMessage();
+ statusRequest.setStringProperty("CONTROL_TYPE", "STATUS_REQUEST");
+
+ receiverConversation.send(receiverControlTopic, statusRequest);
+
+ // Wait for the receivers to send its report.
+ Message receiverReport = receiverConversation.receive();
+
+ // return new Message[] { senderReport, receiverReport };
+
+ // Apply assertions.
+ }
+ catch (JMSException e)
+ {
+ throw new RuntimeException("JMSException not handled.");
+ }
+ }
+
+ /**
+ * Creates a test circuit for the test, configered by the test parameters specified.
+ *
+ * @param testProperties The test parameters.
+ * @return A test circuit.
+ */
+ public Circuit createCircuit(ParsedProperties testProperties)
+ {
+ throw new RuntimeException("Not implemented.");
+ }
+}
diff --git a/java/systests/src/main/java/org/apache/qpid/test/framework/sequencers/TestCaseSequencer.java b/java/systests/src/main/java/org/apache/qpid/test/framework/sequencers/TestCaseSequencer.java
new file mode 100644
index 0000000000..4f09642467
--- /dev/null
+++ b/java/systests/src/main/java/org/apache/qpid/test/framework/sequencers/TestCaseSequencer.java
@@ -0,0 +1,66 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT 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.framework.sequencers;
+
+import org.apache.qpid.test.framework.Assertion;
+import org.apache.qpid.test.framework.Circuit;
+
+import uk.co.thebadgerset.junit.extensions.util.ParsedProperties;
+
+import javax.jms.JMSException;
+import javax.jms.Message;
+
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+
+/**
+ * A TestCaseSequence is responsibile for creating test circuits appropriate to the context that a test case is
+ * running in, and providing an implementation of a standard test procedure over a test circuit.
+ *
+ * <p/><table id="crc"><caption>CRC Card</caption>
+ * <tr><th> Responsibilities
+ * <tr><td> Provide a standard test procedure over a test circuit.
+ * <tr><td> Construct test circuits appropriate to a tests context.
+ * </table>
+ */
+public interface TestCaseSequencer
+{
+ /**
+ * Holds a test coordinating conversation with the test clients. This should consist of assigning the test roles,
+ * begining the test, gathering the test reports from the participants, and checking for assertion failures against
+ * the test reports.
+ *
+ * @param testCircuit The test circuit.
+ * @param assertions The list of assertions to apply to the test circuit.
+ * @param testProperties The test case definition.
+ */
+ public void sequenceTest(Circuit testCircuit, List<Assertion> assertions, Properties testProperties);
+
+ /**
+ * Creates a test circuit for the test, configered by the test parameters specified.
+ *
+ * @param testProperties The test parameters.
+ *
+ * @return A test circuit.
+ */
+ public Circuit createCircuit(ParsedProperties testProperties);
+}
diff --git a/java/integrationtests/src/main/java/org/apache/qpid/util/ClasspathScanner.java b/java/systests/src/main/java/org/apache/qpid/util/ClasspathScanner.java
index bad49060ca..bad49060ca 100644
--- a/java/integrationtests/src/main/java/org/apache/qpid/util/ClasspathScanner.java
+++ b/java/systests/src/main/java/org/apache/qpid/util/ClasspathScanner.java
diff --git a/java/integrationtests/src/main/java/org/apache/qpid/util/ConversationFactory.java b/java/systests/src/main/java/org/apache/qpid/util/ConversationFactory.java
index 0090bec3d0..0090bec3d0 100644
--- a/java/integrationtests/src/main/java/org/apache/qpid/util/ConversationFactory.java
+++ b/java/systests/src/main/java/org/apache/qpid/util/ConversationFactory.java
diff --git a/java/tasks/src/org/apache/qpid/tasks/BaseTask.java b/java/tasks/src/org/apache/qpid/tasks/BaseTask.java
deleted file mode 100644
index be604b14cf..0000000000
--- a/java/tasks/src/org/apache/qpid/tasks/BaseTask.java
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- *
- */
-package org.apache.qpid.tasks;
-
-import org.apache.tools.ant.BuildException;
-import org.apache.tools.ant.Task;
-
-import java.util.HashSet;
-import java.util.Set;
-
-/**
- * BaseTask -- an abstract base task for blaze specific tasks.
- **/
-
-public abstract class BaseTask extends Task {
-
- private static Set EMPTY = new HashSet();
- {
- EMPTY.add(0);
- EMPTY.add("");
- }
-
- public static class Validator {
-
- private String name;
- private Object value;
-
- private Validator(String name, Object value) {
- this.name = name;
- this.value = value;
- }
-
- public Validator required() {
- if (value == null) {
- error("value is required");
- }
- return this;
- }
-
- public Validator nonempty() {
- if (EMPTY.contains(value)) {
- error("value is empty");
- }
- return this;
- }
-
- private void error(String msg) {
- throw new BuildException(name + ": " + msg);
- }
- }
-
- public Validator validate(String name, Object value) {
- return new Validator(name, value);
- }
-
-}
diff --git a/java/tasks/src/org/apache/qpid/tasks/Foreach.java b/java/tasks/src/org/apache/qpid/tasks/Foreach.java
deleted file mode 100644
index 91b8a25ce2..0000000000
--- a/java/tasks/src/org/apache/qpid/tasks/Foreach.java
+++ /dev/null
@@ -1,84 +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.tasks;
-
-import org.apache.tools.ant.BuildException;
-import org.apache.tools.ant.Task;
-import org.apache.tools.ant.TaskContainer;
-
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * Foreach -- an ant task that allows iteration.
- **/
-
-public class Foreach extends BaseTask implements TaskContainer {
-
- private String property;
- private String list;
- private String delim = "\\s+";
- private String stop;
- private List<Task> tasks = new ArrayList<Task>();
-
- public void setProperty(String p) {
- property = p;
- }
-
- public void setList(String l) {
- list = l;
- }
-
- public void setDelim(String d) {
- delim = d;
- }
-
- public void setStop(String s) {
- stop = s;
- }
-
- public void addTask(Task t) {
- tasks.add(t);
- }
-
- public void execute() {
- validate("property", property).required().nonempty();
- validate("list", property).required();
-
- if (list.length() == 0) {
- return;
- }
-
- String[] values = list.split(delim);
- for (int i = 0; i < values.length; i++) {
- String value = values[i];
- if (stop != null && stop.length() > 0 &&
- value.equals(stop)) {
- break;
- }
- getProject().setProperty(property, value);
- for (Task t : tasks) {
- t.perform();
- }
- }
- }
-
-}
diff --git a/java/tasks/src/org/apache/qpid/tasks/Map.java b/java/tasks/src/org/apache/qpid/tasks/Map.java
deleted file mode 100644
index e456b9e6ab..0000000000
--- a/java/tasks/src/org/apache/qpid/tasks/Map.java
+++ /dev/null
@@ -1,94 +0,0 @@
-/*
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- *
- */
-package org.apache.qpid.tasks;
-
-import org.apache.tools.ant.BuildException;
-
-import org.apache.tools.ant.util.ChainedMapper;
-import org.apache.tools.ant.util.FileNameMapper;
-
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * Map -- an ant task that allows arbitrary use of FileNameMappers
- **/
-
-public class Map extends BaseTask {
-
- private String property;
- private String value;
- private String split = "\\s+";
- private String join = " ";
- private boolean setonempty = true;
- private ChainedMapper mapper = new ChainedMapper();
-
- public void setProperty(String p) {
- property = p;
- }
-
- public void setValue(String v) {
- value = v;
- }
-
- public void setSplit(String s) {
- split = s;
- }
-
- public void setJoin(String j) {
- join = j;
- }
-
- public void setSetonempty(boolean b) {
- setonempty = b;
- }
-
- public void add(FileNameMapper m) {
- mapper.add(m);
- }
-
- public void execute() {
- validate("property", property).required().nonempty();
- validate("value", value).required();
-
- if (mapper.getMappers().size() == 0) {
- throw new BuildException("at least one mapper must is required");
- }
-
- String[] parts = value.split(split);
- StringBuffer buf = new StringBuffer();
- for (int i = 0; i < parts.length; i++) {
- if (parts[i].length() == 0) { continue; }
- String[] names = mapper.mapFileName(parts[i]);
- for (int j = 0; j < names.length; j++) {
- if (buf.length() > 0) {
- buf.append(join);
- }
- buf.append(names[j]);
- }
- }
-
- if (buf.length() > 0 || setonempty) {
- getProject().setNewProperty(property, buf.toString());
- }
- }
-
-}
diff --git a/java/tasks/src/org/apache/qpid/tasks/Require.java b/java/tasks/src/org/apache/qpid/tasks/Require.java
deleted file mode 100644
index 84870c90e4..0000000000
--- a/java/tasks/src/org/apache/qpid/tasks/Require.java
+++ /dev/null
@@ -1,80 +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.tasks;
-
-import org.apache.tools.ant.taskdefs.Ant;
-
-import java.io.File;
-import java.util.HashSet;
-import java.util.Set;
-
-/**
- * Require
- *
- * @author Rafael H. Schloming &lt;rhs@mit.edu&gt;
- **/
-
-public class Require extends BaseTask {
-
- private File file;
- private String target = "";
- private Ant ant = null;
- private String key = "";
-
- public void setFile(File f) {
- file = f;
- }
-
- public void setTarget(String t) {
- target = t;
- }
-
- public void setKey(String k) {
- key = k;
- }
-
- public void execute() {
- validate("file", file).required();
-
- String path = file.getAbsolutePath();
- String hash = Require.class.getName() + ":" +
- path + ":" + target + ":" + key;
-
- synchronized (System.class) {
- if (System.getProperty(hash) != null) {
- return;
- }
-
- Ant ant = (Ant) getProject().createTask("ant");
- ant.setInheritAll(false);
- ant.setOwningTarget(getOwningTarget());
- ant.setTaskName(getTaskName());
- ant.init();
- if (target.length() > 0) {
- ant.setTarget(target);
- }
- ant.setAntfile(path);
- ant.setDir(file.getParentFile());
- ant.execute();
-
- System.setProperty(hash, "done");
- }
- }
-
-}