From 9c73ef7a5ac10acd6a50d5d52bd721fc2faa5919 Mon Sep 17 00:00:00 2001 From: Kim van der Riet Date: Thu, 28 Feb 2013 16:14:30 +0000 Subject: Update from trunk r1375509 through r1450773 git-svn-id: https://svn.apache.org/repos/asf/qpid/branches/asyncstore@1451244 13f79535-47bb-0310-9956-ffa450edef68 --- .../qpid/client/AMQQueueDeferredOrderingTest.java | 12 +- .../java/org/apache/qpid/client/HeartbeatTest.java | 116 +++ .../client/failover/FailoverBehaviourTest.java | 51 +- .../failover/MultipleBrokersFailoverTest.java | 285 ++++++++ .../java/org/apache/qpid/client/ssl/SSLTest.java | 291 ++++++-- .../ra/admin/QpidConnectionFactoryProxyTest.java | 120 ++++ .../org/apache/qpid/server/BrokerStartupTest.java | 8 +- .../qpid/server/SupportedProtocolVersionsTest.java | 124 +--- .../configuration/ServerConfigurationFileTest.java | 75 -- .../apache/qpid/server/failure/HeapExhaustion.java | 237 ------- .../qpid/server/logging/AbstractTestLogging.java | 39 +- .../server/logging/AccessControlLoggingTest.java | 42 +- .../apache/qpid/server/logging/AlertingTest.java | 52 +- .../qpid/server/logging/BrokerLoggingTest.java | 98 ++- .../server/logging/SubscriptionLoggingTest.java | 8 +- .../server/logging/VirtualHostLoggingTest.java | 15 +- .../persistent/NoLocalAfterRecoveryTest.java | 2 +- .../queue/MultipleTransactedBatchProducerTest.java | 5 +- .../server/security/acl/AbstractACLTestCase.java | 23 +- .../server/security/acl/ExternalACLJMXTest.java | 34 +- .../qpid/server/security/acl/ExternalACLTest.java | 44 +- .../auth/manager/ExternalAuthenticationTest.java | 184 +++++ .../MultipleAuthenticationManagersTest.java | 38 +- .../security/firewall/FirewallConfigTest.java | 283 -------- .../qpid/server/stats/StatisticsReportingTest.java | 89 ++- .../apache/qpid/server/store/SlowMessageStore.java | 31 - .../qpid/server/store/StoreOverfullTest.java | 6 +- .../org/apache/qpid/systest/GlobalQueuesTest.java | 223 ------ .../org/apache/qpid/systest/GlobalTopicsTest.java | 31 - .../qpid/systest/MergeConfigurationTest.java | 109 --- .../org/apache/qpid/systest/SubscriptionTest.java | 146 ---- .../org/apache/qpid/systest/TestingBaseCase.java | 240 ------- .../java/org/apache/qpid/systest/TopicTest.java | 85 --- .../management/jmx/BrokerManagementTest.java | 126 ++++ .../management/jmx/ConnectionManagementTest.java | 283 ++++++++ .../management/jmx/LoggingManagementTest.java | 147 ++++ .../management/jmx/ManagementActorLoggingTest.java | 480 +++++++++++++ .../management/jmx/ManagementLoggingTest.java | 330 +++++++++ .../management/jmx/QueueManagementTest.java | 778 +++++++++++++++++++++ .../systest/management/jmx/StatisticsTest.java | 210 ++++++ .../systest/management/jmx/UserManagementTest.java | 260 +++++++ .../UserManagementWithBase64MD5PasswordsTest.java | 37 + .../java/org/apache/qpid/systest/rest/Asserts.java | 270 +++++++ .../rest/AuthenticationProviderRestTest.java | 73 ++ .../qpid/systest/rest/BasicAuthRestTest.java | 121 ++++ .../apache/qpid/systest/rest/BindingRestTest.java | 130 ++++ .../qpid/systest/rest/BrokerRestHttpsTest.java | 69 ++ .../apache/qpid/systest/rest/BrokerRestTest.java | 120 ++++ .../qpid/systest/rest/ConnectionRestTest.java | 213 ++++++ .../apache/qpid/systest/rest/ExchangeRestTest.java | 87 +++ .../qpid/systest/rest/GroupProviderRestTest.java | 160 +++++ .../apache/qpid/systest/rest/GroupRestTest.java | 109 +++ .../qpid/systest/rest/LogRecordsRestTest.java | 42 ++ .../apache/qpid/systest/rest/MessagesRestTest.java | 354 ++++++++++ .../org/apache/qpid/systest/rest/PortRestTest.java | 64 ++ .../apache/qpid/systest/rest/QpidRestTestCase.java | 84 +++ .../apache/qpid/systest/rest/QueueRestTest.java | 225 ++++++ .../apache/qpid/systest/rest/RestTestHelper.java | 452 ++++++++++++ .../org/apache/qpid/systest/rest/SaslRestTest.java | 435 ++++++++++++ .../qpid/systest/rest/StructureRestTest.java | 114 +++ .../org/apache/qpid/systest/rest/UserRestTest.java | 99 +++ .../qpid/systest/rest/VirtualHostRestTest.java | 576 +++++++++++++++ .../qpid/systest/rest/acl/GroupRestACLTest.java | 197 ++++++ .../qpid/systest/rest/acl/UserRestACLTest.java | 200 ++++++ .../apache/qpid/test/client/RollbackOrderTest.java | 20 +- .../destination/AddressBasedDestinationTest.java | 200 ++++-- .../qpid/test/client/failover/FailoverTest.java | 25 +- .../test/client/message/JMSDestinationTest.java | 3 +- .../test/client/timeouts/SyncWaitDelayTest.java | 6 +- .../test/unit/basic/InvalidDestinationTest.java | 101 ++- .../client/DynamicQueueExchangeCreateTest.java | 168 ++++- .../test/unit/client/MaxDeliveryCountTest.java | 13 +- .../client/channelclose/ChannelCloseOkTest.java | 236 ------- .../unit/client/channelclose/ChannelCloseTest.java | 399 ----------- .../close/JavaServerCloseRaceConditionTest.java | 4 +- .../test/unit/topic/DurableSubscriptionTest.java | 2 +- .../transacted/TransactionTimeoutDisabledTest.java | 2 +- .../unit/transacted/TransactionTimeoutTest.java | 28 +- .../transacted/TransactionTimeoutTestCase.java | 19 +- .../qpid/test/utils/BrokerCommandHelper.java | 79 +++ .../qpid/test/utils/BrokerCommandHelperTest.java | 61 ++ .../qpid/test/utils/InternalBrokerHolder.java | 26 +- .../org/apache/qpid/test/utils/JMXTestUtils.java | 62 +- .../apache/qpid/test/utils/QpidBrokerTestCase.java | 502 ++++++------- .../test/utils/QpidClientConnectionHelper.java | 295 -------- .../qpid/test/utils/TestBrokerConfiguration.java | 219 ++++++ .../apache/qpid/test/utils/TestSSLConstants.java | 30 + .../java/org/apache/qpid/test/utils/TestUtils.java | 54 ++ .../main/java/org/apache/qpid/util/LogMonitor.java | 39 ++ 89 files changed, 9296 insertions(+), 3288 deletions(-) create mode 100644 java/systests/src/main/java/org/apache/qpid/client/HeartbeatTest.java create mode 100644 java/systests/src/main/java/org/apache/qpid/client/failover/MultipleBrokersFailoverTest.java create mode 100644 java/systests/src/main/java/org/apache/qpid/ra/admin/QpidConnectionFactoryProxyTest.java delete mode 100644 java/systests/src/main/java/org/apache/qpid/server/configuration/ServerConfigurationFileTest.java delete mode 100644 java/systests/src/main/java/org/apache/qpid/server/failure/HeapExhaustion.java create mode 100644 java/systests/src/main/java/org/apache/qpid/server/security/auth/manager/ExternalAuthenticationTest.java delete mode 100644 java/systests/src/main/java/org/apache/qpid/server/security/firewall/FirewallConfigTest.java delete mode 100644 java/systests/src/main/java/org/apache/qpid/systest/GlobalQueuesTest.java delete mode 100644 java/systests/src/main/java/org/apache/qpid/systest/GlobalTopicsTest.java delete mode 100644 java/systests/src/main/java/org/apache/qpid/systest/MergeConfigurationTest.java delete mode 100644 java/systests/src/main/java/org/apache/qpid/systest/SubscriptionTest.java delete mode 100644 java/systests/src/main/java/org/apache/qpid/systest/TestingBaseCase.java delete mode 100644 java/systests/src/main/java/org/apache/qpid/systest/TopicTest.java create mode 100644 java/systests/src/main/java/org/apache/qpid/systest/management/jmx/BrokerManagementTest.java create mode 100644 java/systests/src/main/java/org/apache/qpid/systest/management/jmx/ConnectionManagementTest.java create mode 100644 java/systests/src/main/java/org/apache/qpid/systest/management/jmx/LoggingManagementTest.java create mode 100644 java/systests/src/main/java/org/apache/qpid/systest/management/jmx/ManagementActorLoggingTest.java create mode 100644 java/systests/src/main/java/org/apache/qpid/systest/management/jmx/ManagementLoggingTest.java create mode 100644 java/systests/src/main/java/org/apache/qpid/systest/management/jmx/QueueManagementTest.java create mode 100644 java/systests/src/main/java/org/apache/qpid/systest/management/jmx/StatisticsTest.java create mode 100644 java/systests/src/main/java/org/apache/qpid/systest/management/jmx/UserManagementTest.java create mode 100644 java/systests/src/main/java/org/apache/qpid/systest/management/jmx/UserManagementWithBase64MD5PasswordsTest.java create mode 100644 java/systests/src/main/java/org/apache/qpid/systest/rest/Asserts.java create mode 100644 java/systests/src/main/java/org/apache/qpid/systest/rest/AuthenticationProviderRestTest.java create mode 100644 java/systests/src/main/java/org/apache/qpid/systest/rest/BasicAuthRestTest.java create mode 100644 java/systests/src/main/java/org/apache/qpid/systest/rest/BindingRestTest.java create mode 100644 java/systests/src/main/java/org/apache/qpid/systest/rest/BrokerRestHttpsTest.java create mode 100644 java/systests/src/main/java/org/apache/qpid/systest/rest/BrokerRestTest.java create mode 100644 java/systests/src/main/java/org/apache/qpid/systest/rest/ConnectionRestTest.java create mode 100644 java/systests/src/main/java/org/apache/qpid/systest/rest/ExchangeRestTest.java create mode 100644 java/systests/src/main/java/org/apache/qpid/systest/rest/GroupProviderRestTest.java create mode 100644 java/systests/src/main/java/org/apache/qpid/systest/rest/GroupRestTest.java create mode 100644 java/systests/src/main/java/org/apache/qpid/systest/rest/LogRecordsRestTest.java create mode 100644 java/systests/src/main/java/org/apache/qpid/systest/rest/MessagesRestTest.java create mode 100644 java/systests/src/main/java/org/apache/qpid/systest/rest/PortRestTest.java create mode 100644 java/systests/src/main/java/org/apache/qpid/systest/rest/QpidRestTestCase.java create mode 100644 java/systests/src/main/java/org/apache/qpid/systest/rest/QueueRestTest.java create mode 100644 java/systests/src/main/java/org/apache/qpid/systest/rest/RestTestHelper.java create mode 100644 java/systests/src/main/java/org/apache/qpid/systest/rest/SaslRestTest.java create mode 100644 java/systests/src/main/java/org/apache/qpid/systest/rest/StructureRestTest.java create mode 100644 java/systests/src/main/java/org/apache/qpid/systest/rest/UserRestTest.java create mode 100644 java/systests/src/main/java/org/apache/qpid/systest/rest/VirtualHostRestTest.java create mode 100644 java/systests/src/main/java/org/apache/qpid/systest/rest/acl/GroupRestACLTest.java create mode 100644 java/systests/src/main/java/org/apache/qpid/systest/rest/acl/UserRestACLTest.java delete mode 100644 java/systests/src/main/java/org/apache/qpid/test/unit/client/channelclose/ChannelCloseOkTest.java delete mode 100644 java/systests/src/main/java/org/apache/qpid/test/unit/client/channelclose/ChannelCloseTest.java create mode 100644 java/systests/src/main/java/org/apache/qpid/test/utils/BrokerCommandHelper.java create mode 100644 java/systests/src/main/java/org/apache/qpid/test/utils/BrokerCommandHelperTest.java mode change 100644 => 100755 java/systests/src/main/java/org/apache/qpid/test/utils/QpidBrokerTestCase.java delete mode 100644 java/systests/src/main/java/org/apache/qpid/test/utils/QpidClientConnectionHelper.java create mode 100644 java/systests/src/main/java/org/apache/qpid/test/utils/TestBrokerConfiguration.java create mode 100644 java/systests/src/main/java/org/apache/qpid/test/utils/TestSSLConstants.java create mode 100644 java/systests/src/main/java/org/apache/qpid/test/utils/TestUtils.java (limited to 'java/systests/src/main') diff --git a/java/systests/src/main/java/org/apache/qpid/client/AMQQueueDeferredOrderingTest.java b/java/systests/src/main/java/org/apache/qpid/client/AMQQueueDeferredOrderingTest.java index 6655202067..3025414e4a 100644 --- a/java/systests/src/main/java/org/apache/qpid/client/AMQQueueDeferredOrderingTest.java +++ b/java/systests/src/main/java/org/apache/qpid/client/AMQQueueDeferredOrderingTest.java @@ -27,7 +27,6 @@ import org.apache.qpid.framing.AMQShortString; import org.apache.qpid.test.utils.QpidBrokerTestCase; import javax.jms.Connection; -import javax.jms.JMSException; import javax.jms.Message; import javax.jms.MessageConsumer; import javax.jms.MessageProducer; @@ -72,10 +71,11 @@ public class AMQQueueDeferredOrderingTest extends QpidBrokerTestCase for (int i = start; i < end && !interrupted(); i++) { producer.send(session.createTextMessage(Integer.toString(i))); + ((AMQSession)session).sync(); } this._logger.info("Sent " + (end - start) + " messages"); } - catch (JMSException e) + catch (Exception e) { throw new RuntimeException(e); } @@ -101,7 +101,7 @@ public class AMQQueueDeferredOrderingTest extends QpidBrokerTestCase con.start(); } - public void testPausedOrder() throws Exception + public void testMessagesSentByTwoThreadsAreDeliveredInOrder() throws Exception { // Setup initial messages @@ -121,9 +121,9 @@ public class AMQQueueDeferredOrderingTest extends QpidBrokerTestCase for (int i = 0; i < numMessages; i++) { Message msg = consumer.receive(3000); - assertNotNull("Message should not be null", msg); - assertTrue("Message should be a text message", msg instanceof TextMessage); - assertEquals("Message content does not match expected", Integer.toString(i), ((TextMessage) msg).getText()); + assertNotNull("Message " + i + " should not be null", msg); + assertTrue("Message " + i + " should be a text message", msg instanceof TextMessage); + assertEquals("Message content " + i + "does not match expected", Integer.toString(i), ((TextMessage) msg).getText()); } } diff --git a/java/systests/src/main/java/org/apache/qpid/client/HeartbeatTest.java b/java/systests/src/main/java/org/apache/qpid/client/HeartbeatTest.java new file mode 100644 index 0000000000..0e01bda8d0 --- /dev/null +++ b/java/systests/src/main/java/org/apache/qpid/client/HeartbeatTest.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.client; + +import javax.jms.Destination; +import javax.jms.MessageConsumer; +import javax.jms.MessageProducer; +import javax.jms.Session; +import org.apache.qpid.test.utils.QpidBrokerTestCase; + +public class HeartbeatTest extends QpidBrokerTestCase +{ + public void testHeartbeats() throws Exception + { + setTestSystemProperty("amqj.heartbeat.delay", "1"); + AMQConnection conn = (AMQConnection) getConnection(); + TestListener listener = new TestListener(); + conn.setHeartbeatListener(listener); + conn.start(); + + Thread.sleep(2500); + + assertTrue("Too few heartbeats received: "+listener._heartbeatsReceived+" (expected at least 2)", listener._heartbeatsReceived>=2); + assertTrue("Too few heartbeats sent "+listener._heartbeatsSent+" (expected at least 2)", listener._heartbeatsSent>=2); + + conn.close(); + } + + public void testNoHeartbeats() throws Exception + { + setTestSystemProperty("amqj.heartbeat.delay", "0"); + AMQConnection conn = (AMQConnection) getConnection(); + TestListener listener = new TestListener(); + conn.setHeartbeatListener(listener); + conn.start(); + + Thread.sleep(2500); + + assertEquals("Heartbeats unexpectedly received", 0, listener._heartbeatsReceived); + assertEquals("Heartbeats unexpectedly sent ", 0, listener._heartbeatsSent); + + conn.close(); + } + + public void testReadOnlyConnectionHeartbeats() throws Exception + { + setTestSystemProperty("amqj.heartbeat.delay","1"); + AMQConnection receiveConn = (AMQConnection) getConnection(); + AMQConnection sendConn = (AMQConnection) getConnection(); + Destination destination = getTestQueue(); + TestListener receiveListener = new TestListener(); + TestListener sendListener = new TestListener(); + + + Session receiveSession = receiveConn.createSession(false, Session.CLIENT_ACKNOWLEDGE); + Session senderSession = sendConn.createSession(false, Session.CLIENT_ACKNOWLEDGE); + + MessageConsumer consumer = receiveSession.createConsumer(destination); + MessageProducer producer = senderSession.createProducer(destination); + + receiveConn.setHeartbeatListener(receiveListener); + sendConn.setHeartbeatListener(sendListener); + receiveConn.start(); + + for(int i = 0; i < 5; i++) + { + producer.send(senderSession.createTextMessage("Msg " + i)); + Thread.sleep(500); + assertNotNull("Expected to received message", consumer.receive(500)); + } + + + + assertTrue("Too few heartbeats sent "+receiveListener._heartbeatsSent+" (expected at least 2)", receiveListener._heartbeatsSent>=2); + assertEquals("Unexpected sent at the sender: ",0,sendListener._heartbeatsSent); + + assertTrue("Too few heartbeats received at the sender "+sendListener._heartbeatsReceived+" (expected at least 2)", sendListener._heartbeatsReceived>=2); + assertEquals("Unexpected received at the receiver: ",0,receiveListener._heartbeatsReceived); + + receiveConn.close(); + sendConn.close(); + } + + private class TestListener implements HeartbeatListener + { + int _heartbeatsReceived; + int _heartbeatsSent; + @Override + public void heartbeatReceived() + { + _heartbeatsReceived++; + } + + @Override + public void heartbeatSent() + { + _heartbeatsSent++; + } + } +} diff --git a/java/systests/src/main/java/org/apache/qpid/client/failover/FailoverBehaviourTest.java b/java/systests/src/main/java/org/apache/qpid/client/failover/FailoverBehaviourTest.java index 4b766864b4..4f8a6ee54a 100644 --- a/java/systests/src/main/java/org/apache/qpid/client/failover/FailoverBehaviourTest.java +++ b/java/systests/src/main/java/org/apache/qpid/client/failover/FailoverBehaviourTest.java @@ -25,11 +25,12 @@ import org.apache.qpid.client.AMQSession; import org.apache.qpid.framing.AMQShortString; import org.apache.qpid.jms.BrokerDetails; import org.apache.qpid.jms.ConnectionListener; -import org.apache.qpid.jms.ConnectionURL; import org.apache.qpid.jms.FailoverPolicy; import org.apache.qpid.test.utils.FailoverBaseCase; +import org.apache.qpid.url.URLSyntaxException; import javax.jms.Connection; +import javax.jms.ConnectionFactory; import javax.jms.Destination; import javax.jms.ExceptionListener; import javax.jms.JMSException; @@ -929,18 +930,22 @@ public class FailoverBehaviourTest extends FailoverBaseCase implements Connectio return queue; } - private AMQConnection createConnectionWithFailover() throws NamingException, JMSException + private AMQConnection createConnectionWithFailover() throws NamingException, JMSException, URLSyntaxException { - AMQConnection connection; - AMQConnectionFactory connectionFactory = (AMQConnectionFactory)getConnectionFactory("default"); - ConnectionURL connectionURL = connectionFactory.getConnectionURL(); - connectionURL.setOption(ConnectionURL.OPTIONS_FAILOVER, "singlebroker"); - connectionURL.setOption(ConnectionURL.OPTIONS_FAILOVER_CYCLE, "2"); - BrokerDetails details = connectionURL.getBrokerDetails(0); - details.setProperty(BrokerDetails.OPTIONS_RETRY, "200"); - details.setProperty(BrokerDetails.OPTIONS_CONNECT_DELAY, "1000"); + BrokerDetails origBrokerDetails = ((AMQConnectionFactory) getConnectionFactory("default")).getConnectionURL().getBrokerDetails(0); - connection = (AMQConnection)connectionFactory.createConnection("admin", "admin"); + String retries = "200"; + String connectdelay = "1000"; + String cycleCount = "2"; + + String newUrlFormat="amqp://username:password@clientid/test?brokerlist=" + + "'tcp://%s:%s?retries='%s'&connectdelay='%s''&failover='singlebroker?cyclecount='%s''"; + + String newUrl = String.format(newUrlFormat, origBrokerDetails.getHost(), origBrokerDetails.getPort(), + retries, connectdelay, cycleCount); + + ConnectionFactory connectionFactory = new AMQConnectionFactory(newUrl); + AMQConnection connection = (AMQConnection) connectionFactory.createConnection("admin", "admin"); connection.setConnectionListener(this); return connection; } @@ -1313,7 +1318,7 @@ public class FailoverBehaviourTest extends FailoverBaseCase implements Connectio * @param acknowledgeMode session acknowledge mode * @throws JMSException */ - private void sessionCloseWhileFailoverImpl(int acknowledgeMode) throws JMSException + private void sessionCloseWhileFailoverImpl(int acknowledgeMode) throws Exception { initDelayedFailover(acknowledgeMode); @@ -1324,9 +1329,14 @@ public class FailoverBehaviourTest extends FailoverBaseCase implements Connectio failBroker(getFailingPort()); + // wait until failover is started + _failoverStarted.await(5, TimeUnit.SECONDS); + // test whether session#close blocks while failover is in progress _consumerSession.close(); + assertTrue("Failover has not completed yet but session was closed", _failoverComplete.await(5, TimeUnit.SECONDS)); + assertFailoverException(); } @@ -1360,10 +1370,8 @@ public class FailoverBehaviourTest extends FailoverBaseCase implements Connectio * @param acknowledgeMode session acknowledge mode * @throws JMSException */ - private void browserCloseWhileFailoverImpl(int acknowledgeMode) throws JMSException + private void browserCloseWhileFailoverImpl(int acknowledgeMode) throws Exception { - setDelayedFailoverPolicy(); - QueueBrowser browser = prepareQueueBrowser(acknowledgeMode); @SuppressWarnings("unchecked") @@ -1373,8 +1381,13 @@ public class FailoverBehaviourTest extends FailoverBaseCase implements Connectio failBroker(getFailingPort()); + // wait until failover is started + _failoverStarted.await(5, TimeUnit.SECONDS); + browser.close(); + assertTrue("Failover has not completed yet but browser was closed", _failoverComplete.await(5, TimeUnit.SECONDS)); + assertFailoverException(); } @@ -1402,5 +1415,11 @@ public class FailoverBehaviourTest extends FailoverBaseCase implements Connectio ((AMQConnection) _connection).setFailoverPolicy(failoverPolicy); return failoverPolicy; } - + + @Override + public void failBroker(int port) + { + killBroker(port); + } + } diff --git a/java/systests/src/main/java/org/apache/qpid/client/failover/MultipleBrokersFailoverTest.java b/java/systests/src/main/java/org/apache/qpid/client/failover/MultipleBrokersFailoverTest.java new file mode 100644 index 0000000000..a0fd093bfe --- /dev/null +++ b/java/systests/src/main/java/org/apache/qpid/client/failover/MultipleBrokersFailoverTest.java @@ -0,0 +1,285 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT 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.failover; + +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.TimeUnit; + +import javax.jms.Connection; +import javax.jms.Destination; +import javax.jms.JMSException; +import javax.jms.Message; +import javax.jms.MessageConsumer; +import javax.jms.MessageProducer; +import javax.jms.Session; +import javax.jms.TextMessage; + +import org.apache.log4j.Logger; +import org.apache.qpid.client.AMQConnection; +import org.apache.qpid.client.AMQConnectionURL; +import org.apache.qpid.jms.ConnectionListener; +import org.apache.qpid.test.utils.QpidBrokerTestCase; +import org.apache.qpid.test.utils.TestUtils; +import org.apache.qpid.util.FileUtils; + +public class MultipleBrokersFailoverTest extends QpidBrokerTestCase implements ConnectionListener +{ + private static final Logger _logger = Logger.getLogger(MultipleBrokersFailoverTest.class); + + private static final String FAILOVER_VIRTUAL_HOST = "failover"; + private static final String NON_FAILOVER_VIRTUAL_HOST = "nonfailover"; + private static final String BROKER_PORTION_FORMAT = "tcp://localhost:%d?connectdelay='%d',retries='%d'"; + private static final int FAILOVER_RETRIES = 1; + private static final int FAILOVER_CONNECTDELAY = 1000; + private int[] _brokerPorts; + private AMQConnectionURL _connectionURL; + private Connection _connection; + private CountDownLatch _failoverComplete; + private CountDownLatch _failoverStarted; + private Session _consumerSession; + private Destination _destination; + private MessageConsumer _consumer; + private Session _producerSession; + private MessageProducer _producer; + + @Override + protected void setUp() throws Exception + { + super.setUp(); + + int numBrokers = 4; + int port = findFreePort(); + _brokerPorts = new int[numBrokers]; + + // we need to create 4 brokers: + // 1st broker will be running in test JVM and will not have failover host (only tcp connection will established, amqp connection will be closed) + // 2d broker will be spawn in separate JVM and should have a failover host (amqp connection should be established) + // 3d broker will be spawn in separate JVM and should not have a failover host (only tcp connection will established, amqp connection will be closed) + // 4d broker will be spawn in separate JVM and should have a failover host (amqp connection should be established) + + // the test should connect to the second broker first and fail over to the forth broker + // after unsuccessful try to establish the connection to the 3d broker + for (int i = 0; i < numBrokers; i++) + { + if (i > 0) + { + port = getNextAvailable(port + 1); + } + _brokerPorts[i] = port; + + createBrokerConfiguration(port); + String host = null; + if (i == 1 || i == _brokerPorts.length - 1) + { + host = FAILOVER_VIRTUAL_HOST; + } + else + { + host = NON_FAILOVER_VIRTUAL_HOST; + } + createTestVirtualHost(port, host); + + startBroker(port); + revertSystemProperties(); + } + + _connectionURL = new AMQConnectionURL(generateUrlString(numBrokers)); + + _connection = getConnection(_connectionURL); + ((AMQConnection) _connection).setConnectionListener(this); + _failoverComplete = new CountDownLatch(1); + _failoverStarted = new CountDownLatch(1); + } + + public void startBroker() throws Exception + { + // noop, prevent the broker startup in super.setUp() + } + + private String generateUrlString(int numBrokers) + { + String baseString = "amqp://guest:guest@test/" + FAILOVER_VIRTUAL_HOST + + "?&failover='roundrobin?cyclecount='1''&brokerlist='"; + StringBuffer buffer = new StringBuffer(baseString); + + for(int i = 0; i< numBrokers ; i++) + { + if(i != 0) + { + buffer.append(";"); + } + + String broker = String.format(BROKER_PORTION_FORMAT, _brokerPorts[i], + FAILOVER_CONNECTDELAY, FAILOVER_RETRIES); + buffer.append(broker); + } + buffer.append("'"); + + return buffer.toString(); + } + + public void tearDown() throws Exception + { + try + { + super.tearDown(); + } + finally + { + for (int i = 0; i < _brokerPorts.length; i++) + { + if (_brokerPorts[i] > 0) + { + stopBrokerSafely(_brokerPorts[i]); + FileUtils.deleteDirectory(System.getProperty("QPID_WORK") + "/" + getFailingPort()); + } + } + + } + } + + + public void testFailoverOnBrokerKill() throws Exception + { + init(Session.SESSION_TRANSACTED, true); + assertConnectionPort(_brokerPorts[1]); + + assertSendReceive(0); + + killBroker(_brokerPorts[1]); + + awaitForFailoverCompletion(FAILOVER_CONNECTDELAY * _brokerPorts.length * 2); + assertEquals("Failover is not started as expected", 0, _failoverStarted.getCount()); + + assertSendReceive(2); + assertConnectionPort(_brokerPorts[_brokerPorts.length - 1]); + } + + public void testFailoverOnBrokerStop() throws Exception + { + init(Session.SESSION_TRANSACTED, true); + assertConnectionPort(_brokerPorts[1]); + + assertSendReceive(0); + + stopBroker(_brokerPorts[1]); + + awaitForFailoverCompletion(FAILOVER_CONNECTDELAY * _brokerPorts.length * 2); + assertEquals("Failover is not started as expected", 0, _failoverStarted.getCount()); + + assertSendReceive(1); + assertConnectionPort(_brokerPorts[_brokerPorts.length - 1]); + } + + private void assertConnectionPort(int brokerPort) + { + int connectionPort = ((AMQConnection)_connection).getActiveBrokerDetails().getPort(); + assertEquals("Unexpected broker port", brokerPort, connectionPort); + } + + private void assertSendReceive(int index) throws JMSException + { + Message message = createNextMessage(_producerSession, index); + _producer.send(message); + if (_producerSession.getTransacted()) + { + _producerSession.commit(); + } + Message receivedMessage = _consumer.receive(1000l); + assertReceivedMessage(receivedMessage, index); + if (_consumerSession.getTransacted()) + { + _consumerSession.commit(); + } + } + + private void awaitForFailoverCompletion(long delay) + { + _logger.info("Awaiting Failover completion.."); + try + { + if (!_failoverComplete.await(delay, TimeUnit.MILLISECONDS)) + { + _logger.warn("Test thread stack:\n\n" + TestUtils.dumpThreads()); + fail("Failover did not complete"); + } + } + catch (InterruptedException e) + { + fail("Test was interrupted:" + e.getMessage()); + } + } + + private void assertReceivedMessage(Message receivedMessage, int messageIndex) + { + assertNotNull("Expected message [" + messageIndex + "] is not received!", receivedMessage); + assertTrue( + "Failure to receive message [" + messageIndex + "], expected TextMessage but received " + receivedMessage, + receivedMessage instanceof TextMessage); + } + + private void init(int acknowledgeMode, boolean startConnection) throws JMSException + { + boolean isTransacted = acknowledgeMode == Session.SESSION_TRANSACTED ? true : false; + + _consumerSession = _connection.createSession(isTransacted, acknowledgeMode); + _destination = _consumerSession.createQueue(getTestQueueName()); + _consumer = _consumerSession.createConsumer(_destination); + + if (startConnection) + { + _connection.start(); + } + + _producerSession = _connection.createSession(isTransacted, acknowledgeMode); + _producer = _producerSession.createProducer(_destination); + + } + + @Override + public void bytesSent(long count) + { + } + + @Override + public void bytesReceived(long count) + { + } + + @Override + public boolean preFailover(boolean redirect) + { + _failoverStarted.countDown(); + return true; + } + + @Override + public boolean preResubscribe() + { + return true; + } + + @Override + public void failoverComplete() + { + _failoverComplete.countDown(); + } +} diff --git a/java/systests/src/main/java/org/apache/qpid/client/ssl/SSLTest.java b/java/systests/src/main/java/org/apache/qpid/client/ssl/SSLTest.java index 39689f5096..884e89fb65 100644 --- a/java/systests/src/main/java/org/apache/qpid/client/ssl/SSLTest.java +++ b/java/systests/src/main/java/org/apache/qpid/client/ssl/SSLTest.java @@ -20,54 +20,55 @@ */ package org.apache.qpid.client.ssl; -import org.apache.qpid.client.AMQConnection; +import static org.apache.qpid.test.utils.TestSSLConstants.KEYSTORE; +import static org.apache.qpid.test.utils.TestSSLConstants.KEYSTORE_PASSWORD; +import static org.apache.qpid.test.utils.TestSSLConstants.TRUSTSTORE; +import static org.apache.qpid.test.utils.TestSSLConstants.TRUSTSTORE_PASSWORD; + +import org.apache.commons.configuration.ConfigurationException; +import org.apache.qpid.client.AMQConnectionURL; import org.apache.qpid.client.AMQTestConnection_0_10; +import org.apache.qpid.jms.ConnectionURL; +import org.apache.qpid.server.model.Port; +import org.apache.qpid.server.model.Transport; import org.apache.qpid.test.utils.QpidBrokerTestCase; -import org.apache.qpid.transport.Connection; +import org.apache.qpid.test.utils.TestBrokerConfiguration; +import javax.jms.Connection; +import javax.jms.JMSException; import javax.jms.Session; import java.io.ByteArrayOutputStream; import java.io.PrintStream; +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; public class SSLTest extends QpidBrokerTestCase { - private static final String KEYSTORE = "test-profiles/test_resources/ssl/java_client_keystore.jks"; - private static final String KEYSTORE_PASSWORD = "password"; - private static final String TRUSTSTORE = "test-profiles/test_resources/ssl/java_client_truststore.jks"; - private static final String TRUSTSTORE_PASSWORD = "password"; private static final String CERT_ALIAS_APP1 = "app1"; private static final String CERT_ALIAS_APP2 = "app2"; @Override protected void setUp() throws Exception { - if(isJavaBroker()) - { - setTestClientSystemProperty("profile.use_ssl", "true"); - setConfigurationProperty("connector.ssl.enabled", "true"); - setConfigurationProperty("connector.ssl.sslOnly", "true"); - setConfigurationProperty("connector.ssl.wantClientAuth", "true"); - } - - // set the ssl system properties - setSystemProperty("javax.net.ssl.keyStore", KEYSTORE); - setSystemProperty("javax.net.ssl.keyStorePassword", KEYSTORE_PASSWORD); - setSystemProperty("javax.net.ssl.trustStore", TRUSTSTORE); - setSystemProperty("javax.net.ssl.trustStorePassword", TRUSTSTORE_PASSWORD); setSystemProperty("javax.net.debug", "ssl"); - super.setUp(); + + setSslStoreSystemProperties(); + + //We dont call super.setUp, the tests start the broker after deciding + //whether to run and then configuring it appropriately } public void testCreateSSLConnectionUsingConnectionURLParams() throws Exception { - if (Boolean.getBoolean("profile.use_ssl")) + if (shouldPerformTest()) { - // Clear the ssl system properties - setSystemProperty("javax.net.ssl.keyStore", null); - setSystemProperty("javax.net.ssl.keyStorePassword", null); - setSystemProperty("javax.net.ssl.trustStore", null); - setSystemProperty("javax.net.ssl.trustStorePassword", null); + clearSslStoreSystemProperties(); + //Start the broker (NEEDing client certificate authentication) + configureJavaBrokerIfNecessary(true, true, true, false); + super.setUp(); + String url = "amqp://guest:guest@test/?brokerlist='tcp://localhost:%s" + "?ssl='true'&ssl_verify_hostname='true'" + "&key_store='%s'&key_store_password='%s'" + @@ -76,24 +77,75 @@ public class SSLTest extends QpidBrokerTestCase url = String.format(url,QpidBrokerTestCase.DEFAULT_SSL_PORT, KEYSTORE,KEYSTORE_PASSWORD,TRUSTSTORE,TRUSTSTORE_PASSWORD); - - AMQConnection con = new AMQConnection(url); + + Connection con = getConnection(new AMQConnectionURL(url)); assertNotNull("connection should be successful", con); Session ssn = con.createSession(false,Session.AUTO_ACKNOWLEDGE); assertNotNull("create session should be successful", ssn); - } + } + } + + /** + * Create an SSL connection using the SSL system properties for the trust and key store, but using + * the {@link ConnectionURL} ssl='true' option to indicate use of SSL at a Connection level, + * without specifying anything at the {@link ConnectionURL#OPTIONS_BROKERLIST} level. + */ + public void testSslConnectionOption() throws Exception + { + if (shouldPerformTest()) + { + //Start the broker (NEEDing client certificate authentication) + configureJavaBrokerIfNecessary(true, true, true, false); + super.setUp(); + + //Create URL enabling SSL at the connection rather than brokerlist level + String url = "amqp://guest:guest@test/?ssl='true'&brokerlist='tcp://localhost:%s'"; + url = String.format(url,QpidBrokerTestCase.DEFAULT_SSL_PORT); + + Connection con = getConnection(new AMQConnectionURL(url)); + assertNotNull("connection should be successful", con); + Session ssn = con.createSession(false,Session.AUTO_ACKNOWLEDGE); + assertNotNull("create session should be successful", ssn); + } + } + + /** + * Create an SSL connection using the SSL system properties for the trust and key store, but using + * the {@link ConnectionURL} ssl='true' option to indicate use of SSL at a Connection level, + * overriding the false setting at the {@link ConnectionURL#OPTIONS_BROKERLIST} level. + */ + public void testSslConnectionOptionOverridesBrokerlistOption() throws Exception + { + if (shouldPerformTest()) + { + //Start the broker (NEEDing client certificate authentication) + configureJavaBrokerIfNecessary(true, true, true, false); + super.setUp(); + + //Create URL enabling SSL at the connection, overriding the false at the brokerlist level + String url = "amqp://guest:guest@test/?ssl='true'&brokerlist='tcp://localhost:%s?ssl='false''"; + url = String.format(url,QpidBrokerTestCase.DEFAULT_SSL_PORT); + + Connection con = getConnection(new AMQConnectionURL(url)); + assertNotNull("connection should be successful", con); + Session ssn = con.createSession(false,Session.AUTO_ACKNOWLEDGE); + assertNotNull("create session should be successful", ssn); + } } public void testCreateSSLConnectionUsingSystemProperties() throws Exception { - if (Boolean.getBoolean("profile.use_ssl")) + if (shouldPerformTest()) { + //Start the broker (NEEDing client certificate authentication) + configureJavaBrokerIfNecessary(true, true, true, false); + super.setUp(); String url = "amqp://guest:guest@test/?brokerlist='tcp://localhost:%s?ssl='true''"; url = String.format(url,QpidBrokerTestCase.DEFAULT_SSL_PORT); - AMQConnection con = new AMQConnection(url); + Connection con = getConnection(new AMQConnectionURL(url)); assertNotNull("connection should be successful", con); Session ssn = con.createSession(false,Session.AUTO_ACKNOWLEDGE); assertNotNull("create session should be successful", ssn); @@ -102,14 +154,18 @@ public class SSLTest extends QpidBrokerTestCase public void testMultipleCertsInSingleStore() throws Exception { - if (Boolean.getBoolean("profile.use_ssl")) + if (shouldPerformTest()) { + //Start the broker (NEEDing client certificate authentication) + configureJavaBrokerIfNecessary(true, true, true, false); + super.setUp(); + String url = "amqp://guest:guest@test/?brokerlist='tcp://localhost:" + QpidBrokerTestCase.DEFAULT_SSL_PORT + "?ssl='true'&ssl_cert_alias='" + CERT_ALIAS_APP1 + "''"; AMQTestConnection_0_10 con = new AMQTestConnection_0_10(url); - Connection transportCon = con.getConnection(); + org.apache.qpid.transport.Connection transportCon = con.getConnection(); String userID = transportCon.getSecurityLayer().getUserID(); assertEquals("The correct certificate was not choosen","app1@acme.org",userID); con.close(); @@ -126,65 +182,82 @@ public class SSLTest extends QpidBrokerTestCase } } - public void testVerifyHostNameWithIncorrectHostname() + public void testVerifyHostNameWithIncorrectHostname() throws Exception { - if (Boolean.getBoolean("profile.use_ssl")) + if (shouldPerformTest()) { + //Start the broker (WANTing client certificate authentication) + configureJavaBrokerIfNecessary(true, true, false, true); + super.setUp(); + String url = "amqp://guest:guest@test/?brokerlist='tcp://127.0.0.1:" + QpidBrokerTestCase.DEFAULT_SSL_PORT + "?ssl='true'&ssl_verify_hostname='true''"; try { - AMQConnection con = new AMQConnection(url); + getConnection(new AMQConnectionURL(url)); fail("Hostname verification failed. No exception was thrown"); } catch (Exception e) { - ByteArrayOutputStream bout = new ByteArrayOutputStream(); - e.printStackTrace(new PrintStream(bout)); - String strace = bout.toString(); - assertTrue("Correct exception not thrown",strace.contains("SSL hostname verification failed")); + verifyExceptionCausesContains(e, "SSL hostname verification failed"); } - } } + + private void verifyExceptionCausesContains(Exception e, String expectedString) + { + ByteArrayOutputStream bout = new ByteArrayOutputStream(); + e.printStackTrace(new PrintStream(bout)); + String strace = bout.toString(); + assertTrue("Correct exception not thrown", strace.contains(expectedString)); + } public void testVerifyLocalHost() throws Exception { - if (Boolean.getBoolean("profile.use_ssl")) + if (shouldPerformTest()) { + //Start the broker (WANTing client certificate authentication) + configureJavaBrokerIfNecessary(true, true, false, true); + super.setUp(); + String url = "amqp://guest:guest@test/?brokerlist='tcp://localhost:" + QpidBrokerTestCase.DEFAULT_SSL_PORT + "?ssl='true'&ssl_verify_hostname='true''"; - AMQConnection con = new AMQConnection(url); - assertNotNull("connection should have been created", con); + Connection con = getConnection(new AMQConnectionURL(url)); + assertNotNull("connection should have been created", con); } } public void testVerifyLocalHostLocalDomain() throws Exception { - if (Boolean.getBoolean("profile.use_ssl")) + if (shouldPerformTest()) { + //Start the broker (WANTing client certificate authentication) + configureJavaBrokerIfNecessary(true, true, false, true); + super.setUp(); + String url = "amqp://guest:guest@test/?brokerlist='tcp://localhost.localdomain:" + QpidBrokerTestCase.DEFAULT_SSL_PORT + "?ssl='true'&ssl_verify_hostname='true''"; - AMQConnection con = new AMQConnection(url); + Connection con = getConnection(new AMQConnectionURL(url)); assertNotNull("connection should have been created", con); } } public void testCreateSSLConnectionUsingConnectionURLParamsTrustStoreOnly() throws Exception { - if (Boolean.getBoolean("profile.use_ssl")) + if (shouldPerformTest()) { - // Clear the ssl system properties - setSystemProperty("javax.net.ssl.keyStore", null); - setSystemProperty("javax.net.ssl.keyStorePassword", null); - setSystemProperty("javax.net.ssl.trustStore", null); - setSystemProperty("javax.net.ssl.trustStorePassword", null); + clearSslStoreSystemProperties(); + + //Start the broker (WANTing client certificate authentication) + configureJavaBrokerIfNecessary(true, true, false, true); + super.setUp(); + String url = "amqp://guest:guest@test/?brokerlist='tcp://localhost:%s" + "?ssl='true'&ssl_verify_hostname='true'" + @@ -193,10 +266,122 @@ public class SSLTest extends QpidBrokerTestCase url = String.format(url,QpidBrokerTestCase.DEFAULT_SSL_PORT, TRUSTSTORE,TRUSTSTORE_PASSWORD); - AMQConnection con = new AMQConnection(url); + Connection con = getConnection(new AMQConnectionURL(url)); assertNotNull("connection should be successful", con); Session ssn = con.createSession(false,Session.AUTO_ACKNOWLEDGE); assertNotNull("create session should be successful", ssn); } } + + /** + * Verifies that when the broker is configured to NEED client certificates, + * a client which doesn't supply one fails to connect. + */ + public void testClientCertMissingWhilstNeeding() throws Exception + { + missingClientCertWhileNeedingOrWantingTestImpl(true, false, false); + } + + /** + * Verifies that when the broker is configured to WANT client certificates, + * a client which doesn't supply one succeeds in connecting. + */ + public void testClientCertMissingWhilstWanting() throws Exception + { + missingClientCertWhileNeedingOrWantingTestImpl(false, true, true); + } + + /** + * Verifies that when the broker is configured to WANT and NEED client certificates + * that a client which doesn't supply one fails to connect. + */ + public void testClientCertMissingWhilstWantingAndNeeding() throws Exception + { + missingClientCertWhileNeedingOrWantingTestImpl(true, true, false); + } + + private void missingClientCertWhileNeedingOrWantingTestImpl(boolean needClientCerts, + boolean wantClientCerts, boolean shouldSucceed) throws Exception + { + if (shouldPerformTest()) + { + clearSslStoreSystemProperties(); + + //Start the broker + configureJavaBrokerIfNecessary(true, true, needClientCerts, wantClientCerts); + super.setUp(); + + String url = "amqp://guest:guest@test/?brokerlist='tcp://localhost:%s" + + "?ssl='true'&trust_store='%s'&trust_store_password='%s''"; + + url = String.format(url,QpidBrokerTestCase.DEFAULT_SSL_PORT,TRUSTSTORE,TRUSTSTORE_PASSWORD); + try + { + Connection con = getConnection(new AMQConnectionURL(url)); + if(!shouldSucceed) + { + fail("Connection succeeded, expected exception was not thrown"); + } + else + { + //Use the connection to verify it works + con.createSession(true, Session.SESSION_TRANSACTED); + } + } + catch(JMSException e) + { + if(shouldSucceed) + { + _logger.error("Caught unexpected exception",e); + fail("Connection failed, unexpected exception thrown"); + } + else + { + //expected + verifyExceptionCausesContains(e, "Caused by: javax.net.ssl.SSLException:"); + } + } + } + } + + private boolean shouldPerformTest() + { + // We run the SSL tests on all the Java broker profiles + if(isJavaBroker()) + { + setTestClientSystemProperty(PROFILE_USE_SSL, "true"); + } + + return Boolean.getBoolean(PROFILE_USE_SSL); + } + + private void configureJavaBrokerIfNecessary(boolean sslEnabled, boolean sslOnly, boolean needClientAuth, boolean wantClientAuth) throws ConfigurationException + { + if(isJavaBroker()) + { + Map sslPortAttributes = new HashMap(); + sslPortAttributes.put(Port.TRANSPORTS, Collections.singleton(Transport.SSL)); + sslPortAttributes.put(Port.PORT, DEFAULT_SSL_PORT); + sslPortAttributes.put(Port.NEED_CLIENT_AUTH, needClientAuth); + sslPortAttributes.put(Port.WANT_CLIENT_AUTH, wantClientAuth); + sslPortAttributes.put(Port.NAME, TestBrokerConfiguration.ENTRY_NAME_SSL_PORT); + getBrokerConfiguration().addPortConfiguration(sslPortAttributes); + } + } + + private void setSslStoreSystemProperties() + { + setSystemProperty("javax.net.ssl.keyStore", KEYSTORE); + setSystemProperty("javax.net.ssl.keyStorePassword", KEYSTORE_PASSWORD); + setSystemProperty("javax.net.ssl.trustStore", TRUSTSTORE); + setSystemProperty("javax.net.ssl.trustStorePassword", TRUSTSTORE_PASSWORD); + } + + private void clearSslStoreSystemProperties() + { + setSystemProperty("javax.net.ssl.keyStore", null); + setSystemProperty("javax.net.ssl.keyStorePassword", null); + setSystemProperty("javax.net.ssl.trustStore", null); + setSystemProperty("javax.net.ssl.trustStorePassword", null); + } } diff --git a/java/systests/src/main/java/org/apache/qpid/ra/admin/QpidConnectionFactoryProxyTest.java b/java/systests/src/main/java/org/apache/qpid/ra/admin/QpidConnectionFactoryProxyTest.java new file mode 100644 index 0000000000..80001099a8 --- /dev/null +++ b/java/systests/src/main/java/org/apache/qpid/ra/admin/QpidConnectionFactoryProxyTest.java @@ -0,0 +1,120 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT 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.ra.admin; + +import javax.jms.Connection; +import javax.jms.ConnectionFactory; +import javax.jms.JMSException; +import javax.naming.NamingException; +import javax.jms.QueueConnection; +import javax.jms.QueueConnectionFactory; +import javax.naming.Reference; +import javax.naming.Referenceable; +import javax.naming.spi.ObjectFactory; +import javax.jms.TopicConnection; +import javax.jms.TopicConnectionFactory; + +import junit.framework.TestCase; + +import org.apache.qpid.test.utils.QpidBrokerTestCase; + +public class QpidConnectionFactoryProxyTest extends QpidBrokerTestCase +{ + private static final String BROKER_PORT = "15672"; + + private static final String URL = "amqp://guest:guest@client/test?brokerlist='tcp://localhost:" + BROKER_PORT + "?sasl_mechs='PLAIN''"; + + public void testQueueConnectionFactory() throws Exception + { + QueueConnectionFactory cf = null; + QueueConnection c = null; + + try + { + cf = new QpidConnectionFactoryProxy(); + ((QpidConnectionFactoryProxy)cf).setConnectionURL(URL); + c = cf.createQueueConnection(); + assertTrue(c instanceof QueueConnection); + + } + finally + { + if(c != null) + { + c.close(); + } + } + } + + public void testTopicConnectionFactory() throws Exception + { + TopicConnectionFactory cf = null; + TopicConnection c = null; + + try + { + cf = new QpidConnectionFactoryProxy(); + ((QpidConnectionFactoryProxy)cf).setConnectionURL(URL); + c = cf.createTopicConnection(); + assertTrue(c instanceof TopicConnection); + + } + finally + { + if(c != null) + { + c.close(); + } + } + try + { + + } + finally + { + + } + } + + public void testConnectionFactory() throws Exception + { + ConnectionFactory cf = null; + Connection c = null; + + try + { + cf = new QpidConnectionFactoryProxy(); + ((QpidConnectionFactoryProxy)cf).setConnectionURL(URL); + c = cf.createConnection(); + assertTrue(c instanceof Connection); + + } + finally + { + if(c != null) + { + c.close(); + } + + } + } +} + diff --git a/java/systests/src/main/java/org/apache/qpid/server/BrokerStartupTest.java b/java/systests/src/main/java/org/apache/qpid/server/BrokerStartupTest.java index 9f3994fc91..eba2a638c0 100644 --- a/java/systests/src/main/java/org/apache/qpid/server/BrokerStartupTest.java +++ b/java/systests/src/main/java/org/apache/qpid/server/BrokerStartupTest.java @@ -30,6 +30,7 @@ import org.apache.qpid.util.LogMonitor; import javax.jms.Connection; import javax.jms.Queue; import javax.jms.Session; +import java.io.File; import java.util.List; /** @@ -72,10 +73,7 @@ public class BrokerStartupTest extends AbstractTestLogging if (isJavaBroker() && isExternalBroker() && !isInternalBroker()) { //Remove test Log4j config from the commandline - _brokerCommand = _brokerCommand.substring(0, _brokerCommand.indexOf("-l")); - - // Add an invalid value - _brokerCommand += " -l invalid"; + setBrokerCommandLog4JFile(new File("invalid file")); // The broker has a built in default log4j configuration set up // so if the the broker cannot load the -l value it will use default @@ -145,4 +143,4 @@ public class BrokerStartupTest extends AbstractTestLogging } } -} \ No newline at end of file +} diff --git a/java/systests/src/main/java/org/apache/qpid/server/SupportedProtocolVersionsTest.java b/java/systests/src/main/java/org/apache/qpid/server/SupportedProtocolVersionsTest.java index e8d72c13bd..23a00431d1 100644 --- a/java/systests/src/main/java/org/apache/qpid/server/SupportedProtocolVersionsTest.java +++ b/java/systests/src/main/java/org/apache/qpid/server/SupportedProtocolVersionsTest.java @@ -23,13 +23,17 @@ package org.apache.qpid.server; import org.apache.qpid.client.AMQConnection; import org.apache.qpid.configuration.ClientProperties; import org.apache.qpid.framing.ProtocolVersion; -import org.apache.qpid.server.configuration.ServerConfiguration; +import org.apache.qpid.server.configuration.BrokerProperties; +import org.apache.qpid.server.model.Protocol; +import org.apache.qpid.server.model.adapter.PortFactoryTest; import org.apache.qpid.test.utils.QpidBrokerTestCase; /** * Tests to validate it is possible to disable support for particular protocol * versions entirely, rather than selectively excluding them on particular ports, * and it is possible to configure the reply to an unsupported protocol initiation. + *

+ * Protocol exclusion/inclusion are unit tested as part of {@link PortFactoryTest} */ public class SupportedProtocolVersionsTest extends QpidBrokerTestCase { @@ -41,8 +45,8 @@ public class SupportedProtocolVersionsTest extends QpidBrokerTestCase private void clearProtocolSupportManipulations() { //Remove the QBTC provided protocol manipulations, giving only the protocols which default to enabled - setTestSystemProperty(QpidBrokerTestCase.BROKER_PROTOCOL_EXCLUDES, null); - setTestSystemProperty(QpidBrokerTestCase.BROKER_PROTOCOL_INCLUDES, null); + setSystemProperty(BrokerProperties.PROPERTY_BROKER_DEFAULT_AMQP_PROTOCOL_EXCLUDES, null); + setSystemProperty(BrokerProperties.PROPERTY_BROKER_DEFAULT_AMQP_PROTOCOL_INCLUDES, null); } /** @@ -87,8 +91,8 @@ public class SupportedProtocolVersionsTest extends QpidBrokerTestCase clearProtocolSupportManipulations(); //disable 0-10 and 1-0 support - setConfigurationProperty(ServerConfiguration.CONNECTOR_AMQP010ENABLED, "false"); - setConfigurationProperty(ServerConfiguration.CONNECTOR_AMQP10ENABLED, "false"); + setSystemProperty(BrokerProperties.PROPERTY_BROKER_DEFAULT_AMQP_PROTOCOL_EXCLUDES, + Protocol.AMQP_1_0 + "," + Protocol.AMQP_0_10); super.setUp(); @@ -100,52 +104,14 @@ public class SupportedProtocolVersionsTest extends QpidBrokerTestCase connection.close(); } - public void testDisabling091and010and10() throws Exception - { - clearProtocolSupportManipulations(); - - //disable 0-91 and 0-10 and 1-0 support - setConfigurationProperty(ServerConfiguration.CONNECTOR_AMQP10ENABLED, "false"); - setConfigurationProperty(ServerConfiguration.CONNECTOR_AMQP010ENABLED, "false"); - setConfigurationProperty(ServerConfiguration.CONNECTOR_AMQP091ENABLED, "false"); - - super.setUp(); - - //Verify initially requesting a 0-10 connection now negotiates a 0-9 - //connection as the broker should reply with its highest supported protocol - setTestClientSystemProperty(ClientProperties.AMQP_VERSION, "0-10"); - AMQConnection connection = (AMQConnection) getConnection(); - assertEquals("Unexpected protocol version in use", ProtocolVersion.v0_9, connection.getProtocolVersion()); - connection.close(); - } - - public void testDisabling09and091and010and10() throws Exception - { - clearProtocolSupportManipulations(); - - //disable 0-9, 0-91, 0-10 and 1-0 support - setConfigurationProperty(ServerConfiguration.CONNECTOR_AMQP09ENABLED, "false"); - setConfigurationProperty(ServerConfiguration.CONNECTOR_AMQP091ENABLED, "false"); - setConfigurationProperty(ServerConfiguration.CONNECTOR_AMQP010ENABLED, "false"); - setConfigurationProperty(ServerConfiguration.CONNECTOR_AMQP10ENABLED, "false"); - - super.setUp(); - - //Verify initially requesting a 0-10 connection now negotiates a 0-8 - //connection as the broker should reply with its highest supported protocol - setTestClientSystemProperty(ClientProperties.AMQP_VERSION, "0-10"); - AMQConnection connection = (AMQConnection) getConnection(); - assertEquals("Unexpected protocol version in use", ProtocolVersion.v8_0, connection.getProtocolVersion()); - connection.close(); - } - public void testConfiguringReplyingToUnsupported010ProtocolInitiationWith09insteadOf091() throws Exception { clearProtocolSupportManipulations(); //disable 0-10 support, and set the default unsupported protocol initiation reply to 0-9 - setConfigurationProperty(ServerConfiguration.CONNECTOR_AMQP010ENABLED, "false"); - setConfigurationProperty(ServerConfiguration.CONNECTOR_AMQP_SUPPORTED_REPLY, "v0_9"); + setSystemProperty(BrokerProperties.PROPERTY_BROKER_DEFAULT_AMQP_PROTOCOL_EXCLUDES, + Protocol.AMQP_1_0 + "," + Protocol.AMQP_0_10); + setSystemProperty(BrokerProperties.PROPERTY_DEFAULT_SUPPORTED_PROTOCOL_REPLY, "v0_9"); super.setUp(); @@ -164,71 +130,5 @@ public class SupportedProtocolVersionsTest extends QpidBrokerTestCase connection.close(); } - public void testProtocolInclusionThroughQBTCSystemPropertiesOverridesProtocolExclusion() throws Exception - { - testProtocolInclusionOverridesProtocolExclusion(false); - } - - public void testProtocolInclusionThroughConfigOverridesProtocolExclusion() throws Exception - { - testProtocolInclusionOverridesProtocolExclusion(true); - } - - private void testProtocolInclusionOverridesProtocolExclusion(boolean useConfig) throws Exception - { - clearProtocolSupportManipulations(); - - //selectively exclude 0-10 and 1-0 on the test port - setTestSystemProperty(QpidBrokerTestCase.BROKER_PROTOCOL_EXCLUDES,"--exclude-0-10 @PORT --exclude-1-0 @PORT"); - - super.setUp(); - - //Verify initially requesting a 0-10 connection negotiates a 0-9-1 connection - setTestClientSystemProperty(ClientProperties.AMQP_VERSION, "0-10"); - AMQConnection connection = (AMQConnection) getConnection(); - assertEquals("Unexpected protocol version in use", ProtocolVersion.v0_91, connection.getProtocolVersion()); - connection.close(); - - stopBroker(); - - if(useConfig) - { - //selectively include 0-10 support again on the test port through config - setConfigurationProperty(ServerConfiguration.CONNECTOR_INCLUDE_010, String.valueOf(getPort())); - } - else - { - //selectively include 0-10 support again on the test port through QBTC sys props - setTestSystemProperty(QpidBrokerTestCase.BROKER_PROTOCOL_INCLUDES,"--include-0-10 @PORT"); - } - - startBroker(); - - //Verify requesting a 0-10 connection now returns one - setTestClientSystemProperty(ClientProperties.AMQP_VERSION, "0-10"); - connection = (AMQConnection) getConnection(); - assertEquals("Unexpected protocol version in use", ProtocolVersion.v0_10, connection.getProtocolVersion()); - connection.close(); - } - - public void testProtocolInclusionOverridesProtocolDisabling() throws Exception - { - clearProtocolSupportManipulations(); - - //disable 0-10 and 1-0 - setConfigurationProperty(ServerConfiguration.CONNECTOR_AMQP010ENABLED, "false"); - setConfigurationProperty(ServerConfiguration.CONNECTOR_AMQP10ENABLED, "false"); - - //selectively include 0-10 support again on the test port - setConfigurationProperty(ServerConfiguration.CONNECTOR_INCLUDE_010, String.valueOf(getPort())); - - super.setUp(); - - //Verify initially requesting a 0-10 connection still works - setTestClientSystemProperty(ClientProperties.AMQP_VERSION, "0-10"); - AMQConnection connection = (AMQConnection) getConnection(); - assertEquals("Unexpected protocol version in use", ProtocolVersion.v0_10, connection.getProtocolVersion()); - connection.close(); - } } \ No newline at end of file diff --git a/java/systests/src/main/java/org/apache/qpid/server/configuration/ServerConfigurationFileTest.java b/java/systests/src/main/java/org/apache/qpid/server/configuration/ServerConfigurationFileTest.java deleted file mode 100644 index 6f54a56e93..0000000000 --- a/java/systests/src/main/java/org/apache/qpid/server/configuration/ServerConfigurationFileTest.java +++ /dev/null @@ -1,75 +0,0 @@ -/* - * - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * - */ -package org.apache.qpid.server.configuration; - -import org.apache.commons.configuration.ConfigurationException; - -import org.apache.qpid.test.utils.QpidBrokerTestCase; - -/** - * This system test ensures that when loading our default system-test - * configuration file the configuration is correctly loaded. - * - * All configuration values should be set in the systest config file so that - * the ability to load them can be validated. - */ -public class ServerConfigurationFileTest extends QpidBrokerTestCase -{ - private ServerConfiguration _serverConfig; - - public void setUp() throws ConfigurationException - { - if (!_configFile.exists()) - { - fail("Unable to test without config file:" + _configFile); - } - - saveTestConfiguration(); - saveTestVirtualhosts(); - - _serverConfig = new ServerConfiguration(_configFile); - } - - /** - * This helper method ensures that when we attempt to read a value that is - * set in the configuration file we do actualy read a value and not - * simply get a defaulted value from the ServerConfiguration.get*() methods. - * - * @param property the propert to test - */ - private void validatePropertyDefinedInFile(String property) - { - //Verify that we are not just picking up the the default value from the getBoolean - assertNotNull("The value set in the configuration file is not being read for property:" + property, - _serverConfig.getConfig().getProperty(property)); - } - - public void testStatusUpdates() throws ConfigurationException - { - validatePropertyDefinedInFile(ServerConfiguration.STATUS_UPDATES); - } - - public void testLocale() throws ConfigurationException - { - validatePropertyDefinedInFile(ServerConfiguration.ADVANCED_LOCALE); - } - -} diff --git a/java/systests/src/main/java/org/apache/qpid/server/failure/HeapExhaustion.java b/java/systests/src/main/java/org/apache/qpid/server/failure/HeapExhaustion.java deleted file mode 100644 index 87a53a0765..0000000000 --- a/java/systests/src/main/java/org/apache/qpid/server/failure/HeapExhaustion.java +++ /dev/null @@ -1,237 +0,0 @@ -/* - * - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * - */ - -package org.apache.qpid.server.failure; - -import junit.framework.TestCase; -import org.apache.log4j.Logger; - -import org.apache.qpid.AMQException; -import org.apache.qpid.client.failover.FailoverException; -import org.apache.qpid.protocol.AMQConstant; -import org.apache.qpid.test.utils.QpidClientConnectionHelper; - -import javax.jms.DeliveryMode; -import javax.jms.JMSException; -import java.io.IOException; - - -/** Test Case provided by client Non-functional Test NF101: heap exhaustion behaviour */ -public class HeapExhaustion extends TestCase -{ - private static final Logger _logger = Logger.getLogger(HeapExhaustion.class); - - protected QpidClientConnectionHelper conn; - protected final String BROKER = "localhost"; - protected final String vhost = "/test"; - protected final String queue = "direct://amq.direct//queue"; - - protected String hundredK; - protected String megabyte; - - protected String generatePayloadOfSize(Integer numBytes) - { - return new String(new byte[numBytes]); - } - - protected void setUp() throws Exception - { - conn = new QpidClientConnectionHelper(BROKER); - conn.setVirtualHost(vhost); - - try - { - conn.connect(); - } catch (JMSException e) - { - e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates. - } - // clear queue - _logger.debug("setup: clearing test queue"); - conn.consume(queue, 2000); - - hundredK = generatePayloadOfSize(1024 * 100); - megabyte = generatePayloadOfSize(1024 * 1024); - } - - protected void tearDown() throws Exception - { - conn.disconnect(); - } - - - /** - * PUT at maximum rate (although we commit after each PUT) until failure - * - * @throws Exception on error - */ - public void testUntilFailureTransient() throws Exception - { - int copies = 0; - int total = 0; - String payload = hundredK; - int size = payload.getBytes().length; - while (true) - { - conn.put(queue, payload, 1, DeliveryMode.NON_PERSISTENT); - copies++; - total += size; - System.out.println("put copy " + copies + " OK for total bytes: " + total); - } - } - - /** - * PUT at lower rate (5 per second) until failure - * - * @throws Exception on error - */ - public void testUntilFailureWithDelaysTransient() throws Exception - { - int copies = 0; - int total = 0; - String payload = hundredK; - int size = payload.getBytes().length; - while (true) - { - conn.put(queue, payload, 1, DeliveryMode.NON_PERSISTENT); - copies++; - total += size; - System.out.println("put copy " + copies + " OK for total bytes: " + total); - Thread.sleep(200); - } - } - - public static void noDelay() - { - HeapExhaustion he = new HeapExhaustion(); - - try - { - he.setUp(); - } - catch (Exception e) - { - _logger.info("Unable to connect"); - System.exit(0); - } - - try - { - _logger.info("Running testUntilFailure"); - try - { - he.testUntilFailureTransient(); - } - catch (FailoverException fe) - { - _logger.error("Caught failover:" + fe); - } - _logger.info("Finishing Connection "); - - try - { - he.tearDown(); - } - catch (JMSException jmse) - { - if (((AMQException) jmse.getLinkedException()).getErrorCode() == AMQConstant.REQUEST_TIMEOUT) - { - _logger.info("Successful test of testUntilFailure"); - } - else - { - _logger.error("Test Failed due to:" + jmse); - } - } - } - catch (Exception e) - { - _logger.error("Test Failed due to:" + e); - } - } - - public static void withDelay() - { - HeapExhaustion he = new HeapExhaustion(); - - try - { - he.setUp(); - } - catch (Exception e) - { - _logger.info("Unable to connect"); - System.exit(0); - } - - try - { - _logger.info("Running testUntilFailure"); - try - { - he.testUntilFailureWithDelaysTransient(); - } - catch (FailoverException fe) - { - _logger.error("Caught failover:" + fe); - } - _logger.info("Finishing Connection "); - - try - { - he.tearDown(); - } - catch (JMSException jmse) - { - if (((AMQException) jmse.getLinkedException()).getErrorCode() == AMQConstant.REQUEST_TIMEOUT) - { - _logger.info("Successful test of testUntilFailure"); - } - else - { - _logger.error("Test Failed due to:" + jmse); - } - } - } - catch (Exception e) - { - _logger.error("Test Failed due to:" + e); - } - } - - public static void main(String args[]) - { - noDelay(); - - - try - { - System.out.println("Restart failed broker now to retest broker with delays in send."); - System.in.read(); - } - catch (IOException e) - { - _logger.info("Continuing"); - } - - withDelay(); - } -} diff --git a/java/systests/src/main/java/org/apache/qpid/server/logging/AbstractTestLogging.java b/java/systests/src/main/java/org/apache/qpid/server/logging/AbstractTestLogging.java index b666b1f424..84017b6850 100644 --- a/java/systests/src/main/java/org/apache/qpid/server/logging/AbstractTestLogging.java +++ b/java/systests/src/main/java/org/apache/qpid/server/logging/AbstractTestLogging.java @@ -20,12 +20,7 @@ */ package org.apache.qpid.server.logging; -import org.apache.commons.configuration.ConfigurationException; - -import org.apache.qpid.server.configuration.ServerConfiguration; import org.apache.qpid.server.logging.subjects.AbstractTestLogSubject; -import org.apache.qpid.server.registry.ApplicationRegistry; -import org.apache.qpid.server.util.InternalBrokerBaseCase; import org.apache.qpid.test.utils.QpidBrokerTestCase; import org.apache.qpid.util.LogMonitor; @@ -47,8 +42,6 @@ public class AbstractTestLogging extends QpidBrokerTestCase public static final String TEST_LOG_PREFIX = "MESSAGE"; protected LogMonitor _monitor; - private InternalBrokerBaseCase _configLoader; - @Override public void setUp() throws Exception { @@ -58,32 +51,6 @@ public class AbstractTestLogging extends QpidBrokerTestCase _monitor = new LogMonitor(_outputFile); } - protected ServerConfiguration getServerConfig() throws ConfigurationException - { - ServerConfiguration _serverConfiguration; - if (isExternalBroker()) - { - _serverConfiguration = new ServerConfiguration(_configFile) - { - @Override - public void initialise() throws ConfigurationException - { - //Overriding initialise to only setup the vhosts and not - //perform the ConfigurationPlugin setup, removing need for - //an ApplicationRegistry to be loaded. - setupVirtualHosts(getConfig()); - } - }; - _serverConfiguration.initialise(); - } - else - { - _serverConfiguration = ApplicationRegistry.getInstance().getConfiguration(); - } - - return _serverConfiguration; - } - protected void setLogMessagePrefix() { //set the message prefix to facilitate scraping from the munged test output. @@ -94,10 +61,6 @@ public class AbstractTestLogging extends QpidBrokerTestCase public void tearDown() throws Exception { _monitor.close(); - if (isExternalBroker() && _configLoader != null) - { - _configLoader.tearDown(); - } super.tearDown(); } @@ -159,7 +122,7 @@ public class AbstractTestLogging extends QpidBrokerTestCase } protected String fromMessage(String log) - { + {; int startSubject = log.indexOf("]") + 1; int start = log.indexOf("]", startSubject) + 1; diff --git a/java/systests/src/main/java/org/apache/qpid/server/logging/AccessControlLoggingTest.java b/java/systests/src/main/java/org/apache/qpid/server/logging/AccessControlLoggingTest.java index 4b7b3f0cf0..37f960a65a 100644 --- a/java/systests/src/main/java/org/apache/qpid/server/logging/AccessControlLoggingTest.java +++ b/java/systests/src/main/java/org/apache/qpid/server/logging/AccessControlLoggingTest.java @@ -31,10 +31,10 @@ import java.util.List; /** * ACL version 2/3 file testing to verify that ACL actor logging works correctly. - * + * * This suite of tests validate that the AccessControl messages occur correctly * and according to the following format: - * + * *

  * ACL-1001 : Allowed Operation Object {PROPERTIES}
  * ACL-1002 : Denied Operation Object {PROPERTIES}
@@ -83,12 +83,12 @@ public class AccessControlLoggingTest extends AbstractTestLogging
         Session sess = conn.createSession(false, Session.AUTO_ACKNOWLEDGE);
         conn.start();
         ((AMQSession) sess).createQueue(new AMQShortString("allow"), false, false, false);
-        
+
         List matches = findMatches(ACL_LOG_PREFIX);
-        
+
         assertTrue("Should be no ACL log messages", matches.isEmpty());
     }
-    
+
     /**
      * Test that {@code allow-log} ACL entries log correctly.
      */
@@ -98,25 +98,25 @@ public class AccessControlLoggingTest extends AbstractTestLogging
         Session sess = conn.createSession(false, Session.AUTO_ACKNOWLEDGE);
         conn.start();
         ((AMQSession) sess).createQueue(new AMQShortString("allow-log"), false, false, false);
-        
+
         List matches = findMatches(ACL_LOG_PREFIX);
-        
+
         assertEquals("Should only be one ACL log message", 1, matches.size());
-        
+
         String log = getLogMessage(matches, 0);
         String actor = fromActor(log);
         String subject = fromSubject(log);
         String message = getMessageString(fromMessage(log));
-        
+
         validateMessageID(ACL_LOG_PREFIX + 1001, log);
-        
-        assertTrue("Actor should contain the user identity", actor.contains(USER));
+
+        assertTrue("Actor " + actor + " should contain the user identity: " + USER, actor.contains(USER));
         assertTrue("Subject should be empty", subject.length() == 0);
         assertTrue("Message should start with 'Allowed'", message.startsWith("Allowed"));
         assertTrue("Message should contain 'Create Queue'", message.contains("Create Queue"));
         assertTrue("Message should have contained the queue name", message.contains("allow-log"));
     }
-    
+
     /**
      * Test that {@code deny-log} ACL entries log correctly.
      */
@@ -134,25 +134,25 @@ public class AccessControlLoggingTest extends AbstractTestLogging
             // Denied, so exception thrown
             assertEquals("Expected ACCESS_REFUSED error code", AMQConstant.ACCESS_REFUSED, amqe.getErrorCode());
         }
-        
+
         List matches = findMatches(ACL_LOG_PREFIX);
-        
+
         assertEquals("Should only be one ACL log message", 1, matches.size());
-        
+
         String log = getLogMessage(matches, 0);
         String actor = fromActor(log);
         String subject = fromSubject(log);
         String message = getMessageString(fromMessage(log));
-        
+
         validateMessageID(ACL_LOG_PREFIX + 1002, log);
-        
-        assertTrue("Actor should contain the user identity", actor.contains(USER));
+
+        assertTrue("Actor " + actor + " should contain the user identity: " + USER, actor.contains(USER));
         assertTrue("Subject should be empty", subject.length() == 0);
         assertTrue("Message should start with 'Denied'", message.startsWith("Denied"));
         assertTrue("Message should contain 'Create Queue'", message.contains("Create Queue"));
         assertTrue("Message should have contained the queue name", message.contains("deny-log"));
     }
-    
+
     /**
      * Test that {@code deny} ACL entries do not log anything.
      */
@@ -170,9 +170,9 @@ public class AccessControlLoggingTest extends AbstractTestLogging
             // Denied, so exception thrown
             assertEquals("Expected ACCESS_REFUSED error code", AMQConstant.ACCESS_REFUSED, amqe.getErrorCode());
         }
-        
+
         List matches = findMatches(ACL_LOG_PREFIX);
-        
+
         assertTrue("Should be no ACL log messages", matches.isEmpty());
     }
 }
diff --git a/java/systests/src/main/java/org/apache/qpid/server/logging/AlertingTest.java b/java/systests/src/main/java/org/apache/qpid/server/logging/AlertingTest.java
index 02c41e14c0..68ec101245 100644
--- a/java/systests/src/main/java/org/apache/qpid/server/logging/AlertingTest.java
+++ b/java/systests/src/main/java/org/apache/qpid/server/logging/AlertingTest.java
@@ -22,10 +22,6 @@ package org.apache.qpid.server.logging;
 
 import org.apache.qpid.client.AMQDestination;
 import org.apache.qpid.client.AMQSession;
-import org.apache.qpid.framing.AMQShortString;
-import org.apache.qpid.server.configuration.ServerConfiguration;
-import org.apache.qpid.server.registry.ApplicationRegistry;
-import org.apache.qpid.util.FileUtils;
 
 import javax.jms.Connection;
 import javax.jms.Queue;
@@ -44,29 +40,19 @@ public class AlertingTest extends AbstractTestLogging
 
     public void setUp() throws Exception
     {
-        // Update the configuration to make our virtualhost Persistent.
-        makeVirtualHostPersistent(VIRTUALHOST);
-        setConfigurationProperty("virtualhosts.virtualhost." + VIRTUALHOST + ".housekeeping.checkPeriod", "5000");
-
         _numMessages = 50;
 
+        setVirtualHostConfigurationProperty("virtualhosts.virtualhost." + VIRTUALHOST + ".housekeeping.checkPeriod", String.valueOf(ALERT_LOG_WAIT_PERIOD));
+        setVirtualHostConfigurationProperty("virtualhosts.virtualhost." + VIRTUALHOST + ".queues.maximumMessageCount", String.valueOf(_numMessages));
+
         // Then we do the normal setup stuff like starting the broker, getting a connection etc.
         super.setUp();
 
         setupConnection();
     }
 
-    @Override
-    public void tearDown() throws Exception
-    {
-        // Ensure queue is clean for next run.
-        drainQueue(_destination);
-        super.tearDown();
-    }
-
-
     /**
-     * Create a new connection and ensure taht our destination queue is created
+     * Create a new connection and ensure that our destination queue is created
      * and bound.
      *
      * Note that the tests here that restart the broker rely on persistence.
@@ -102,20 +88,6 @@ public class AlertingTest extends AbstractTestLogging
         if (!waitForMessage(MESSAGE_COUNT_ALERT, ALERT_LOG_WAIT_PERIOD))
         {
             StringBuffer message = new StringBuffer("Could not find 'MESSAGE_COUNT_ALERT' in log file: " + _monitor.getMonitoredFile().getAbsolutePath());
-            message.append("\n");
-
-            // Add the current contents of the log file to test output
-            message.append(_monitor.readFile());
-
-            // Write the test config file to test output
-            message.append("Server configuration overrides in use:\n");
-            message.append(FileUtils.readFileAsString(getTestConfigFile()));
-
-            message.append("\nVirtualhost maxMessageCount:\n");
-            ServerConfiguration config = new ServerConfiguration(_configFile);
-            config.initialise();
-            message.append(config.getVirtualHostConfig(VIRTUALHOST).getMaximumMessageCount());
-
             fail(message.toString());
         }
     }
@@ -148,9 +120,6 @@ public class AlertingTest extends AbstractTestLogging
      * Test sends two messages to the broker then restarts the broker with new
      * configuration.
      *
-     * If the test is running inVM the test validates that the new configuration
-     * has been applied.
-     *
      * Validates that we only have two messages on the queue and then sends
      * enough messages to trigger the alert.
      *
@@ -172,31 +141,24 @@ public class AlertingTest extends AbstractTestLogging
         _monitor.markDiscardPoint();
 
         // Change max message count to 5, start broker and make sure that that's triggered at the right time
-        setConfigurationProperty("virtualhosts.virtualhost." + VIRTUALHOST + ".queues.maximumMessageCount", "5");
+        setVirtualHostConfigurationProperty("virtualhosts.virtualhost." + VIRTUALHOST + ".queues.maximumMessageCount", "5");
 
         startBroker();
 
-        if (isInternalBroker())
-        {
-            assertEquals("Alert Max Msg Count is not correct", 5, ApplicationRegistry.getInstance().getVirtualHostRegistry().
-                    getVirtualHost(VIRTUALHOST).getQueueRegistry().getQueue(new AMQShortString(_destination.getQueueName())).
-                    getMaximumMessageCount());
-        }
-
         setupConnection();
 
         // Validate the queue depth is as expected
         long messageCount = ((AMQSession) _session).getQueueDepth((AMQDestination) _destination);
         assertEquals("Broker has invalid message count for test", 2, messageCount);
 
-        // Ensure the alert has not occured yet
+        // Ensure the alert has not occurred yet
         assertLoggingNotYetOccured(MESSAGE_COUNT_ALERT);
 
         // Trigger the new value
         sendMessage(_session, _destination, 3);
         _session.commit();
 
-        // Validate that the alert occured.
+        // Validate that the alert occurred.
         wasAlertFired();
     }
 }
diff --git a/java/systests/src/main/java/org/apache/qpid/server/logging/BrokerLoggingTest.java b/java/systests/src/main/java/org/apache/qpid/server/logging/BrokerLoggingTest.java
index dee593b12b..c5f5e06ae1 100644
--- a/java/systests/src/main/java/org/apache/qpid/server/logging/BrokerLoggingTest.java
+++ b/java/systests/src/main/java/org/apache/qpid/server/logging/BrokerLoggingTest.java
@@ -23,12 +23,20 @@ package org.apache.qpid.server.logging;
 import junit.framework.AssertionFailedError;
 
 import org.apache.qpid.server.BrokerOptions;
+import org.apache.qpid.server.model.Port;
+import org.apache.qpid.server.model.Transport;
+import org.apache.qpid.test.utils.TestBrokerConfiguration;
 import org.apache.qpid.transport.ConnectionException;
 import org.apache.qpid.util.LogMonitor;
 
 import java.io.IOException;
 import java.net.Socket;
+import java.util.Collections;
+import java.util.HashMap;
 import java.util.List;
+import java.util.Map;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
 
 /**
  * Broker Test Suite
@@ -47,6 +55,8 @@ import java.util.List;
  */
 public class BrokerLoggingTest extends AbstractTestLogging
 {
+    private static final String BROKER_MESSAGE_LOG_REG_EXP = ".*\\[\\w*\\] (BRK\\-\\d*) .*";
+    private static final Pattern BROKER_MESSAGE_LOG_PATTERN = Pattern.compile(BROKER_MESSAGE_LOG_REG_EXP);
     private static final String BRK_LOG_PREFIX = "BRK-";
 
     public void setUp() throws Exception
@@ -95,7 +105,7 @@ public class BrokerLoggingTest extends AbstractTestLogging
             _monitor = new LogMonitor(_outputFile);
 
 
-            String configFilePath = _configFile.toString();
+            String configFilePath = getConfigPath();
 
             // Ensure we wait for TESTID to be logged
             waitAndFindMatches(TESTID);
@@ -118,8 +128,9 @@ public class BrokerLoggingTest extends AbstractTestLogging
                              1, results.size());
 
                 //3
-                assertTrue("Config file details not correctly logged",
-                           log.endsWith(configFilePath));
+                assertTrue("Config file details not correctly logged, got "
+                        + log + " but expected it to end with " + configFilePath,
+                        log.endsWith(configFilePath));
             }
             catch (AssertionFailedError afe)
             {
@@ -130,6 +141,11 @@ public class BrokerLoggingTest extends AbstractTestLogging
         }
     }
 
+    private String getConfigPath()
+    {
+        return getPathRelativeToWorkingDirectory(getTestConfigFile(DEFAULT_PORT));
+    }
+
     /**
      * Description:
      * On startup the broker must report correctly report the log4j file in use. This is important as it can help diagnose why logging messages are not being reported.
@@ -155,8 +171,7 @@ public class BrokerLoggingTest extends AbstractTestLogging
         {
             String TESTID = "BRK-1007";
 
-            //Remove test Log4j config from the commandline
-            _brokerCommand = _brokerCommand.substring(0, _brokerCommand.indexOf("-l"));
+            _brokerCommandHelper.removeBrokerCommandLog4JFile();
 
             startBroker();
 
@@ -243,8 +258,7 @@ public class BrokerLoggingTest extends AbstractTestLogging
         // This logging startup code only occurs when you run a Java broker
         if (isJavaBroker() && isExternalBroker())
         {
-            // Get custom -l value used during testing for the broker startup
-            String customLog4j = _brokerCommand.substring(_brokerCommand.indexOf("-l") + 2).trim();
+            String customLog4j = getBrokerCommandLog4JFile().getAbsolutePath();
 
             String TESTID = "BRK-1007";
 
@@ -293,8 +307,10 @@ public class BrokerLoggingTest extends AbstractTestLogging
                                  1, findMatches(TESTID).size());
 
                     //3
-                    assertTrue("Log4j file details not correctly logged:" + getMessageString(log),
-                               getMessageString(log).endsWith(customLog4j));
+                    String messageString = getMessageString(log);
+                    assertTrue("Log4j file details not correctly logged. Message '"
+                            + messageString + "' should contain '" +customLog4j + "'",
+                            messageString.endsWith(customLog4j));
 
                     validation = true;
                 }
@@ -442,10 +458,13 @@ public class BrokerLoggingTest extends AbstractTestLogging
                 {
                     String log = getLog(rawLog);
 
+                    // using custom method to get id as getMessageId() fails to correctly identify id
+                    // because of using brackets for protocols
+                    String id = getBrokerLogId(log);
                     // Ensure we do not have a BRK-1002 message
-                    if (!getMessageID(log).equals(TESTID))
+                    if (!id.equals(TESTID))
                     {
-                        if (getMessageID(log).equals("BRK-1001"))
+                        if (id.equals("BRK-1001"))
                         {
                             foundBRK1001 = true;
                         }
@@ -455,7 +474,7 @@ public class BrokerLoggingTest extends AbstractTestLogging
                     assertTrue("BRK-1001 not logged before this message", foundBRK1001);
 
                     //1
-                    validateMessageID(TESTID, log);
+                    assertEquals("Incorrect message", TESTID, id);
 
                     //2
                     //There will be 2 copies of the startup message (one via SystemOut, and one via Log4J)
@@ -465,7 +484,7 @@ public class BrokerLoggingTest extends AbstractTestLogging
                     //3
                     String message = getMessageString(log);
                     assertTrue("Expected Listen log not correct" + message,
-                               message.endsWith("Listening on TCP port " + getPort()));
+                               message.endsWith("Listening on [TCP] port " + getPort()));
 
                     validation = true;
                 }
@@ -481,6 +500,16 @@ public class BrokerLoggingTest extends AbstractTestLogging
         }
     }
 
+    private String getBrokerLogId(String log)
+    {
+        Matcher m = BROKER_MESSAGE_LOG_PATTERN.matcher(log);
+        if (m.matches())
+        {
+            return m.group(1);
+        }
+        return getMessageID(log);
+    }
+
     /**
      * Description:
      * On startup the broker may listen on a number of ports and protocols. Each of these must be reported as they are made available.
@@ -498,8 +527,8 @@ public class BrokerLoggingTest extends AbstractTestLogging
      * 1. The BRK ID is correct
      * 2. This occurs after the BRK-1001 startup message
      * 3. With SSL enabled in the configuration two BRK-1002 will be printed (order is not specified)
-     * 1. One showing values TCP / 5672
-     * 2. One showing values TCP/SSL / 5672
+     * 1. One showing values [TCP] 5672
+     * 2. One showing values [SSL] 5671
      *
      * @throws Exception caused by broker startup
      */
@@ -512,12 +541,11 @@ public class BrokerLoggingTest extends AbstractTestLogging
             String TESTID = "BRK-1002";
 
             // Enable SSL on the connection
-            setConfigurationProperty("connector.ssl.enabled", "true");
-            setConfigurationProperty("connector.ssl.sslOnly", "false");
-            setConfigurationProperty("connector.ssl.keyStorePath", getConfigurationStringProperty("management.ssl.keyStorePath"));
-            setConfigurationProperty("connector.ssl.keyStorePassword", getConfigurationStringProperty("management.ssl.keyStorePassword"));
-
-            Integer sslPort = Integer.parseInt(getConfigurationStringProperty("connector.ssl.port"));
+            Map sslPortAttributes = new HashMap();
+            sslPortAttributes.put(Port.TRANSPORTS, Collections.singleton(Transport.SSL));
+            sslPortAttributes.put(Port.PORT, DEFAULT_SSL_PORT);
+            sslPortAttributes.put(Port.NAME, TestBrokerConfiguration.ENTRY_NAME_SSL_PORT);
+            getBrokerConfiguration().addPortConfiguration(sslPortAttributes);
 
             startBroker();
 
@@ -545,10 +573,11 @@ public class BrokerLoggingTest extends AbstractTestLogging
                 {
                     String log = getLog(rawLog);
 
+                    String id = getBrokerLogId(log);
                     // Ensure we do not have a BRK-1002 message
-                    if (!getMessageID(log).equals(TESTID))
+                    if (!id.equals(TESTID))
                     {
-                        if (getMessageID(log).equals("BRK-1001"))
+                        if (id.equals("BRK-1001"))
                         {
                             foundBRK1001 = true;
                         }
@@ -558,7 +587,7 @@ public class BrokerLoggingTest extends AbstractTestLogging
                     assertTrue("BRK-1001 not logged before this message", foundBRK1001);
 
                     //1
-                    validateMessageID(TESTID, log);
+                    assertEquals("Incorrect message", TESTID, id);
 
                     //2
                     //There will be 4 copies of the startup message (two via SystemOut, and two via Log4J)
@@ -570,16 +599,16 @@ public class BrokerLoggingTest extends AbstractTestLogging
                     //Check the first
                     String message = getMessageString(getLog(listenMessages .get(0)));
                     assertTrue("Expected Listen log not correct" + message,
-                               message.endsWith("Listening on TCP port " + getPort()));
+                               message.endsWith("Listening on [TCP] port " + getPort()));
 
                     // Check the third, ssl listen.
                     message = getMessageString(getLog(listenMessages .get(2)));
                     assertTrue("Expected Listen log not correct" + message,
-                               message.endsWith("Listening on TCP/SSL port " + sslPort));
+                               message.endsWith("Listening on [SSL] port " + DEFAULT_SSL_PORT));
 
                     //4 Test ports open
                     testSocketOpen(getPort());
-                    testSocketOpen(sslPort);
+                    testSocketOpen(DEFAULT_SSL_PORT);
 
                     validation = true;
                 }
@@ -803,11 +832,11 @@ public class BrokerLoggingTest extends AbstractTestLogging
             String TESTID = "BRK-1003";
 
             // Enable SSL on the connection
-            setConfigurationProperty("connector.ssl.enabled", "true");
-            setConfigurationProperty("connector.ssl.keyStorePath", getConfigurationStringProperty("management.ssl.keyStorePath"));
-            setConfigurationProperty("connector.ssl.keyStorePassword", getConfigurationStringProperty("management.ssl.keyStorePassword"));
-
-            Integer sslPort = Integer.parseInt(getConfigurationStringProperty("connector.ssl.port"));
+            Map sslPortAttributes = new HashMap();
+            sslPortAttributes.put(Port.TRANSPORTS, Collections.singleton(Transport.SSL));
+            sslPortAttributes.put(Port.PORT, DEFAULT_SSL_PORT);
+            sslPortAttributes.put(Port.NAME, TestBrokerConfiguration.ENTRY_NAME_SSL_PORT);
+            getBrokerConfiguration().addPortConfiguration(sslPortAttributes);
 
             startBroker();
 
@@ -848,13 +877,13 @@ public class BrokerLoggingTest extends AbstractTestLogging
                 // Check second, ssl, listen.
                 message = getMessageString(getLog(listenMessages.get(1)));
                 assertTrue("Expected shutdown log not correct" + message,
-                           message.endsWith("TCP/SSL port " + sslPort));
+                           message.endsWith("TCP/SSL port " + DEFAULT_SSL_PORT));
 
                 //4
                 //Test Port closed
                 checkSocketClosed(getPort());
                 //Test SSL Port closed
-                checkSocketClosed(sslPort);
+                checkSocketClosed(DEFAULT_SSL_PORT);
             }
             catch (AssertionFailedError afe)
             {
@@ -999,4 +1028,5 @@ public class BrokerLoggingTest extends AbstractTestLogging
                  + ". Due to:" + e.getMessage());
         }
     }
+
 }
diff --git a/java/systests/src/main/java/org/apache/qpid/server/logging/SubscriptionLoggingTest.java b/java/systests/src/main/java/org/apache/qpid/server/logging/SubscriptionLoggingTest.java
index 236202f323..9f532ec5f7 100644
--- a/java/systests/src/main/java/org/apache/qpid/server/logging/SubscriptionLoggingTest.java
+++ b/java/systests/src/main/java/org/apache/qpid/server/logging/SubscriptionLoggingTest.java
@@ -66,8 +66,8 @@ public class SubscriptionLoggingTest extends AbstractTestLogging
 
         _session = _connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
 
-        _queue = (Queue) getInitialContext().lookup(QUEUE);
-        _topic = (Topic) getInitialContext().lookup(TOPIC);
+        _queue = _session.createQueue(getTestQueueName() + "Queue");
+        _topic = _session.createTopic(getTestQueueName() + "Topic");
     }
 
     /**
@@ -434,10 +434,6 @@ public class SubscriptionLoggingTest extends AbstractTestLogging
             throw afe;
         }
         _connection.close();
-
-        //Ensure the queue is drained before the test ends
-        drainQueue(_queue);
-
     }
 
     /**
diff --git a/java/systests/src/main/java/org/apache/qpid/server/logging/VirtualHostLoggingTest.java b/java/systests/src/main/java/org/apache/qpid/server/logging/VirtualHostLoggingTest.java
index 5f96215269..1ea105ae1a 100644
--- a/java/systests/src/main/java/org/apache/qpid/server/logging/VirtualHostLoggingTest.java
+++ b/java/systests/src/main/java/org/apache/qpid/server/logging/VirtualHostLoggingTest.java
@@ -23,7 +23,6 @@ package org.apache.qpid.server.logging;
 
 import junit.framework.AssertionFailedError;
 
-import org.apache.qpid.server.configuration.ServerConfiguration;
 
 import java.util.Arrays;
 import java.util.List;
@@ -68,7 +67,7 @@ public class VirtualHostLoggingTest extends AbstractTestLogging
         
         try
         {
-            List vhosts = Arrays.asList(getServerConfig().getVirtualHosts());
+            List vhosts = Arrays.asList("test");
 
             assertEquals("Each vhost did not create a store.", vhosts.size(), results.size());
 
@@ -110,23 +109,17 @@ public class VirtualHostLoggingTest extends AbstractTestLogging
 
         // Wait for the correct VHT message to arrive.                                 
         waitForMessage(VHT_PREFIX + "1002");
-        
+
         // Validate each vhost logs a closure
         List results = findMatches(VHT_PREFIX + "1002");
-        
+
         try
         {
-            // Load VirtualHost list from file. 
-            ServerConfiguration configuration = new ServerConfiguration(_configFile);
-            configuration.initialise();
-            List vhosts = Arrays.asList(configuration.getVirtualHosts());
-
-            assertEquals("Each vhost did not close their store.", vhosts.size(), results.size());
+            assertEquals("Each vhost did not close their store.", 1, results.size());
         }
         catch (AssertionFailedError afe)
         {
             dumpLogs(results, _monitor);
-
             throw afe;
         }
     }
diff --git a/java/systests/src/main/java/org/apache/qpid/server/persistent/NoLocalAfterRecoveryTest.java b/java/systests/src/main/java/org/apache/qpid/server/persistent/NoLocalAfterRecoveryTest.java
index bcad59a1fa..82b421a531 100644
--- a/java/systests/src/main/java/org/apache/qpid/server/persistent/NoLocalAfterRecoveryTest.java
+++ b/java/systests/src/main/java/org/apache/qpid/server/persistent/NoLocalAfterRecoveryTest.java
@@ -39,7 +39,7 @@ import org.apache.qpid.test.utils.QpidBrokerTestCase;
  */
 public class NoLocalAfterRecoveryTest extends QpidBrokerTestCase
 {
-    protected final String MY_TOPIC_SUBSCRIPTION_NAME = this.getName();
+    protected final String MY_TOPIC_SUBSCRIPTION_NAME = getTestQueueName();
     protected static final int SEND_COUNT = 10;
 
     public void testNoLocalNotQueued() throws Exception
diff --git a/java/systests/src/main/java/org/apache/qpid/server/queue/MultipleTransactedBatchProducerTest.java b/java/systests/src/main/java/org/apache/qpid/server/queue/MultipleTransactedBatchProducerTest.java
index 8536651ffb..cbf4e032db 100644
--- a/java/systests/src/main/java/org/apache/qpid/server/queue/MultipleTransactedBatchProducerTest.java
+++ b/java/systests/src/main/java/org/apache/qpid/server/queue/MultipleTransactedBatchProducerTest.java
@@ -30,6 +30,7 @@ import javax.jms.Message;
 import javax.jms.MessageConsumer;
 import javax.jms.MessageListener;
 import javax.jms.Session;
+
 import java.util.Random;
 import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.TimeUnit;
@@ -54,7 +55,9 @@ public class MultipleTransactedBatchProducerTest extends QpidBrokerTestCase
         //debug level logging often makes this test pass artificially, turn the level down to info.
         setSystemProperty("amqj.server.logging.level", "INFO");
         _receivedLatch = new CountDownLatch(MESSAGE_COUNT * NUM_PRODUCERS);
-        setConfigurationProperty("management.enabled", "true");
+
+        getBrokerConfiguration().addJmxManagementConfiguration();
+
         super.setUp();
         _queueName = getTestQueueName();
         _failMsg = null;
diff --git a/java/systests/src/main/java/org/apache/qpid/server/security/acl/AbstractACLTestCase.java b/java/systests/src/main/java/org/apache/qpid/server/security/acl/AbstractACLTestCase.java
index 8ccf74a22b..814936f342 100644
--- a/java/systests/src/main/java/org/apache/qpid/server/security/acl/AbstractACLTestCase.java
+++ b/java/systests/src/main/java/org/apache/qpid/server/security/acl/AbstractACLTestCase.java
@@ -26,6 +26,7 @@ import org.apache.qpid.client.AMQConnection;
 import org.apache.qpid.client.AMQConnectionURL;
 import org.apache.qpid.jms.ConnectionListener;
 import org.apache.qpid.protocol.AMQConstant;
+import org.apache.qpid.server.model.Broker;
 import org.apache.qpid.test.utils.QpidBrokerTestCase;
 import org.apache.qpid.url.URLSyntaxException;
 
@@ -45,7 +46,7 @@ import java.util.concurrent.TimeUnit;
 /**
  * Abstract test case for ACLs.
  * 
- * This base class contains convenience methods to mange ACL files and implements a mechanism that allows each
+ * This base class contains convenience methods to manage ACL files and implements a mechanism that allows each
  * test method to run its own setup code before the broker starts.
  * 
  * TODO move the pre broker-startup setup method invocation code to {@link QpidBrokerTestCase}
@@ -58,25 +59,11 @@ public abstract class AbstractACLTestCase extends QpidBrokerTestCase implements
 {
     /** Used to synchronise {@link #tearDown()} when exceptions are thrown */
     protected CountDownLatch _exceptionReceived;
-    
-    /** Override this to return the name of the configuration XML file. */
-    public String getConfig()
-    {
-        return "config-systests.xml";
-    }
 
-    /**
-     * This setup method checks {@link #getConfig()} and {@link #getHostList()} to initialise the broker with specific
-     * ACL configurations and then runs an optional per-test setup method, which is simply a method with the same name
-     * as the test, but starting with {@code setUp} rather than {@code test}.
-     * 
-     * @see org.apache.qpid.test.utils.QpidBrokerTestCase#setUp()
-     */
     @Override
     public void setUp() throws Exception
     {
-        // Initialise ACLs.
-        _configFile = new File("build" + File.separator + "etc" + File.separator + getConfig());
+        getBrokerConfiguration().setBrokerAttribute(Broker.GROUP_FILE, System.getProperty(QPID_HOME) + "/etc/groups-systests");
 
         // run test specific setup
         String testSetup = StringUtils.replace(getName(), "test", "setUp");
@@ -123,11 +110,11 @@ public abstract class AbstractACLTestCase extends QpidBrokerTestCase implements
 
         if (vhost == null)
         {
-            testcase.setConfigurationProperty("security.acl", aclFile.getAbsolutePath());
+            testcase.getBrokerConfiguration().setBrokerAttribute(Broker.ACL_FILE, aclFile.getAbsolutePath());
         }
         else
         {
-            testcase.setConfigurationProperty("virtualhosts.virtualhost." + vhost + ".security.acl", aclFile.getAbsolutePath());
+            testcase.setVirtualHostConfigurationProperty("virtualhosts.virtualhost." + vhost + ".security.acl", aclFile.getAbsolutePath());
         }
 
         PrintWriter out = new PrintWriter(new FileWriter(aclFile));
diff --git a/java/systests/src/main/java/org/apache/qpid/server/security/acl/ExternalACLJMXTest.java b/java/systests/src/main/java/org/apache/qpid/server/security/acl/ExternalACLJMXTest.java
index ceff2b998a..1830040007 100644
--- a/java/systests/src/main/java/org/apache/qpid/server/security/acl/ExternalACLJMXTest.java
+++ b/java/systests/src/main/java/org/apache/qpid/server/security/acl/ExternalACLJMXTest.java
@@ -33,14 +33,19 @@ import java.lang.management.RuntimeMXBean;
  */
 public class ExternalACLJMXTest extends AbstractACLTestCase
 {
+
     private JMXTestUtils _jmx;
 
     private static final String TEST_QUEUE_OWNER = "admin";
     private static final String TEST_VHOST = "test";
+    private static final String TEST2_VHOST = "test2";
 
     @Override
     public void setUp() throws Exception
     {
+        createTestVirtualHost(0, TEST_VHOST);
+        createTestVirtualHost(0, TEST2_VHOST);
+
         _jmx = new JMXTestUtils(this);
         _jmx.setUp();
         super.setUp();
@@ -54,15 +59,14 @@ public class ExternalACLJMXTest extends AbstractACLTestCase
         super.tearDown();
     }
 
-    /**
-     * Ensure an empty ACL defaults to DENY ALL.
-     */
-    public void setUpDenyAllIsDefault() throws Exception
+    public void setUpDenyAllIsCatchAllRule() throws Exception
     {
-        writeACLFile(null, "#Empty ACL file");
+        writeACLFile(null,
+                "ACL ALLOW admin ACCESS MANAGEMENT",
+                "#No more rules, default catch all (deny all) should apply");
     }
 
-    public void testDenyAllIsDefault() throws Exception
+    public void testDenyAllIsCatchAllRule() throws Exception
     {
         //try a broker-level method
         ServerInformation info = _jmx.getServerInformation();
@@ -115,6 +119,7 @@ public class ExternalACLJMXTest extends AbstractACLTestCase
     public void setUpVhostAllowOverridesGlobalDeny() throws Exception
     {
         writeACLFile(null,
+                "ACL ALLOW admin ACCESS MANAGEMENT",
                 "ACL DENY admin UPDATE METHOD component='VirtualHost.VirtualHostManager' name='createNewQueue'");
         writeACLFile(TEST_VHOST,
                 "ACL ALLOW admin UPDATE METHOD component='VirtualHost.VirtualHostManager' name='createNewQueue'");
@@ -128,7 +133,7 @@ public class ExternalACLJMXTest extends AbstractACLTestCase
         //try a vhost-level method on a different vhost
         try
         {
-            _jmx.createQueue("development", getTestQueueName(), TEST_QUEUE_OWNER, true);
+            _jmx.createQueue(TEST2_VHOST, getTestQueueName(), TEST_QUEUE_OWNER, true);
             fail("Exception not thrown");
         }
         catch (SecurityException e)
@@ -144,6 +149,7 @@ public class ExternalACLJMXTest extends AbstractACLTestCase
     public void setUpUpdateComponentOnlyAllow() throws Exception
     {
         writeACLFile(null,
+                "ACL ALLOW admin ACCESS MANAGEMENT",
                 "ACL ALLOW admin UPDATE METHOD component='VirtualHost.VirtualHostManager'");
     }
 
@@ -162,6 +168,7 @@ public class ExternalACLJMXTest extends AbstractACLTestCase
     public void setUpUpdateMethodOnlyAllow() throws Exception
     {
         writeACLFile(null,
+                "ACL ALLOW admin ACCESS MANAGEMENT",
                 "ACL ALLOW admin UPDATE METHOD");
     }
 
@@ -179,8 +186,8 @@ public class ExternalACLJMXTest extends AbstractACLTestCase
      */
     public void setUpCreateQueueSuccess() throws Exception
     {
-        writeACLFile(TEST_VHOST,
-                "ACL ALLOW admin UPDATE METHOD component='VirtualHost.VirtualHostManager' name='createNewQueue'");
+        writeACLFile(null, "ACL ALLOW admin ACCESS MANAGEMENT");
+        writeACLFile(TEST_VHOST, "ACL ALLOW admin UPDATE METHOD component='VirtualHost.VirtualHostManager' name='createNewQueue'");
     }
 
     public void testCreateQueueSuccess() throws Exception
@@ -194,6 +201,7 @@ public class ExternalACLJMXTest extends AbstractACLTestCase
      */
     public void setUpCreateQueueSuccessNoAMQPRights() throws Exception
     {
+        writeACLFile(null, "ACL ALLOW admin ACCESS MANAGEMENT");
         writeACLFile(TEST_VHOST,
                 "ACL ALLOW admin UPDATE METHOD component='VirtualHost.VirtualHostManager' name='createNewQueue'",
                 "ACL DENY admin CREATE QUEUE");
@@ -210,6 +218,7 @@ public class ExternalACLJMXTest extends AbstractACLTestCase
      */
     public void setUpCreateQueueDenied() throws Exception
     {
+        writeACLFile(null, "ACL ALLOW admin ACCESS MANAGEMENT");
         writeACLFile(TEST_VHOST,
                 "ACL DENY admin UPDATE METHOD component='VirtualHost.VirtualHostManager' name='createNewQueue'");
     }
@@ -234,6 +243,7 @@ public class ExternalACLJMXTest extends AbstractACLTestCase
     public void setUpServerInformationUpdateDenied() throws Exception
     {
         writeACLFile(null,
+                "ACL ALLOW admin ACCESS MANAGEMENT",
                 "ACL DENY admin UPDATE METHOD component='ServerInformation' name='resetStatistics'");
     }
 
@@ -258,6 +268,7 @@ public class ExternalACLJMXTest extends AbstractACLTestCase
     public void setUpServerInformationAccessGranted() throws Exception
     {
         writeACLFile(null,
+        "ACL ALLOW admin ACCESS MANAGEMENT",
         "ACL ALLOW-LOG admin ACCESS METHOD component='ServerInformation' name='getManagementApiMajorVersion'");
     }
 
@@ -284,6 +295,7 @@ public class ExternalACLJMXTest extends AbstractACLTestCase
     public void setUpServerInformationUpdateMethodPermission() throws Exception
     {
         writeACLFile(null,
+                "ACL ALLOW admin ACCESS MANAGEMENT",
                 "ACL ALLOW admin UPDATE METHOD component='ServerInformation' name='resetStatistics'");
     }
 
@@ -300,7 +312,9 @@ public class ExternalACLJMXTest extends AbstractACLTestCase
      */
     public void setUpServerInformationAllMethodPermissions() throws Exception
     {
-        writeACLFile(null, "ACL ALLOW admin ALL METHOD component='ServerInformation'");
+        writeACLFile(null,
+                "ACL ALLOW admin ACCESS MANAGEMENT",
+                "ACL ALLOW admin ALL METHOD component='ServerInformation'");
     }
 
     public void testServerInformationAllMethodPermissions() throws Exception
diff --git a/java/systests/src/main/java/org/apache/qpid/server/security/acl/ExternalACLTest.java b/java/systests/src/main/java/org/apache/qpid/server/security/acl/ExternalACLTest.java
index 0e45ca9493..8324ac74a5 100644
--- a/java/systests/src/main/java/org/apache/qpid/server/security/acl/ExternalACLTest.java
+++ b/java/systests/src/main/java/org/apache/qpid/server/security/acl/ExternalACLTest.java
@@ -319,8 +319,12 @@ public class ExternalACLTest extends AbstractACLTestCase
 
     public void setUpRequestResponseSuccess() throws Exception
     {
-        writeACLFile("test", "GROUP messaging-users client server",
-                             "ACL ALLOW-LOG messaging-users ACCESS VIRTUALHOST",
+        // The group "messaging-users", referenced in the ACL below, is currently defined
+        // in broker/etc/groups-systests.
+        // We tolerate a dependency from this test to that file because its
+        // contents are expected to change rarely.
+
+        writeACLFile("test", "ACL ALLOW-LOG messaging-users ACCESS VIRTUALHOST",
                              "# Server side",
                              "ACL ALLOW-LOG server CREATE QUEUE name=\"example.RequestQueue\"" ,
                              "ACL ALLOW-LOG server BIND EXCHANGE",
@@ -389,14 +393,44 @@ public class ExternalACLTest extends AbstractACLTestCase
         conn.start();
 
         // create kipper
-        Topic kipper = sess.createTopic("kipper");
-        TopicSubscriber subscriber = sess.createDurableSubscriber(kipper, "kipper");
+        String topicName = "kipper";
+        Topic topic = sess.createTopic(topicName);
+        TopicSubscriber subscriber = sess.createDurableSubscriber(topic, topicName);
 
         subscriber.close();
-        sess.unsubscribe("kipper");
+        sess.unsubscribe(topicName);
 
         //Do something to show connection is active.
         sess.rollback();
         conn.close();
     }
+
+    public void setUpFirewallAllow() throws Exception
+    {
+        writeACLFile("test", "ACL ALLOW client ACCESS VIRTUALHOST from_network=\"127.0.0.1\"");
+    }
+
+    public void testFirewallAllow() throws Exception
+    {
+        getConnection("test", "client", "guest");
+        // test pass because we successfully connected
+    }
+
+    public void setUpFirewallDeny() throws Exception
+    {
+        writeACLFile("test", "ACL DENY client ACCESS VIRTUALHOST from_network=\"127.0.0.1\"");
+    }
+
+    public void testFirewallDeny() throws Exception
+    {
+        try
+        {
+            getConnection("test", "client", "guest");
+            fail("We expected the connection to fail");
+        }
+        catch(JMSException e)
+        {
+            // pass
+        }
+    }
 }
diff --git a/java/systests/src/main/java/org/apache/qpid/server/security/auth/manager/ExternalAuthenticationTest.java b/java/systests/src/main/java/org/apache/qpid/server/security/auth/manager/ExternalAuthenticationTest.java
new file mode 100644
index 0000000000..c7a43a292b
--- /dev/null
+++ b/java/systests/src/main/java/org/apache/qpid/server/security/auth/manager/ExternalAuthenticationTest.java
@@ -0,0 +1,184 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ *
+ *
+ */
+package org.apache.qpid.server.security.auth.manager;
+
+import static org.apache.qpid.test.utils.TestSSLConstants.KEYSTORE;
+import static org.apache.qpid.test.utils.TestSSLConstants.KEYSTORE_PASSWORD;
+import static org.apache.qpid.test.utils.TestSSLConstants.TRUSTSTORE;
+import static org.apache.qpid.test.utils.TestSSLConstants.TRUSTSTORE_PASSWORD;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.jms.Connection;
+import javax.jms.JMSException;
+
+import org.apache.commons.configuration.ConfigurationException;
+import org.apache.qpid.client.AMQConnectionURL;
+import org.apache.qpid.server.model.AuthenticationProvider;
+import org.apache.qpid.server.model.Broker;
+import org.apache.qpid.server.model.Port;
+import org.apache.qpid.server.model.Transport;
+import org.apache.qpid.server.plugin.AuthenticationManagerFactory;
+import org.apache.qpid.test.utils.QpidBrokerTestCase;
+import org.apache.qpid.test.utils.TestBrokerConfiguration;
+
+public class ExternalAuthenticationTest extends QpidBrokerTestCase
+{
+    @Override
+    protected void setUp() throws Exception
+    {
+        // not calling super.setUp() to avoid broker start-up
+    }
+
+    /**
+     * Tests that when EXTERNAL authentication is used on the SSL port, clients presenting certificates are able to connect.
+     * Also, checks that default authentication manager PrincipalDatabaseAuthenticationManager is used on non SSL port.
+     */
+    public void testExternalAuthenticationManagerOnSSLPort() throws Exception
+    {
+        setCommonBrokerSSLProperties(true);
+        getBrokerConfiguration().setObjectAttribute(TestBrokerConfiguration.ENTRY_NAME_SSL_PORT, Port.AUTHENTICATION_MANAGER, TestBrokerConfiguration.ENTRY_NAME_EXTERNAL_PROVIDER);
+        super.setUp();
+
+        setClientKeystoreProperties();
+        setClientTrustoreProperties();
+
+        try
+        {
+            getExternalSSLConnection(false);
+        }
+        catch (JMSException e)
+        {
+            fail("Should be able to create a connection to the SSL port: " + e.getMessage());
+        }
+
+        try
+        {
+            getConnection();
+        }
+        catch (JMSException e)
+        {
+            fail("Should be able to create a connection with credentials to the standard port: " + e.getMessage());
+        }
+
+    }
+
+    /**
+     * Tests that when EXTERNAL authentication manager is set as the default, clients presenting certificates are able to connect.
+     * Also, checks a client with valid username and password but not using ssl is unable to connect to the non SSL port.
+     */
+    public void testExternalAuthenticationManagerAsDefault() throws Exception
+    {
+        setCommonBrokerSSLProperties(true);
+        getBrokerConfiguration().setBrokerAttribute(Broker.DEFAULT_AUTHENTICATION_PROVIDER, TestBrokerConfiguration.ENTRY_NAME_EXTERNAL_PROVIDER);
+        super.setUp();
+
+        setClientKeystoreProperties();
+        setClientTrustoreProperties();
+
+        try
+        {
+            getConnection();
+            fail("Connection should not succeed");
+        }
+        catch (JMSException e)
+        {
+            // pass
+        }
+
+        try
+        {
+            getExternalSSLConnection(false);
+        }
+        catch (JMSException e)
+        {
+            fail("Should be able to create a connection to the SSL port. " + e.getMessage());
+        }
+    }
+
+    /**
+     * Tests that when EXTERNAL authentication manager is set as the default, clients without certificates are unable to connect to the SSL port
+     * even with valid username and password.
+     */
+    public void testExternalAuthenticationManagerWithoutClientKeyStore() throws Exception
+    {
+        setCommonBrokerSSLProperties(false);
+        getBrokerConfiguration().setBrokerAttribute(Broker.DEFAULT_AUTHENTICATION_PROVIDER, TestBrokerConfiguration.ENTRY_NAME_EXTERNAL_PROVIDER);
+        super.setUp();
+
+        setClientTrustoreProperties();
+
+        try
+        {
+            getExternalSSLConnection(true);
+            fail("Connection should not succeed");
+        }
+        catch (JMSException e)
+        {
+            // pass
+        }
+    }
+
+    private Connection getExternalSSLConnection(boolean includeUserNameAndPassword) throws Exception
+    {
+        String url = "amqp://%s@test/?brokerlist='tcp://localhost:%s?ssl='true'&sasl_mechs='EXTERNAL''";
+        if (includeUserNameAndPassword)
+        {
+            url = String.format(url, "guest:guest", String.valueOf(QpidBrokerTestCase.DEFAULT_SSL_PORT));
+        }
+        else
+        {
+            url = String.format(url, ":", String.valueOf(QpidBrokerTestCase.DEFAULT_SSL_PORT));
+        }
+        return getConnection(new AMQConnectionURL(url));
+    }
+
+    private void setCommonBrokerSSLProperties(boolean needClientAuth) throws ConfigurationException
+    {
+        TestBrokerConfiguration config = getBrokerConfiguration();
+        Map sslPortAttributes = new HashMap();
+        sslPortAttributes.put(Port.TRANSPORTS, Collections.singleton(Transport.SSL));
+        sslPortAttributes.put(Port.PORT, DEFAULT_SSL_PORT);
+        sslPortAttributes.put(Port.NEED_CLIENT_AUTH, String.valueOf(needClientAuth));
+        sslPortAttributes.put(Port.NAME, TestBrokerConfiguration.ENTRY_NAME_SSL_PORT);
+        config.addPortConfiguration(sslPortAttributes);
+
+        Map externalAuthProviderAttributes = new HashMap();
+        externalAuthProviderAttributes.put(AuthenticationManagerFactory.ATTRIBUTE_TYPE, ExternalAuthenticationManagerFactory.PROVIDER_TYPE);
+        externalAuthProviderAttributes.put(AuthenticationProvider.NAME, TestBrokerConfiguration.ENTRY_NAME_EXTERNAL_PROVIDER);
+        config.addAuthenticationProviderConfiguration(externalAuthProviderAttributes);
+    }
+
+    private void setClientKeystoreProperties()
+    {
+        setSystemProperty("javax.net.ssl.keyStore", KEYSTORE);
+        setSystemProperty("javax.net.ssl.keyStorePassword", KEYSTORE_PASSWORD);
+    }
+
+    private void setClientTrustoreProperties()
+    {
+        setSystemProperty("javax.net.ssl.trustStore", TRUSTSTORE);
+        setSystemProperty("javax.net.ssl.trustStorePassword", TRUSTSTORE_PASSWORD);
+        setSystemProperty("javax.net.debug", "ssl");
+    }
+}
diff --git a/java/systests/src/main/java/org/apache/qpid/server/security/auth/manager/MultipleAuthenticationManagersTest.java b/java/systests/src/main/java/org/apache/qpid/server/security/auth/manager/MultipleAuthenticationManagersTest.java
index 858b32c24c..f41f1159ab 100644
--- a/java/systests/src/main/java/org/apache/qpid/server/security/auth/manager/MultipleAuthenticationManagersTest.java
+++ b/java/systests/src/main/java/org/apache/qpid/server/security/auth/manager/MultipleAuthenticationManagersTest.java
@@ -20,28 +20,44 @@
  */
 package org.apache.qpid.server.security.auth.manager;
 
+import static org.apache.qpid.test.utils.TestSSLConstants.KEYSTORE;
+import static org.apache.qpid.test.utils.TestSSLConstants.KEYSTORE_PASSWORD;
+import static org.apache.qpid.test.utils.TestSSLConstants.TRUSTSTORE;
+import static org.apache.qpid.test.utils.TestSSLConstants.TRUSTSTORE_PASSWORD;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+
 import javax.jms.Connection;
 import javax.jms.JMSException;
 import org.apache.qpid.AMQException;
 import org.apache.qpid.client.AMQConnection;
+import org.apache.qpid.server.model.AuthenticationProvider;
+import org.apache.qpid.server.model.Port;
+import org.apache.qpid.server.model.Transport;
+import org.apache.qpid.server.plugin.AuthenticationManagerFactory;
 import org.apache.qpid.test.utils.QpidBrokerTestCase;
+import org.apache.qpid.test.utils.TestBrokerConfiguration;
 
 public class MultipleAuthenticationManagersTest extends QpidBrokerTestCase
 {
-    private static final String KEYSTORE = "test-profiles/test_resources/ssl/java_client_keystore.jks";
-    private static final String KEYSTORE_PASSWORD = "password";
-    private static final String TRUSTSTORE = "test-profiles/test_resources/ssl/java_client_truststore.jks";
-    private static final String TRUSTSTORE_PASSWORD = "password";
-
     @Override
     protected void setUp() throws Exception
     {
-        setConfigurationProperty("connector.ssl.enabled", "true");
-        setConfigurationProperty("connector.ssl.sslOnly", "false");
-        setConfigurationProperty("security.anonymous-auth-manager", "");
-        setConfigurationProperty("security.default-auth-manager", "PrincipalDatabaseAuthenticationManager");
-        setConfigurationProperty("security.port-mappings.port-mapping.port", String.valueOf(QpidBrokerTestCase.DEFAULT_SSL_PORT));
-        setConfigurationProperty("security.port-mappings.port-mapping.auth-manager", "AnonymousAuthenticationManager");
+        TestBrokerConfiguration config = getBrokerConfiguration();
+
+        Map externalAuthProviderAttributes = new HashMap();
+        externalAuthProviderAttributes.put(AuthenticationManagerFactory.ATTRIBUTE_TYPE, AnonymousAuthenticationManagerFactory.PROVIDER_TYPE);
+        externalAuthProviderAttributes.put(AuthenticationProvider.NAME, TestBrokerConfiguration.ENTRY_NAME_ANONYMOUS_PROVIDER);
+        config.addAuthenticationProviderConfiguration(externalAuthProviderAttributes);
+
+        Map sslPortAttributes = new HashMap();
+        sslPortAttributes.put(Port.TRANSPORTS, Collections.singleton(Transport.SSL));
+        sslPortAttributes.put(Port.PORT, DEFAULT_SSL_PORT);
+        sslPortAttributes.put(Port.NAME, TestBrokerConfiguration.ENTRY_NAME_SSL_PORT);
+        sslPortAttributes.put(Port.AUTHENTICATION_MANAGER, TestBrokerConfiguration.ENTRY_NAME_ANONYMOUS_PROVIDER);
+        config.addPortConfiguration(sslPortAttributes);
 
         // set the ssl system properties
         setSystemProperty("javax.net.ssl.keyStore", KEYSTORE);
diff --git a/java/systests/src/main/java/org/apache/qpid/server/security/firewall/FirewallConfigTest.java b/java/systests/src/main/java/org/apache/qpid/server/security/firewall/FirewallConfigTest.java
deleted file mode 100644
index f5adf815aa..0000000000
--- a/java/systests/src/main/java/org/apache/qpid/server/security/firewall/FirewallConfigTest.java
+++ /dev/null
@@ -1,283 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- * 
- *   http://www.apache.org/licenses/LICENSE-2.0
- * 
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.qpid.server.security.firewall;
-
-import org.apache.qpid.client.AMQConnectionURL;
-import org.apache.qpid.test.utils.QpidBrokerTestCase;
-
-import javax.jms.Connection;
-import javax.jms.JMSException;
-import java.io.File;
-import java.io.FileWriter;
-import java.io.IOException;
-import java.net.InetAddress;
-import java.net.UnknownHostException;
-
-public class FirewallConfigTest extends QpidBrokerTestCase 
-{
-    private File _tmpConfig, _tmpVirtualhosts;
-    private String _ipAddressOfBrokerHost;
-
-    @Override
-    protected void setUp() throws Exception
-    {
-        // Setup initial config file.
-        _configFile = new File("build/etc/config-systests-firewall.xml");
-        
-        // Setup temporary config file
-        _tmpConfig = File.createTempFile("config-systests-firewall", ".xml");
-        setSystemProperty("QPID_FIREWALL_CONFIG_SETTINGS", _tmpConfig.getAbsolutePath());
-        _tmpConfig.deleteOnExit();
-
-        // Setup temporary virtualhosts file
-        _tmpVirtualhosts = File.createTempFile("virtualhosts-systests-firewall", ".xml");
-        setSystemProperty("QPID_FIREWALL_VIRTUALHOSTS_SETTINGS", _tmpVirtualhosts.getAbsolutePath());
-        _tmpVirtualhosts.deleteOnExit();
-
-        _ipAddressOfBrokerHost = getIpAddressOfBrokerHost();
-    }
-
-    private void writeFirewallFile(boolean allow, boolean inVhost) throws IOException
-    {
-        FileWriter out = new FileWriter(inVhost ? _tmpVirtualhosts : _tmpConfig);
-        if (inVhost) 
-        {
-            out.write("");
-        }
-        else
-        {
-            out.write("");
-        }
-        out.write("");
-        out.write("");
-        out.write("");
-        if (inVhost)
-        {
-            out.write("");
-        }
-        else
-        {
-            out.write("");
-        }
-        out.close();
-    }
-
-    public void testVhostAllowBrokerDeny() throws Exception
-    {
-
-        _configFile = new File("build/etc/config-systests-firewall-2.xml");
-        
-        super.setUp();
-        try 
-        {
-            //Try to get a connection to the 'test2' vhost
-            //This is expected to succeed as it is allowed at the vhost level
-            getConnection(new AMQConnectionURL("amqp://guest:guest@clientid/test2?brokerlist='" + getBroker() + "'"));
-        } 
-        catch (JMSException e)
-        {
-            e.getLinkedException().printStackTrace();
-            fail("The connection was expected to succeed: " + e.getMessage());
-        }
-
-        try 
-        {
-            //Try to get a connection to the 'test' vhost
-            //This is expected to fail as it is denied at the broker level
-            getConnection();
-            fail("We expected the connection to fail");
-        } 
-        catch (JMSException e)
-        {
-            //ignore
-        }
-    }
-    
-    public void testVhostDenyBrokerAllow() throws Exception
-    {
-        _configFile = new File("build/etc/config-systests-firewall-3.xml");
-        
-        super.setUp();
-        try 
-        {
-            //Try to get a connection to the 'test2' vhost
-            //This is expected to fail as it is denied at the vhost level
-            getConnection(new AMQConnectionURL("amqp://guest:guest@clientid/test2?brokerlist='" + getBroker() + "'"));
-            fail("The connection was expected to fail");
-        } 
-        catch (JMSException e)
-        {
-            //ignore
-        }
-
-        try 
-        {
-            //Try to get a connection to the 'test' vhost
-            //This is expected to succeed as it is allowed at the broker level
-            getConnection();
-        } 
-        catch (JMSException e)
-        {
-            e.getLinkedException().printStackTrace();
-            fail("The connection was expected to succeed: " + e.getMessage());
-        }
-    }
- 
-    public void testDenyOnRestart() throws Exception
-    {
-        testDeny(false, new Runnable() {
-
-            public void run()
-            {
-                try
-                {
-                    restartBroker();
-                } catch (Exception e)
-                {
-                    fail(e.getMessage());
-                }
-            }
-        });
-    }
-    
-    public void testDenyOnRestartInVhost() throws Exception
-    {
-        testDeny(true, new Runnable() {
-
-            public void run()
-            {
-                try
-                {
-                    restartBroker();
-                } catch (Exception e)
-                {
-                    fail(e.getMessage());
-                }
-            }
-        });
-    }
-    
-    public void testAllowOnReloadInVhost() throws Exception
-    {
-        testFirewall(false, true, new Runnable() {
-
-            public void run()
-            {
-                try
-                {
-                    reloadBrokerSecurityConfig();
-                } catch (Exception e)
-                {
-                    fail(e.getMessage());
-                }
-            }
-        });
-    }
-    
-    public void testDenyOnReload() throws Exception
-    {
-        testDeny(false, new Runnable() {
-
-            public void run()
-            {
-                try
-                {
-                    reloadBrokerSecurityConfig();
-                } catch (Exception e)
-                {
-                    fail(e.getMessage());
-                }
-            }
-        }
-        );
-    }
-
-    public void testDenyOnReloadInVhost() throws Exception
-    {
-        testDeny(true, new Runnable() {
-
-            public void run()
-            {
-                try
-                {
-                    reloadBrokerSecurityConfig();
-                } catch (Exception e)
-                {
-                   fail(e.getMessage());
-                }
-            }
-        }
-        );
-       
-    }
-
-    private void testDeny(boolean inVhost, Runnable restartOrReload) throws Exception
-    {
-        testFirewall(true, inVhost, restartOrReload);
-    }
-
-    /*
-     * Check we can get a connection
-     */
-    private boolean checkConnection() throws Exception
-    {
-        Exception exception  = null;
-        Connection conn = null;
-        try 
-        {
-            conn = getConnection();
-        } 
-        catch (JMSException e)
-        {
-            exception = e;
-        }
-        
-        return conn != null;
-    }
-
-    private void testFirewall(boolean initial, boolean inVhost, Runnable restartOrReload) throws Exception
-    {
-        
-        writeFirewallFile(initial, inVhost);
-        setConfigurationProperty("management.enabled", String.valueOf(true));
-        super.setUp();
-
-        assertEquals("Initial connection check failed", initial, checkConnection());
-
-        // Reload changed firewall file after restart or reload
-        writeFirewallFile(!initial, inVhost);
-        restartOrReload.run();
-        
-        assertEquals("Second connection check failed", !initial, checkConnection());
-    }
-
-    private String getIpAddressOfBrokerHost()
-    {
-        String brokerHost = getBroker().getHost();
-        try
-        {
-            return InetAddress.getByName(brokerHost).getHostAddress();
-        }
-        catch (UnknownHostException e)
-        {
-            throw new RuntimeException("Could not determine IP address of host : " + brokerHost, e);
-        }
-
-    }
-}
diff --git a/java/systests/src/main/java/org/apache/qpid/server/stats/StatisticsReportingTest.java b/java/systests/src/main/java/org/apache/qpid/server/stats/StatisticsReportingTest.java
index c38fcd9199..6d53896371 100644
--- a/java/systests/src/main/java/org/apache/qpid/server/stats/StatisticsReportingTest.java
+++ b/java/systests/src/main/java/org/apache/qpid/server/stats/StatisticsReportingTest.java
@@ -27,10 +27,13 @@ import org.apache.qpid.client.AMQQueue;
 import org.apache.qpid.client.AMQSession;
 import org.apache.qpid.exchange.ExchangeDefaults;
 import org.apache.qpid.framing.AMQShortString;
+import org.apache.qpid.server.model.Broker;
 import org.apache.qpid.test.utils.QpidBrokerTestCase;
+import org.apache.qpid.test.utils.TestBrokerConfiguration;
 import org.apache.qpid.util.LogMonitor;
 
 import java.util.List;
+import java.util.Map;
 
 import javax.jms.Connection;
 import javax.jms.Destination;
@@ -45,46 +48,55 @@ import javax.jms.TextMessage;
  */
 public class StatisticsReportingTest extends QpidBrokerTestCase
 {
+    private static final String VHOST_NAME1 = "vhost1";
+    private static final String VHOST_NAME2 = "vhost2";
+    private static final String VHOST_NAME3 = "vhost3";
+    private static long STATISTICS_REPORTING_PERIOD_IN_SECONDS = 10l;
+
     protected LogMonitor _monitor;
     protected static final String USER = "admin";
 
-    protected Connection _test, _dev, _local;
+    protected Connection _conToVhost1, _conToVhost2, _conToVhost3;
     protected String _queueName = "statistics";
     protected Destination _queue;
     protected String _brokerUrl;
+    private long _startTestTime;
 
     @Override
     public void setUp() throws Exception
     {
-        setConfigurationProperty("statistics.generation.broker", "true");
-        setConfigurationProperty("statistics.generation.virtualhosts", "true");
+        createTestVirtualHost(0, VHOST_NAME1);
+        createTestVirtualHost(0, VHOST_NAME2);
+        createTestVirtualHost(0, VHOST_NAME3);
 
         if (getName().equals("testEnabledStatisticsReporting"))
         {
-            setConfigurationProperty("statistics.reporting.period", "10");
+            TestBrokerConfiguration config = getBrokerConfiguration();
+            config.removeObjectConfiguration(TestBrokerConfiguration.ENTRY_NAME_VIRTUAL_HOST);
+            config.setBrokerAttribute(Broker.STATISTICS_REPORTING_PERIOD, STATISTICS_REPORTING_PERIOD_IN_SECONDS);
         }
 
         _monitor = new LogMonitor(_outputFile);
+        _startTestTime = System.currentTimeMillis();
 
         super.setUp();
 
         _brokerUrl = getBroker().toString();
-        _test = new AMQConnection(_brokerUrl, USER, USER, "clientid", "test");
-        _dev = new AMQConnection(_brokerUrl, USER, USER, "clientid", "development");
-        _local = new AMQConnection(_brokerUrl, USER, USER, "clientid", "localhost");
-
-        _test.start();
-        _dev.start();
-        _local.start();
+        _conToVhost1 = new AMQConnection(_brokerUrl, USER, USER, "clientid", VHOST_NAME1);
+        _conToVhost2 = new AMQConnection(_brokerUrl, USER, USER, "clientid", VHOST_NAME2);
+        _conToVhost3 = new AMQConnection(_brokerUrl, USER, USER, "clientid", VHOST_NAME3);
 
+        _conToVhost1.start();
+        _conToVhost2.start();
+        _conToVhost3.start();
     }
 
     @Override
     public void tearDown() throws Exception
     {
-        _test.close();
-        _dev.close();
-        _local.close();
+        _conToVhost1.close();
+        _conToVhost2.close();
+        _conToVhost3.close();
 
         super.tearDown();
     }
@@ -94,21 +106,30 @@ public class StatisticsReportingTest extends QpidBrokerTestCase
      */
     public void testEnabledStatisticsReporting() throws Exception
     {
-        sendUsing(_test, 10, 100);
-        sendUsing(_dev, 20, 100);
-        sendUsing(_local, 15, 100);
-
-        Thread.sleep(10 * 1000); // 15s
-
-        List brokerStatsData = _monitor.findMatches("BRK-1008");
-        List brokerStatsMessages = _monitor.findMatches("BRK-1009");
-        List vhostStatsData = _monitor.findMatches("VHT-1003");
-        List vhostStatsMessages = _monitor.findMatches("VHT-1004");
-
-        assertEquals("Incorrect number of broker data stats log messages", 2, brokerStatsData.size());
-        assertEquals("Incorrect number of broker message stats log messages", 2, brokerStatsMessages.size());
-        assertEquals("Incorrect number of virtualhost data stats log messages", 6, vhostStatsData.size());
-        assertEquals("Incorrect number of virtualhost message stats log messages", 6, vhostStatsMessages.size());
+        sendUsing(_conToVhost1, 10, 100);
+        sendUsing(_conToVhost2, 20, 100);
+        sendUsing(_conToVhost3, 15, 100);
+
+        Thread.sleep(STATISTICS_REPORTING_PERIOD_IN_SECONDS * 1000);
+
+        Map> brokerStatsData = _monitor.findMatches("BRK-1008", "BRK-1009", "VHT-1003", "VHT-1004");
+        long endTestTime = System.currentTimeMillis();
+
+        int maxNumberOfReports = (int)((endTestTime - _startTestTime)/STATISTICS_REPORTING_PERIOD_IN_SECONDS);
+
+        int brk1008LinesNumber = brokerStatsData.get("BRK-1008").size();
+        int brk1009LinesNumber = brokerStatsData.get("BRK-1009").size();
+        int vht1003LinesNumber = brokerStatsData.get("VHT-1003").size();
+        int vht1004LinesNumber = brokerStatsData.get("VHT-1004").size();
+
+        assertTrue("Incorrect number of broker data stats log messages:" + brk1008LinesNumber, 2 <= brk1008LinesNumber
+                && brk1008LinesNumber <= maxNumberOfReports * 2);
+        assertTrue("Incorrect number of broker message stats log messages:" + brk1009LinesNumber, 2 <= brk1009LinesNumber
+                && brk1009LinesNumber <= maxNumberOfReports * 2);
+        assertTrue("Incorrect number of virtualhost data stats log messages:" + vht1003LinesNumber, 6 <= vht1003LinesNumber
+                && vht1003LinesNumber <= maxNumberOfReports * 6);
+        assertTrue("Incorrect number of virtualhost message stats log messages: " + vht1004LinesNumber, 6 <= vht1004LinesNumber
+                && vht1004LinesNumber <= maxNumberOfReports * 6);
     }
 
     /**
@@ -116,9 +137,9 @@ public class StatisticsReportingTest extends QpidBrokerTestCase
      */
     public void testNotEnabledStatisticsReporting() throws Exception
     {
-        sendUsing(_test, 10, 100);
-        sendUsing(_dev, 20, 100);
-        sendUsing(_local, 15, 100);
+        sendUsing(_conToVhost1, 10, 100);
+        sendUsing(_conToVhost2, 20, 100);
+        sendUsing(_conToVhost3, 15, 100);
 
         Thread.sleep(10 * 1000); // 15s
 
@@ -135,7 +156,7 @@ public class StatisticsReportingTest extends QpidBrokerTestCase
 
     private void sendUsing(Connection con, int number, int size) throws Exception
     {
-        Session session = con.createSession(false, Session.AUTO_ACKNOWLEDGE);
+        Session session = con.createSession(true, Session.SESSION_TRANSACTED);
         createQueue(session);
         MessageProducer producer = session.createProducer(_queue);
         String content = new String(new byte[size]);
@@ -144,6 +165,8 @@ public class StatisticsReportingTest extends QpidBrokerTestCase
         {
             producer.send(msg);
         }
+        session.commit();
+        session.close();
     }
 
     private void createQueue(Session session) throws AMQException, JMSException
diff --git a/java/systests/src/main/java/org/apache/qpid/server/store/SlowMessageStore.java b/java/systests/src/main/java/org/apache/qpid/server/store/SlowMessageStore.java
index 9db04b64b3..6d38004451 100644
--- a/java/systests/src/main/java/org/apache/qpid/server/store/SlowMessageStore.java
+++ b/java/systests/src/main/java/org/apache/qpid/server/store/SlowMessageStore.java
@@ -27,8 +27,6 @@ import org.apache.qpid.AMQStoreException;
 import org.apache.qpid.framing.FieldTable;
 import org.apache.qpid.server.binding.Binding;
 import org.apache.qpid.server.exchange.Exchange;
-import org.apache.qpid.server.federation.Bridge;
-import org.apache.qpid.server.federation.BrokerLink;
 import org.apache.qpid.server.message.EnqueableMessage;
 import org.apache.qpid.server.message.ServerMessage;
 import org.apache.qpid.server.queue.AMQQueue;
@@ -322,35 +320,6 @@ public class SlowMessageStore implements MessageStore
         doPostDelay("updateQueue");
     }
 
-
-    public void createBrokerLink(final BrokerLink link) throws AMQStoreException
-    {
-        doPreDelay("createBrokerLink");
-        _durableConfigurationStore.createBrokerLink(link);
-        doPostDelay("createBrokerLink");
-    }
-
-    public void deleteBrokerLink(final BrokerLink link) throws AMQStoreException
-    {
-        doPreDelay("deleteBrokerLink");
-        _durableConfigurationStore.deleteBrokerLink(link);
-        doPostDelay("deleteBrokerLink");
-    }
-
-    public void createBridge(final Bridge bridge) throws AMQStoreException
-    {
-        doPreDelay("createBridge");
-        _durableConfigurationStore.createBridge(bridge);
-        doPostDelay("createBridge");
-    }
-
-    public void deleteBridge(final Bridge bridge) throws AMQStoreException
-    {
-        doPreDelay("deleteBridge");
-        _durableConfigurationStore.deleteBridge(bridge);
-        doPostDelay("deleteBridge");
-    }
-
     @Override
     public void activate() throws Exception
     {
diff --git a/java/systests/src/main/java/org/apache/qpid/server/store/StoreOverfullTest.java b/java/systests/src/main/java/org/apache/qpid/server/store/StoreOverfullTest.java
index 9fb1db3a4f..61ca6d9c28 100644
--- a/java/systests/src/main/java/org/apache/qpid/server/store/StoreOverfullTest.java
+++ b/java/systests/src/main/java/org/apache/qpid/server/store/StoreOverfullTest.java
@@ -60,9 +60,9 @@ public class StoreOverfullTest extends QpidBrokerTestCase
 
     public void setUp() throws Exception
     {
-        setConfigurationProperty("virtualhosts.virtualhost.test.store.class", QuotaMessageStore.class.getName());
-        setConfigurationProperty("virtualhosts.virtualhost.test.store.overfull-size", String.valueOf(OVERFULL_SIZE));
-        setConfigurationProperty("virtualhosts.virtualhost.test.store.underfull-size", String.valueOf(UNDERFULL_SIZE));
+        setVirtualHostConfigurationProperty("virtualhosts.virtualhost.test.store.class", QuotaMessageStore.class.getName());
+        setVirtualHostConfigurationProperty("virtualhosts.virtualhost.test.store.overfull-size", String.valueOf(OVERFULL_SIZE));
+        setVirtualHostConfigurationProperty("virtualhosts.virtualhost.test.store.underfull-size", String.valueOf(UNDERFULL_SIZE));
 
         super.setUp();
 
diff --git a/java/systests/src/main/java/org/apache/qpid/systest/GlobalQueuesTest.java b/java/systests/src/main/java/org/apache/qpid/systest/GlobalQueuesTest.java
deleted file mode 100644
index 9ff143daf3..0000000000
--- a/java/systests/src/main/java/org/apache/qpid/systest/GlobalQueuesTest.java
+++ /dev/null
@@ -1,223 +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.systest;
-
-import org.apache.commons.configuration.ConfigurationException;
-
-import javax.jms.Session;
-import javax.naming.NamingException;
-import java.io.IOException;
-
-/**
- * QPID-1447 : Add slow consumer detection and disconnection.
- *
- * Slow consumers should on a topic should expect to receive a
- * 506 : Resource Error if the hit a predefined threshold.
- */
-public class GlobalQueuesTest extends TestingBaseCase
-{
-
-    protected String CONFIG_SECTION = ".queues";
-
-    /**
-     *  Queue Configuration
-
-     
-     
-     4235264
-
-     
-     600000
-
-     
-     50
-
-     
-     
-     TopicDelete
-     
-     
-     
-     
-     
-
-     */
-
-
-    /**
-     *  VirtualHost Plugin Configuration
-
-     
-     1
-     MINUTES
-     
-
-     */
-
-    public void setConfig(String property, String value, boolean deleteDurable) throws NamingException, IOException, ConfigurationException
-    {
-        setProperty(CONFIG_SECTION + ".slow-consumer-detection." +
-                    "policy.name", "TopicDelete");
-
-        setProperty(CONFIG_SECTION + ".slow-consumer-detection." +
-                    property, value);
-
-        if (deleteDurable)
-        {
-            setProperty(CONFIG_SECTION + ".slow-consumer-detection." +
-                        "policy.topicdelete.delete-persistent", "");
-        }
-    }
-
-    /**
-     * Test that setting messageCount takes affect on topics
-     *
-     * We send 10 messages and disconnect at 9
-     *
-     * @throws Exception
-     */
-    public void testTopicConsumerMessageCount() throws Exception
-    {
-        MAX_QUEUE_MESSAGE_COUNT = 10;
-
-        setConfig("messageCount", String.valueOf(MAX_QUEUE_MESSAGE_COUNT - 1), false);
-
-        //Start the broker
-        startBroker();
-
-        topicConsumer(Session.AUTO_ACKNOWLEDGE, false);
-    }
-
-    /**
-     * Test that setting depth has an effect on topics
-     *
-     * Sets the message size for the test
-     * Sets the depth to be 9 * the depth
-     * Ensure that sending 10 messages causes the disconnection
-     *
-     * @throws Exception
-     */
-    public void testTopicConsumerMessageSize() throws Exception
-    {
-        MAX_QUEUE_MESSAGE_COUNT = 10;
-
-        setConfig("depth", String.valueOf(MESSAGE_SIZE * 9), false);
-
-        //Start the broker
-        startBroker();
-
-        setMessageSize(MESSAGE_SIZE);
-
-        topicConsumer(Session.AUTO_ACKNOWLEDGE, false);
-    }
-
-    /**
-     * Test that setting messageAge has an effect on topics
-     *
-     * Sets the messageAge to be half the disconnection wait timeout
-     * Send 10 messages and then ensure that we get disconnected as we will
-     * wait for the full timeout.
-     *
-     * @throws Exception
-     */
-    public void testTopicConsumerMessageAge() throws Exception
-    {
-        MAX_QUEUE_MESSAGE_COUNT = 10;
-
-        setConfig("messageAge", String.valueOf(DISCONNECTION_WAIT / 2), false);
-
-        //Start the broker
-        startBroker();
-
-        topicConsumer(Session.AUTO_ACKNOWLEDGE, false);
-    }
-
-    /**
-     * Test that setting messageCount takes affect on a durable Consumer
-     *
-     * Ensure we set the delete-persistent option
-     *
-     * We send 10 messages and disconnect at 9
-     *
-     * @throws Exception
-     */
-
-    public void testTopicDurableConsumerMessageCount() throws Exception
-    {
-        MAX_QUEUE_MESSAGE_COUNT = 10;
-
-        setConfig("messageCount", String.valueOf(MAX_QUEUE_MESSAGE_COUNT - 1), true);
-
-        //Start the broker
-        startBroker();
-
-        topicConsumer(Session.AUTO_ACKNOWLEDGE, true);
-    }
-
-    /**
-     * Test that setting depth has an effect on durable consumer topics
-     *
-     * Ensure we set the delete-persistent option
-     *
-     * Sets the message size for the test
-     * Sets the depth to be 9 * the depth
-     * Ensure that sending 10 messages causes the disconnection
-     *
-     * @throws Exception
-     */
-    public void testTopicDurableConsumerMessageSize() throws Exception
-    {
-        MAX_QUEUE_MESSAGE_COUNT = 10;
-
-        setConfig("depth", String.valueOf(MESSAGE_SIZE * 9), true);
-
-        //Start the broker
-        startBroker();
-
-        setMessageSize(MESSAGE_SIZE);
-
-        topicConsumer(Session.AUTO_ACKNOWLEDGE, true);
-    }
-
-    /**
-     * Test that setting messageAge has an effect on topics
-     *
-     * Ensure we set the delete-persistent option
-     *
-     * Sets the messageAge to be 1/5 the disconnection wait timeout (or 1sec)
-     * Send 10 messages and then ensure that we get disconnected as we will
-     * wait for the full timeout.
-     *
-     * @throws Exception
-     */
-    public void testTopicDurableConsumerMessageAge() throws Exception
-    {
-        MAX_QUEUE_MESSAGE_COUNT = 10;
-
-        setConfig("messageAge", String.valueOf(DISCONNECTION_WAIT / 5), true);
-
-        //Start the broker
-        startBroker();
-
-        topicConsumer(Session.AUTO_ACKNOWLEDGE, true);
-    }
-
-}
diff --git a/java/systests/src/main/java/org/apache/qpid/systest/GlobalTopicsTest.java b/java/systests/src/main/java/org/apache/qpid/systest/GlobalTopicsTest.java
deleted file mode 100644
index 6297478883..0000000000
--- a/java/systests/src/main/java/org/apache/qpid/systest/GlobalTopicsTest.java
+++ /dev/null
@@ -1,31 +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.systest;
-
-public class GlobalTopicsTest extends GlobalQueuesTest
-{
-    @Override
-    public void setUp() throws Exception
-    {
-        CONFIG_SECTION = ".topics";
-        super.setUp();
-    }
-}
diff --git a/java/systests/src/main/java/org/apache/qpid/systest/MergeConfigurationTest.java b/java/systests/src/main/java/org/apache/qpid/systest/MergeConfigurationTest.java
deleted file mode 100644
index 993d71ea34..0000000000
--- a/java/systests/src/main/java/org/apache/qpid/systest/MergeConfigurationTest.java
+++ /dev/null
@@ -1,109 +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.systest;
-
-import org.apache.commons.configuration.ConfigurationException;
-
-import javax.jms.Session;
-import javax.naming.NamingException;
-import java.io.IOException;
-
-public class MergeConfigurationTest extends TestingBaseCase
-{
-
-    protected int topicCount = 0;
-
-
-    public void configureTopic(String topic, int msgCount) throws NamingException, IOException, ConfigurationException
-    {
-
-        setProperty(".topics.topic("+topicCount+").name", topic);
-        setProperty(".topics.topic("+topicCount+").slow-consumer-detection.messageCount", String.valueOf(msgCount));
-        setProperty(".topics.topic("+topicCount+").slow-consumer-detection.policy.name", "TopicDelete");
-        topicCount++;
-    }
-
-
-    /**
-     * Test that setting messageCount takes affect on topics
-     *
-     * We send 10 messages and disconnect at 9
-     *
-     * @throws Exception
-     */
-    public void testTopicConsumerMessageCount() throws Exception
-    {
-        MAX_QUEUE_MESSAGE_COUNT = 10;
-
-        configureTopic(getName(), (MAX_QUEUE_MESSAGE_COUNT * 4) - 1);
-
-        //Configure topic as a subscription
-        setProperty(".topics.topic("+topicCount+").subscriptionName", "clientid:"+getTestQueueName());
-        configureTopic(getName(), (MAX_QUEUE_MESSAGE_COUNT - 1));
-
-
-
-        //Start the broker
-        startBroker();
-
-        topicConsumer(Session.AUTO_ACKNOWLEDGE, true);
-    }
-
-
-//
-//    public void testMerge() throws ConfigurationException, AMQException
-//    {
-//
-//        AMQQueue queue = AMQQueueFactory.createAMQQueueImpl(new AMQShortString(getName()+":stockSubscription"), false, new AMQShortString("testowner"),
-//                                                    false, false, _virtualHost, null);
-//
-//        _virtualHost.getQueueRegistry().registerQueue(queue);
-//        Exchange defaultExchange = _virtualHost.getExchangeRegistry().getDefaultExchange();
-//        _virtualHost.getBindingFactory().addBinding(getName(), queue, defaultExchange, null);
-//
-//
-//        Exchange topicExchange = _virtualHost.getExchangeRegistry().getExchange(ExchangeDefaults.TOPIC_EXCHANGE_NAME);
-//        _virtualHost.getBindingFactory().addBinding("stocks.nyse.orcl", queue, topicExchange, null);
-//
-//        TopicConfig config = queue.getConfiguration().getConfiguration(TopicConfig.class.getName());
-//
-//        assertNotNull("Queue should have topic configuration bound to it.", config);
-//        assertEquals("Configuration name not correct", getName() + ":stockSubscription", config.getSubscriptionName());
-//
-//        ConfigurationPlugin scdConfig = queue.getConfiguration().getConfiguration(SlowConsumerDetectionQueueConfiguration.class.getName());
-//        if (scdConfig instanceof org.apache.qpid.server.configuration.plugin.SlowConsumerDetectionQueueConfiguration)
-//        {
-//            System.err.println("********************** scd is a SlowConsumerDetectionQueueConfiguration.");
-//        }
-//        else
-//        {
-//            System.err.println("********************** Test SCD "+SlowConsumerDetectionQueueConfiguration.class.getClassLoader());
-//            System.err.println("********************** Broker SCD "+scdConfig.getClass().getClassLoader());
-//                 System.err.println("********************** Broker SCD "+scdConfig.getClass().isAssignableFrom(SlowConsumerDetectionQueueConfiguration.class));
-//            System.err.println("********************** is a "+scdConfig.getClass());
-//        }
-//
-//        assertNotNull("Queue should have scd configuration bound to it.", scdConfig);
-//        assertEquals("MessageCount is not correct", 10 , ((SlowConsumerDetectionQueueConfiguration)scdConfig).getMessageCount());
-//        assertEquals("Policy is not correct", TopicDeletePolicy.class.getName() , ((SlowConsumerDetectionQueueConfiguration)scdConfig).getPolicy().getClass().getName());
-//    }
-
-}
diff --git a/java/systests/src/main/java/org/apache/qpid/systest/SubscriptionTest.java b/java/systests/src/main/java/org/apache/qpid/systest/SubscriptionTest.java
deleted file mode 100644
index 9e9375fd44..0000000000
--- a/java/systests/src/main/java/org/apache/qpid/systest/SubscriptionTest.java
+++ /dev/null
@@ -1,146 +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.systest;
-
-import org.apache.commons.configuration.ConfigurationException;
-
-import javax.jms.Session;
-import javax.naming.NamingException;
-import java.io.IOException;
-
-/**
- * Test SCD when configured with Subscription details.
- *
- * We run the subscription based tests here to validate that the
- * subscriptionname value is correctly associated with the subscription.
- *
- *
- */
-public class SubscriptionTest extends TestingBaseCase
-{
-    private int _count=0;
-    protected String CONFIG_SECTION = ".topics.topic";
-
-    /**
-     * Add configuration for the queue that relates just to this test.
-     * We use the getTestQueueName() as our subscription. To ensure the
-     * config sections do not overlap we identify each section with a _count
-     * value.
-     *
-     * This would allow each test to configure more than one section.
-     *
-     * @param property to set
-     * @param value the value to set
-     * @param deleteDurable should deleteDurable be set.
-     * @throws NamingException
-     * @throws IOException
-     * @throws ConfigurationException
-     */
-    public void setConfig(String property, String value, boolean deleteDurable) throws NamingException, IOException, ConfigurationException
-    {
-        setProperty(CONFIG_SECTION + "("+_count+").subscriptionName", "clientid:"+getTestQueueName());
-
-        setProperty(CONFIG_SECTION + "("+_count+").slow-consumer-detection." +
-                    "policy.name", "TopicDelete");
-
-        setProperty(CONFIG_SECTION + "("+_count+").slow-consumer-detection." +
-                    property, value);
-
-        if (deleteDurable)
-        {
-            setProperty(CONFIG_SECTION + "("+_count+").slow-consumer-detection." +
-                        "policy.topicdelete.delete-persistent", "");
-        }
-        _count++;
-    }
-
-
-    /**
-     * Test that setting messageCount takes affect on a durable Consumer
-     *
-     * Ensure we set the delete-persistent option
-     *
-     * We send 10 messages and disconnect at 9
-     *
-     * @throws Exception
-     */
-
-    public void testTopicDurableConsumerMessageCount() throws Exception
-    {
-        MAX_QUEUE_MESSAGE_COUNT = 10;
-
-        setConfig("messageCount", String.valueOf(MAX_QUEUE_MESSAGE_COUNT - 1), true);
-
-        //Start the broker
-        startBroker();
-
-        topicConsumer(Session.AUTO_ACKNOWLEDGE, true);
-    }
-
-    /**
-     * Test that setting depth has an effect on durable consumer topics
-     *
-     * Ensure we set the delete-persistent option
-     *
-     * Sets the message size for the test
-     * Sets the depth to be 9 * the depth
-     * Ensure that sending 10 messages causes the disconnection
-     *
-     * @throws Exception
-     */
-    public void testTopicDurableConsumerMessageSize() throws Exception
-    {
-        MAX_QUEUE_MESSAGE_COUNT = 10;
-
-        setConfig("depth", String.valueOf(MESSAGE_SIZE * 9), true);
-
-        //Start the broker
-        startBroker();
-
-        setMessageSize(MESSAGE_SIZE);
-
-        topicConsumer(Session.AUTO_ACKNOWLEDGE, true);
-    }
-
-    /**
-     * Test that setting messageAge has an effect on topics
-     *
-     * Ensure we set the delete-persistent option
-     *
-     * Sets the messageAge to be 1/5 the disconnection wait timeout (or 1sec)
-     * Send 10 messages and then ensure that we get disconnected as we will
-     * wait for the full timeout.
-     *
-     * @throws Exception
-     */
-    public void testTopicDurableConsumerMessageAge() throws Exception
-    {
-        MAX_QUEUE_MESSAGE_COUNT = 10;
-
-        setConfig("messageAge", String.valueOf(DISCONNECTION_WAIT / 5), true);
-
-        //Start the broker
-        startBroker();
-
-        topicConsumer(Session.AUTO_ACKNOWLEDGE, true);
-    }
-
-}
diff --git a/java/systests/src/main/java/org/apache/qpid/systest/TestingBaseCase.java b/java/systests/src/main/java/org/apache/qpid/systest/TestingBaseCase.java
deleted file mode 100644
index 86c9462fc9..0000000000
--- a/java/systests/src/main/java/org/apache/qpid/systest/TestingBaseCase.java
+++ /dev/null
@@ -1,240 +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.systest;
-
-import org.apache.commons.configuration.ConfigurationException;
-
-import org.apache.qpid.AMQException;
-import org.apache.qpid.jms.ConnectionListener;
-import org.apache.qpid.protocol.AMQConstant;
-import org.apache.qpid.test.utils.QpidBrokerTestCase;
-
-import javax.jms.Connection;
-import javax.jms.Destination;
-import javax.jms.ExceptionListener;
-import javax.jms.JMSException;
-import javax.jms.MessageConsumer;
-import javax.jms.MessageProducer;
-import javax.jms.Session;
-import javax.jms.Topic;
-import javax.naming.NamingException;
-import java.io.IOException;
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.TimeUnit;
-
-public class TestingBaseCase extends QpidBrokerTestCase implements ExceptionListener, ConnectionListener
-{
-
-    private Topic _destination;
-    protected CountDownLatch _disconnectionLatch = new CountDownLatch(1);
-    protected int MAX_QUEUE_MESSAGE_COUNT;
-    protected int MESSAGE_SIZE = DEFAULT_MESSAGE_SIZE;
-
-    private Thread _publisher;
-    protected static final long DISCONNECTION_WAIT = 5;
-    protected Exception _publisherError = null;
-    protected JMSException _connectionException = null;
-    private static final long JOIN_WAIT = 5000;
-
-    @Override
-    public void setUp() throws Exception
-    {
-
-        setConfigurationProperty("virtualhosts.virtualhost."
-                                 + getConnectionURL().getVirtualHost().substring(1) +
-                                 ".slow-consumer-detection.delay", "1");
-
-        setConfigurationProperty("virtualhosts.virtualhost."
-                                 + getConnectionURL().getVirtualHost().substring(1) +
-                                 ".slow-consumer-detection.timeunit", "SECONDS");
-
-    }
-
-
-    protected void setProperty(String property, String value) throws NamingException, IOException, ConfigurationException
-    {
-        setConfigurationProperty("virtualhosts.virtualhost." +
-                                 getConnectionURL().getVirtualHost().substring(1) +
-                                 property, value);
-    }
-
-
-    /**
-     * Create and start an asynchrounous publisher that will send MAX_QUEUE_MESSAGE_COUNT
-     * messages to the provided destination. Messages are sent in a new connection
-     * on a transaction. Any error is captured and the test is signalled to exit.
-     *
-     * @param destination
-     */
-    private void startPublisher(final Destination destination)
-    {
-        _publisher = new Thread(new Runnable()
-        {
-
-            public void run()
-            {
-                try
-                {
-                    Connection connection = getConnection();
-                    Session session = connection.createSession(true, Session.SESSION_TRANSACTED);
-
-                    MessageProducer publisher = session.createProducer(destination);
-
-                    for (int count = 0; count < MAX_QUEUE_MESSAGE_COUNT; count++)
-                    {
-                        publisher.send(createNextMessage(session, count));
-                        session.commit();
-                    }
-                }
-                catch (Exception e)
-                {
-                    _publisherError = e;
-                    _disconnectionLatch.countDown();
-                }
-            }
-        });
-
-        _publisher.start();
-    }
-
-
-
-    /**
-     * Perform the Main test of a topic Consumer with the given AckMode.
-     *
-     * Test creates a new connection and sets up the connection to prevent
-     * failover
-     *
-     * A new consumer is connected and started so that it will prefetch msgs.
-     *
-     * An asynchrounous publisher is started to fill the broker with messages.
-     *
-     * We then wait to be notified of the disconnection via the ExceptionListener
-     *
-     * 0-10 does not have the same notification paths but sync() apparently should
-     * give us the exception, currently it doesn't, so the test is excluded from 0-10
-     *
-     * We should ensure that this test has the same path for all protocol versions.
-     *
-     * Clients should not have to modify their code based on the protocol in use.
-     *
-     * @param ackMode @see javax.jms.Session
-     *
-     * @throws Exception
-     */
-    protected void topicConsumer(int ackMode, boolean durable) throws Exception
-    {
-        Connection connection = getConnection();
-
-        connection.setExceptionListener(this);
-
-        Session session = connection.createSession(ackMode == Session.SESSION_TRANSACTED, ackMode);
-
-        _destination = session.createTopic(getName());
-
-        MessageConsumer consumer;
-
-        if (durable)
-        {
-            consumer = session.createDurableSubscriber(_destination, getTestQueueName());
-        }
-        else
-        {
-            consumer = session.createConsumer(_destination);
-        }
-
-        connection.start();
-
-        // Start the consumer pre-fetching
-        // Don't care about response as we will fill the broker up with messages
-        // after this point and ensure that the client is disconnected at the
-        // right point.
-        consumer.receiveNoWait();
-        startPublisher(_destination);
-
-        boolean disconnected = _disconnectionLatch.await(DISCONNECTION_WAIT, TimeUnit.SECONDS);
-        
-        assertTrue("Client was not disconnected", disconnected);
-        assertTrue("Client was not disconnected.", _connectionException != null);
-
-        Exception linked = _connectionException.getLinkedException();
-
-        _publisher.join(JOIN_WAIT);
-
-        assertFalse("Publisher still running", _publisher.isAlive());
-
-        //Validate publishing occurred ok
-        if (_publisherError != null)
-        {
-            throw _publisherError;
-        }
-
-        // NOTE these exceptions will need to be modeled so that they are not
-        // 0-8 specific. e.g. JMSSessionClosedException
-
-        assertNotNull("No error received onException listener.", _connectionException);
-
-        assertNotNull("No linked exception set on:" + _connectionException.getMessage(), linked);
-
-        assertTrue("Incorrect linked exception received.", linked instanceof AMQException);
-
-        AMQException amqException = (AMQException) linked;
-
-        assertEquals("Channel was not closed with correct code.", AMQConstant.RESOURCE_ERROR, amqException.getErrorCode());
-    }
-
-
-    // Exception Listener
-
-    public void onException(JMSException e)
-    {
-        _connectionException = e;
-
-        e.printStackTrace();
-
-        _disconnectionLatch.countDown();
-    }
-
-    /// Connection Listener
-
-    public void bytesSent(long count)
-    {
-    }
-
-    public void bytesReceived(long count)
-    {
-    }
-
-    public boolean preFailover(boolean redirect)
-    {
-        // Prevent Failover
-        return false;
-    }
-
-    public boolean preResubscribe()
-    {
-        return false;
-    }
-
-    public void failoverComplete()
-    {
-    }
-}
diff --git a/java/systests/src/main/java/org/apache/qpid/systest/TopicTest.java b/java/systests/src/main/java/org/apache/qpid/systest/TopicTest.java
deleted file mode 100644
index 09c849cfde..0000000000
--- a/java/systests/src/main/java/org/apache/qpid/systest/TopicTest.java
+++ /dev/null
@@ -1,85 +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.systest;
-
-import org.apache.commons.configuration.ConfigurationException;
-
-import javax.naming.NamingException;
-import java.io.IOException;
-
-/**
- * This Topic test extends the Global queue test so it will run all the topic
- * and subscription tests.
- *
- * We redefine the CONFIG_SECTION here so that the configuration is written
- * against a topic element.
- *
- * To complete the migration to testing 'topic' elements we also override
- * the setConfig to use the test name as the topic name.
- *
- */
-public class TopicTest extends GlobalQueuesTest
-{
-    private int _count=0;
-
-    @Override
-    public void setUp() throws Exception
-    {
-        CONFIG_SECTION = ".topics.topic";
-        super.setUp();
-    }
-
-    /**
-     * Add configuration for the queue that relates just to this test.
-     * We use the getTestQueueName() as our subscription. To ensure the
-     * config sections do not overlap we identify each section with a _count
-     * value.
-     *
-     * This would allow each test to configure more than one section.
-     *
-     * @param property to set
-     * @param value the value to set
-     * @param deleteDurable should deleteDurable be set.
-     * @throws NamingException
-     * @throws IOException
-     * @throws ConfigurationException
-     */
-    @Override
-    public void setConfig(String property, String value, boolean deleteDurable) throws NamingException, IOException, ConfigurationException
-    {
-        setProperty(CONFIG_SECTION + "("+_count+").name", getName());
-
-        setProperty(CONFIG_SECTION + "("+_count+").slow-consumer-detection." +
-                    "policy.name", "TopicDelete");
-
-        setProperty(CONFIG_SECTION + "("+_count+").slow-consumer-detection." +
-                    property, value);
-
-        if (deleteDurable)
-        {
-            setProperty(CONFIG_SECTION + "("+_count+").slow-consumer-detection." +
-                        "policy.topicdelete.delete-persistent", "");
-        }
-        _count++;
-    }
-
-    
-}
diff --git a/java/systests/src/main/java/org/apache/qpid/systest/management/jmx/BrokerManagementTest.java b/java/systests/src/main/java/org/apache/qpid/systest/management/jmx/BrokerManagementTest.java
new file mode 100644
index 0000000000..954208e78e
--- /dev/null
+++ b/java/systests/src/main/java/org/apache/qpid/systest/management/jmx/BrokerManagementTest.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.systest.management.jmx;
+
+import org.apache.qpid.exchange.ExchangeDefaults;
+import org.apache.qpid.management.common.mbeans.ManagedBroker;
+import org.apache.qpid.management.common.mbeans.ManagedExchange;
+import org.apache.qpid.test.utils.JMXTestUtils;
+import org.apache.qpid.test.utils.QpidBrokerTestCase;
+
+/**
+ * Tests the JMX API for the Managed Broker.
+ *
+ */
+public class BrokerManagementTest extends QpidBrokerTestCase
+{
+    private static final String VIRTUAL_HOST = "test";
+
+    /**
+     * JMX helper.
+     */
+    private JMXTestUtils _jmxUtils;
+    private ManagedBroker _managedBroker;
+
+    public void setUp() throws Exception
+    {
+        _jmxUtils = new JMXTestUtils(this);
+        _jmxUtils.setUp();
+        super.setUp();
+        _jmxUtils.open();
+        _managedBroker = _jmxUtils.getManagedBroker(VIRTUAL_HOST);
+    }
+
+    public void tearDown() throws Exception
+    {
+        if (_jmxUtils != null)
+        {
+            _jmxUtils.close();
+        }
+        super.tearDown();
+    }
+
+    /**
+     * Tests queue creation/deletion also verifying the automatic binding to the default exchange.
+     */
+    public void testCreateQueueAndDeletion() throws Exception
+    {
+        final String queueName = getTestQueueName();
+        final ManagedExchange defaultExchange = _jmxUtils.getManagedExchange(ExchangeDefaults.DEFAULT_EXCHANGE_NAME.asString());
+
+        // Check that bind does not exist before queue creation
+        assertFalse("Binding to " + queueName + " should not exist in default exchange before queue creation",
+                     defaultExchange.bindings().containsKey(new String[] {queueName}));
+
+        _managedBroker.createNewQueue(queueName, "testowner", true);
+
+        // Ensure the queue exists
+        assertNotNull("Queue object name expected to exist", _jmxUtils.getQueueObjectName(VIRTUAL_HOST, queueName));
+        assertNotNull("Manager queue expected to be available", _jmxUtils.getManagedQueue(queueName));
+
+        // Now verify that the default exchange has been bound.
+        assertTrue("Binding to " + queueName + " should exist in default exchange after queue creation",
+                     defaultExchange.bindings().containsKey(new String[] {queueName}));
+
+        // Now delete the queue
+        _managedBroker.deleteQueue(queueName);
+
+        // Finally ensure that the binding has been removed.
+        assertFalse("Binding to " + queueName + " should not exist in default exchange after queue deletion",
+                defaultExchange.bindings().containsKey(new String[] {queueName}));
+    }
+
+    /**
+     * Tests exchange creation/deletion via JMX API.
+     */
+    public void testCreateExchangeAndUnregister() throws Exception
+    {
+        String exchangeName = getTestName();
+        _managedBroker.createNewExchange(exchangeName, "topic", true);
+
+        ManagedExchange exchange = _jmxUtils.getManagedExchange(exchangeName);
+        assertNotNull("Exchange should exist", exchange);
+
+        _managedBroker.unregisterExchange(exchangeName);
+    }
+
+    /**
+     * Tests that it is disallowed to unregister the default exchange.
+     */
+    public void testUnregisterOfDefaultExchangeDisallowed() throws Exception
+    {
+        String defaultExchangeName = ExchangeDefaults.DEFAULT_EXCHANGE_NAME.asString();
+
+        ManagedExchange defaultExchange = _jmxUtils.getManagedExchange(defaultExchangeName);
+        assertNotNull("Exchange should exist", defaultExchange);
+        try
+        {
+            _managedBroker.unregisterExchange(defaultExchangeName);
+            fail("Exception not thrown");
+        }
+        catch (UnsupportedOperationException e)
+        {
+            // PASS
+            assertEquals("'<>' is a reserved exchange and can't be deleted", e.getMessage());
+        }
+        defaultExchange = _jmxUtils.getManagedExchange(defaultExchangeName);
+        assertNotNull("Exchange should exist", defaultExchange);
+    }
+
+}
diff --git a/java/systests/src/main/java/org/apache/qpid/systest/management/jmx/ConnectionManagementTest.java b/java/systests/src/main/java/org/apache/qpid/systest/management/jmx/ConnectionManagementTest.java
new file mode 100644
index 0000000000..28d7bf4aed
--- /dev/null
+++ b/java/systests/src/main/java/org/apache/qpid/systest/management/jmx/ConnectionManagementTest.java
@@ -0,0 +1,283 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.qpid.systest.management.jmx;
+
+import java.io.IOException;
+import java.util.Date;
+import java.util.Iterator;
+import java.util.List;
+
+import javax.jms.Connection;
+import javax.jms.Destination;
+import javax.jms.JMSException;
+import javax.jms.Message;
+import javax.jms.MessageConsumer;
+import javax.jms.Queue;
+import javax.jms.Session;
+import javax.management.JMException;
+import javax.management.openmbean.CompositeData;
+import javax.management.openmbean.CompositeDataSupport;
+import javax.management.openmbean.TabularData;
+
+import org.apache.commons.lang.StringUtils;
+import org.apache.qpid.common.QpidProperties;
+import org.apache.qpid.management.common.mbeans.ManagedConnection;
+import org.apache.qpid.management.common.mbeans.ManagedQueue;
+import org.apache.qpid.test.utils.JMXTestUtils;
+import org.apache.qpid.test.utils.QpidBrokerTestCase;
+
+public class ConnectionManagementTest extends QpidBrokerTestCase
+{
+    private static final String VIRTUAL_HOST_NAME = "test";
+
+    private JMXTestUtils _jmxUtils;
+    private Connection _connection;
+
+    public void setUp() throws Exception
+    {
+        _jmxUtils = new JMXTestUtils(this);
+        _jmxUtils.setUp(); // modifies broker config therefore must be done before super.setUp()
+        super.setUp();
+        _jmxUtils.open();
+    }
+
+    public void tearDown() throws Exception
+    {
+        try
+        {
+            if (_jmxUtils != null)
+            {
+                _jmxUtils.close();
+            }
+        }
+        finally
+        {
+            super.tearDown();
+        }
+    }
+
+    public void testNumberOfManagedConnectionsMatchesNumberOfClientConnections() throws Exception
+    {
+        assertEquals("Expected no managed connections", 0, getManagedConnections().size());
+
+        _connection = getConnection();
+        assertEquals("Expected one managed connection", 1, getManagedConnections().size());
+
+        _connection.close();
+        assertEquals("Expected no managed connections after client connection closed", 0, getManagedConnections().size());
+    }
+
+    public void testGetAttributes() throws Exception
+    {
+        _connection = getConnection();
+        final ManagedConnection mBean = getConnectionMBean();
+
+        checkAuthorisedId(mBean);
+        checkClientVersion(mBean);
+        checkClientId(mBean);
+    }
+
+    public void testNonTransactedSession() throws Exception
+    {
+        _connection = getConnection();
+
+        boolean transactional = false;
+        boolean flowBlocked = false;
+
+        _connection.createSession(transactional, Session.AUTO_ACKNOWLEDGE);
+
+        final ManagedConnection mBean = getConnectionMBean();
+        final CompositeDataSupport row = getTheOneChannelRow(mBean);
+        assertChannelRowData(row, 0, transactional, flowBlocked);
+    }
+
+    public void testTransactedSessionWithUnackMessages() throws Exception
+    {
+        _connection = getConnection();
+        _connection.start();
+
+        boolean transactional = true;
+        int numberOfMessages = 2;
+        final Session session = _connection.createSession(transactional, Session.SESSION_TRANSACTED);
+        final Destination destination = session.createQueue(getTestQueueName());
+        final MessageConsumer consumer = session.createConsumer(destination);
+
+        sendMessage(session, destination, numberOfMessages);
+        receiveMessagesWithoutCommit(consumer, numberOfMessages);
+
+        final ManagedConnection mBean = getConnectionMBean();
+        final CompositeDataSupport row = getTheOneChannelRow(mBean);
+        boolean flowBlocked = false;
+        assertChannelRowData(row, numberOfMessages, transactional, flowBlocked);
+
+        // check that commit advances the lastIoTime
+        final Date initialLastIOTime = mBean.getLastIoTime();
+        session.commit();
+        assertTrue("commit should have caused last IO time to advance", mBean.getLastIoTime().after(initialLastIOTime));
+
+        // check that channels() now returns one session with no unacknowledged messages
+        final CompositeDataSupport rowAfterCommit = getTheOneChannelRow(mBean);
+        final Number unackCountAfterCommit = (Number) rowAfterCommit.get(ManagedConnection.UNACKED_COUNT);
+        assertEquals("Unexpected number of unacknowledged messages", 0, unackCountAfterCommit);
+    }
+
+
+    public void testProducerFlowBlocked() throws Exception
+    {
+        _connection = getConnection();
+        _connection.start();
+
+        String queueName = getTestQueueName();
+        Session session = _connection.createSession(true, Session.SESSION_TRANSACTED);
+        Queue queue = session.createQueue(queueName);
+        createQueueOnBroker(session, queue);
+
+        ManagedQueue managedQueue = _jmxUtils.getManagedQueue(queueName);
+        managedQueue.setFlowResumeCapacity(DEFAULT_MESSAGE_SIZE * 2l);
+        managedQueue.setCapacity(DEFAULT_MESSAGE_SIZE * 3l);
+
+        final ManagedConnection managedConnection = getConnectionMBean();
+
+        // Check that producer flow is not block before test
+        final CompositeDataSupport rowBeforeSend = getTheOneChannelRow(managedConnection);
+        assertFlowBlocked(rowBeforeSend, false);
+
+
+        // Check that producer flow does not become block too soon
+        sendMessage(session, queue, 3);
+        final CompositeDataSupport rowBeforeFull = getTheOneChannelRow(managedConnection);
+        assertFlowBlocked(rowBeforeFull, false);
+
+        // Fourth message will over-fill the queue (but as we are not sending more messages, client thread wont't block)
+        sendMessage(session, queue, 1);
+        final CompositeDataSupport rowAfterFull = getTheOneChannelRow(managedConnection);
+        assertFlowBlocked(rowAfterFull, true);
+
+        // Consume two to bring the queue down to the resume capacity
+        MessageConsumer consumer = session.createConsumer(queue);
+        assertNotNull("Could not receive first message", consumer.receive(1000));
+        assertNotNull("Could not receive second message", consumer.receive(1000));
+        session.commit();
+
+        // Check that producer flow is no longer blocked
+        final CompositeDataSupport rowAfterReceive = getTheOneChannelRow(managedConnection);
+        assertFlowBlocked(rowAfterReceive, false);
+    }
+
+    private void createQueueOnBroker(Session session, Destination destination) throws JMSException
+    {
+        session.createConsumer(destination).close(); // Create a consumer only to cause queue creation
+    }
+
+    private void assertChannelRowData(final CompositeData row, int unacknowledgedMessages, boolean isTransactional, boolean flowBlocked)
+    {
+        assertNotNull(row);
+        assertEquals("Unexpected transactional flag", isTransactional, row.get(ManagedConnection.TRANSACTIONAL));
+        assertEquals("Unexpected unacknowledged message count", unacknowledgedMessages, row.get(ManagedConnection.UNACKED_COUNT));
+        assertEquals("Unexpected flow blocked", flowBlocked, row.get(ManagedConnection.FLOW_BLOCKED));
+    }
+
+    private void assertFlowBlocked(final CompositeData row, boolean flowBlocked)
+    {
+        assertNotNull(row);
+        assertEquals("Unexpected flow blocked", flowBlocked, row.get(ManagedConnection.FLOW_BLOCKED));
+    }
+
+    private void checkAuthorisedId(ManagedConnection mBean) throws Exception
+    {
+        assertEquals("Unexpected authorized id", GUEST_USERNAME, mBean.getAuthorizedId());
+    }
+
+    private void checkClientVersion(ManagedConnection mBean) throws Exception
+    {
+        String expectedVersion = QpidProperties.getReleaseVersion();
+        assertTrue(StringUtils.isNotBlank(expectedVersion));
+
+        assertEquals("Unexpected version", expectedVersion, mBean.getVersion());
+    }
+
+    private void checkClientId(ManagedConnection mBean) throws Exception
+    {
+        String expectedClientId = _connection.getClientID();
+        assertTrue(StringUtils.isNotBlank(expectedClientId));
+
+        assertEquals("Unexpected ClientId", expectedClientId, mBean.getClientId());
+    }
+
+    private ManagedConnection getConnectionMBean()
+    {
+        List connections = getManagedConnections();
+        assertNotNull("Connection MBean is not found", connections);
+        assertEquals("Unexpected number of connection mbeans", 1, connections.size());
+        final ManagedConnection mBean = connections.get(0);
+        assertNotNull("Connection MBean is null", mBean);
+        return mBean;
+    }
+
+    private List getManagedConnections()
+    {
+        return _jmxUtils.getManagedConnections(VIRTUAL_HOST_NAME);
+    }
+
+    private CompositeDataSupport getTheOneChannelRow(final ManagedConnection mBean) throws Exception
+    {
+        TabularData channelsData = getChannelsDataWithRetry(mBean);
+
+        assertEquals("Unexpected number of rows in channel table", 1, channelsData.size());
+
+        @SuppressWarnings("unchecked")
+        final Iterator rowItr = (Iterator) channelsData.values().iterator();
+        final CompositeDataSupport row = rowItr.next();
+        return row;
+    }
+
+    private void receiveMessagesWithoutCommit(final MessageConsumer consumer, int numberOfMessages) throws Exception
+    {
+        for (int i = 0; i < numberOfMessages; i++)
+        {
+            final Message m = consumer.receive(1000l);
+            assertNotNull("Message " + i + " is not received", m);
+        }
+    }
+
+    private TabularData getChannelsDataWithRetry(final ManagedConnection mBean)
+            throws IOException, JMException
+    {
+        TabularData channelsData = mBean.channels();
+        int retries = 0;
+        while(channelsData.size() == 0 && retries < 5)
+        {
+            sleep();
+            channelsData = mBean.channels();
+            retries++;
+        }
+        return channelsData;
+    }
+
+    private void sleep()
+    {
+        try
+        {
+            Thread.sleep(50);
+        }
+        catch (InterruptedException ie)
+        {
+            Thread.currentThread().interrupt();
+        }
+    }}
diff --git a/java/systests/src/main/java/org/apache/qpid/systest/management/jmx/LoggingManagementTest.java b/java/systests/src/main/java/org/apache/qpid/systest/management/jmx/LoggingManagementTest.java
new file mode 100644
index 0000000000..3c3bbdca41
--- /dev/null
+++ b/java/systests/src/main/java/org/apache/qpid/systest/management/jmx/LoggingManagementTest.java
@@ -0,0 +1,147 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.qpid.systest.management.jmx;
+
+import java.io.File;
+import java.util.List;
+
+import javax.management.openmbean.CompositeData;
+import javax.management.openmbean.TabularData;
+
+import org.apache.qpid.management.common.mbeans.LoggingManagement;
+import org.apache.qpid.server.logging.log4j.LoggingManagementFacadeTest;
+import org.apache.qpid.test.utils.JMXTestUtils;
+import org.apache.qpid.test.utils.QpidBrokerTestCase;
+import org.apache.qpid.util.FileUtils;
+import org.apache.qpid.util.LogMonitor;
+
+/**
+ * System test for Logging Management.  These tests rely on value set within
+ * test-profiles/log4j-test.xml.
+ *
+ * @see LoggingManagementMBeanTest
+ * @see LoggingManagementFacadeTest
+ *
+ */
+public class LoggingManagementTest extends QpidBrokerTestCase
+{
+    private JMXTestUtils _jmxUtils;
+    private LoggingManagement _loggingManagement;
+    private LogMonitor _monitor;
+
+    public void setUp() throws Exception
+    {
+        _jmxUtils = new JMXTestUtils(this);
+        _jmxUtils.setUp();
+
+        // System test normally run with log for4j test config from beneath test-profiles.   We need to
+        // copy it as some of our tests write to this file.
+
+        File tmpLogFile = File.createTempFile("log4j" + "." + getName(), ".xml");
+        tmpLogFile.deleteOnExit();
+        FileUtils.copy(getBrokerCommandLog4JFile(), tmpLogFile);
+        setBrokerCommandLog4JFile(tmpLogFile);
+
+        super.setUp();
+        _jmxUtils.open();
+
+        _loggingManagement = _jmxUtils.getLoggingManagement();
+        _monitor = new LogMonitor(_outputFile);
+    }
+
+    public void tearDown() throws Exception
+    {
+        try
+        {
+            if (_jmxUtils != null)
+            {
+                _jmxUtils.close();
+            }
+        }
+        finally
+        {
+            super.tearDown();
+        }
+    }
+
+    public void testViewEffectiveRuntimeLoggerLevels() throws Exception
+    {
+        final String qpidMainLogger = "org.apache.qpid";
+
+        TabularData table = _loggingManagement.viewEffectiveRuntimeLoggerLevels();
+        final CompositeData row = table.get(new String[] {qpidMainLogger} );
+        assertChannelRow(row, qpidMainLogger, "DEBUG");
+    }
+
+    public void testViewConfigFileLoggerLevels() throws Exception
+    {
+        final String operationalLoggingLogger = "qpid.message";
+
+        TabularData table = _loggingManagement.viewConfigFileLoggerLevels();
+        final CompositeData row = table.get(new String[] {operationalLoggingLogger} );
+        assertChannelRow(row, operationalLoggingLogger, "INFO");
+    }
+
+    public void testTurnOffOrgApacheQpidAtRuntime() throws Exception
+    {
+        final String logger = "org.apache.qpid";
+        _monitor.markDiscardPoint();
+        _loggingManagement.setRuntimeLoggerLevel(logger, "OFF");
+
+        List matches = _monitor.waitAndFindMatches("Setting level to OFF for logger 'org.apache.qpid'", 5000);
+        assertEquals(1, matches.size());
+
+        TabularData table = _loggingManagement.viewEffectiveRuntimeLoggerLevels();
+        final CompositeData row1 = table.get(new String[] {logger} );
+        assertChannelRow(row1, logger, "OFF");
+    }
+
+    public void testChangesToConfigFileBecomeEffectiveAfterReload() throws Exception
+    {
+        final String operationalLoggingLogger  = "qpid.message";
+        assertEffectiveLoggingLevel(operationalLoggingLogger, "INFO");
+
+        _monitor.markDiscardPoint();
+        _loggingManagement.setConfigFileLoggerLevel(operationalLoggingLogger, "OFF");
+
+        List matches = _monitor.waitAndFindMatches("Setting level to OFF for logger 'qpid.message'", 5000);
+        assertEquals(1, matches.size());
+
+        assertEffectiveLoggingLevel(operationalLoggingLogger, "INFO");
+
+        _loggingManagement.reloadConfigFile();
+
+        assertEffectiveLoggingLevel(operationalLoggingLogger, "OFF");
+    }
+
+    private void assertEffectiveLoggingLevel(String operationalLoggingLogger, String expectedLevel)
+    {
+        TabularData table = _loggingManagement.viewEffectiveRuntimeLoggerLevels();
+        final CompositeData row1 = table.get(new String[] {operationalLoggingLogger} );
+        assertChannelRow(row1, operationalLoggingLogger, expectedLevel);
+    }
+
+    private void assertChannelRow(final CompositeData row, String logger, String level)
+    {
+        assertNotNull("No row for  " + logger, row);
+        assertEquals("Unexpected logger name", logger, row.get(LoggingManagement.LOGGER_NAME));
+        assertEquals("Unexpected level", level, row.get(LoggingManagement.LOGGER_LEVEL));
+    }
+
+}
diff --git a/java/systests/src/main/java/org/apache/qpid/systest/management/jmx/ManagementActorLoggingTest.java b/java/systests/src/main/java/org/apache/qpid/systest/management/jmx/ManagementActorLoggingTest.java
new file mode 100644
index 0000000000..47b38381c5
--- /dev/null
+++ b/java/systests/src/main/java/org/apache/qpid/systest/management/jmx/ManagementActorLoggingTest.java
@@ -0,0 +1,480 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.qpid.systest.management.jmx;
+
+import org.apache.qpid.management.common.mbeans.ManagedBroker;
+import org.apache.qpid.management.common.mbeans.ManagedConnection;
+import org.apache.qpid.management.common.mbeans.ManagedExchange;
+import org.apache.qpid.server.logging.AbstractTestLogging;
+import org.apache.qpid.server.logging.subjects.AbstractTestLogSubject;
+import org.apache.qpid.test.utils.JMXTestUtils;
+
+import javax.jms.Connection;
+import javax.jms.ExceptionListener;
+import javax.jms.JMSException;
+import javax.management.JMException;
+import java.io.IOException;
+import java.util.List;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Test class to test if any change in the broker JMX code is affesting the management console
+ * There are some hardcoding of management feature names and parameter names to create a customized
+ * look in the console.
+ */
+public class ManagementActorLoggingTest extends AbstractTestLogging
+{
+    private JMXTestUtils _jmxUtils;
+    private boolean _closed = false;
+
+    @Override
+    public void setUp() throws Exception
+    {
+        _jmxUtils = new JMXTestUtils(this);
+        _jmxUtils.setUp();
+        super.setUp();
+        _jmxUtils.open();
+    }
+
+    @Override
+    public void tearDown() throws Exception
+    {
+        if(!_closed)
+        {
+            _jmxUtils.close();
+        }
+        super.tearDown();
+    }
+
+    /**
+     * Description:
+     * When a connected client has its connection closed via the Management Console this will be logged as a CON-1002 message.
+     * Input:
+     *
+     * 1. Running Broker
+     * 2. Connected Client
+     * 3. Connection is closed via Management Console
+     * Output:
+     *
+     *  CON-1002 : Close
+     *
+     * Validation Steps:
+     * 4. The CON ID is correct
+     * 5. This must be the last CON message for the Connection
+     * 6. It must be preceded by a CON-1001 for this Connection
+     *
+     * @throws Exception           - {@see ManagedConnection.closeConnection and #getConnection}
+     * @throws java.io.IOException - if there is a problem reseting the log monitor
+     */
+    public void testConnectionCloseViaManagement() throws IOException, Exception
+    {
+        //Create a connection to the broker
+        Connection connection = getConnection();
+
+        // Monitor the connection for an exception being thrown
+        // this should be a DisconnectionException but it is not this tests
+        // job to valiate that. Only use the exception as a synchronisation
+        // to check the log file for the Close message
+        final CountDownLatch exceptionReceived = new CountDownLatch(1);
+        connection.setExceptionListener(new ExceptionListener()
+        {
+            public void onException(JMSException e)
+            {
+                //Failover being attempted.
+                exceptionReceived.countDown();
+            }
+        });
+
+        //Remove the connection close from any 0-10 connections
+        _monitor.markDiscardPoint();
+
+        // Get a managedConnection
+        ManagedConnection mangedConnection = _jmxUtils.getManagedObject(ManagedConnection.class, "org.apache.qpid:type=VirtualHost.Connection,*");
+
+        //Close the connection
+        mangedConnection.closeConnection();
+
+        //Wait for the connection to close
+        assertTrue("Timed out waiting for conneciton to report close",
+                   exceptionReceived.await(2, TimeUnit.SECONDS));
+
+        //Validate results
+        List results = waitAndFindMatches("CON-1002");
+
+        assertEquals("Unexpected Connection Close count", 1, results.size());
+    }
+
+    /**
+     * Description:
+     * Exchange creation is possible from the Management Console.
+     * When an exchanged is created in this way then a EXH-1001 create message
+     * is expected to be logged.
+     * Input:
+     *
+     * 1. Running broker
+     * 2. Connected Management Console
+     * 3. Exchange Created via Management Console
+     * Output:
+     *
+     * EXH-1001 : Create : [Durable] Type: Name:
+     *
+     * Validation Steps:
+     * 4. The EXH ID is correct
+     * 5. The correct tags are present in the message based on the create options
+     *
+     * @throws java.io.IOException          - if there is a problem reseting the log monitor
+     * @throws javax.management.JMException - {@see #createQueue and ManagedExchange.deleteQueue}
+     */
+    public void testCreateExchangeDirectTransientViaManagementConsole() throws IOException, JMException
+    {
+        _monitor.markDiscardPoint();
+
+        _jmxUtils.createExchange("test", getName(), "direct", false);
+
+        // Validate
+
+        //1 - ID is correct
+        List results = waitAndFindMatches("EXH-1001");
+
+        assertEquals("More than one exchange creation found", 1, results.size());
+
+        String log = getLogMessage(results, 0);
+
+        // Validate correct exchange name
+        assertTrue("Incorrect exchange name created:" + log, log.endsWith(getName()));
+
+        // Validate it was a management actor.
+        String actor = fromActor(log);
+        assertTrue("Actor is not a manangement actor:" + actor, actor.startsWith("mng"));
+    }
+
+    public void testCreateExchangeTopicTransientViaManagementConsole() throws IOException, JMException
+    {
+        //Remove any previous exchange declares
+        _monitor.markDiscardPoint();
+
+        _jmxUtils.createExchange("test", getName(), "topic", false);
+
+        // Validate
+
+        //1 - ID is correct
+        List results = waitAndFindMatches("EXH-1001");
+
+        assertEquals("More than one exchange creation found", 1, results.size());
+
+        String log = getLogMessage(results, 0);
+
+        // Validate correct exchange name
+        assertTrue("Incorrect exchange name created:" + log, log.endsWith(getName()));
+
+        // Validate it was a management actor.
+        String actor = fromActor(log);
+        assertTrue("Actor is not a manangement actor:" + actor, actor.startsWith("mng"));
+
+    }
+
+    public void testCreateExchangeFanoutTransientViaManagementConsole() throws IOException, JMException
+    {
+        //Remove any previous exchange declares
+        _monitor.markDiscardPoint();
+
+        _jmxUtils.createExchange("test", getName(), "fanout", false);
+
+        // Validate
+
+        //1 - ID is correct
+        List results = waitAndFindMatches("EXH-1001");
+
+        assertEquals("More than one exchange creation found", 1, results.size());
+
+        String log = getLogMessage(results, 0);
+
+        // Validate correct exchange name
+        assertTrue("Incorrect exchange name created:" + log, log.endsWith(getName()));
+
+        // Validate it was a management actor.
+        String actor = fromActor(log);
+        assertTrue("Actor is not a manangement actor:" + actor, actor.startsWith("mng"));
+
+    }
+
+    public void testCreateExchangeHeadersTransientViaManagementConsole() throws IOException, JMException
+    {
+        //Remove any previous exchange declares
+        _monitor.markDiscardPoint();
+
+        _jmxUtils.createExchange("test", getName(), "headers", false);
+
+        // Validate
+
+        //1 - ID is correct
+        List results = waitAndFindMatches("EXH-1001");
+
+        assertEquals("More than one exchange creation found", 1, results.size());
+
+        String log = getLogMessage(results, 0);
+
+        // Validate correct exchange name
+        assertTrue("Incorrect exchange name created:" + log, log.endsWith(getName()));
+
+        // Validate it was a management actor.
+        String actor = fromActor(log);
+        assertTrue("Actor is not a manangement actor:" + actor, actor.startsWith("mng"));
+
+    }
+
+    /**
+     * Description:
+     * Queue creation is possible from the Management Console. When a queue is created in this way then a QUE-1001 create message is expected to be logged.
+     * Input:
+     *
+     * 1. Running broker
+     * 2. Connected Management Console
+     * 3. Queue Created via Management Console
+     * Output:
+     *
+     *  QUE-1001 : Create : Transient Owner:
+     *
+     * Validation Steps:
+     * 4. The QUE ID is correct
+     * 5. The correct tags are present in the message based on the create options
+     *
+     * @throws java.io.IOException          - if there is a problem reseting the log monitor
+     * @throws javax.management.JMException - {@see #createQueue and ManagedExchange.deleteQueue}
+     */
+    public void testCreateQueueTransientViaManagementConsole() throws IOException, JMException
+    {
+        //Remove any previous queue declares
+        _monitor.markDiscardPoint();
+
+        _jmxUtils.createQueue("test", getName(), null, false);
+
+        // Validate
+
+        List results = waitAndFindMatches("QUE-1001");
+
+        assertEquals("More than one queue creation found", 1, results.size());
+
+        String log = getLogMessage(results, 0);
+
+        // Validate correct queue name
+        String subject = fromSubject(log);
+        assertEquals("Incorrect queue name created", getName(), AbstractTestLogSubject.getSlice("qu", subject));
+
+        // Validate it was a management actor.
+        String actor = fromActor(log);
+        assertTrue("Actor is not a manangement actor:" + actor, actor.startsWith("mng"));
+    }
+
+    /**
+     * Description:
+     * The ManagementConsole can be used to delete a queue. When this is done a QUE-1002 Deleted message must be logged.
+     * Input:
+     *
+     * 1. Running Broker
+     * 2. Queue created on the broker with no subscribers
+     * 3. Management Console connected
+     * 4. Queue is deleted via Management Console
+     * Output:
+     *
+     *  QUE-1002 : Deleted
+     *
+     * Validation Steps:
+     * 5. The QUE ID is correct
+     *
+     * @throws java.io.IOException          - if there is a problem reseting the log monitor
+     * @throws javax.management.JMException - {@see #createQueue and ManagedExchange.deleteQueue}
+     */
+    public void testQueueDeleteViaManagementConsole() throws IOException, JMException
+    {
+        //Remove any previous queue declares
+        _monitor.markDiscardPoint();
+
+        _jmxUtils.createQueue("test", getName(), null, false);
+
+        ManagedBroker managedBroker = _jmxUtils.getManagedBroker("test");
+
+        managedBroker.deleteQueue(getName());
+
+        List results = waitAndFindMatches("QUE-1002");
+
+        assertEquals("More than one queue deletion found", 1, results.size());
+
+        String log = getLog(results.get(0));
+
+        // Validate correct binding
+        String subject = fromSubject(log);
+        assertEquals("Incorrect queue named in delete", getName(), AbstractTestLogSubject.getSlice("qu", subject));
+
+        // Validate it was a management actor.
+        String actor = fromActor(log);
+        assertTrue("Actor is not a manangement actor:" + actor, actor.startsWith("mng"));
+
+    }
+
+    /**
+     * Description:
+     * The binding of a Queue and an Exchange is done via a Binding. When this Binding is created via the Management Console a BND-1001 Create message will be logged.
+     * Input:
+     *
+     * 1. Running Broker
+     * 2. Connected Management Console
+     * 3. Use Management Console to perform binding
+     * Output:
+     *
+     *  BND-1001 : Create
+     *
+     * Validation Steps:
+     * 4. The BND ID is correct
+     * 5. This will be the first message for the given binding
+     *
+     * @throws java.io.IOException          - if there is a problem reseting the log monitor
+     * @throws javax.management.JMException - {@see #createQueue and ManagedExchange.createNewBinding}
+     */
+    public void testBindingCreateOnDirectViaManagementConsole() throws IOException, JMException
+    {
+        //Remove any previous queue declares
+        _monitor.markDiscardPoint();
+
+        _jmxUtils.createQueue("test", getName(), null, false);
+
+        ManagedExchange managedExchange = _jmxUtils.getManagedExchange("amq.direct");
+
+        managedExchange.createNewBinding(getName(), getName());
+
+        List results = waitAndFindMatches("BND-1001");
+
+        assertEquals("Unexpected number of bindings logged", 2, results.size());
+
+        String log = getLogMessage(results, 0);
+
+        // Validate correct binding
+        String subject = fromSubject(log);
+        assertEquals("Incorrect queue named in create", getName(), AbstractTestLogSubject.getSlice("qu", subject));
+        assertEquals("Incorrect routing key in create", getName(), AbstractTestLogSubject.getSlice("rk", subject));
+
+        // Validate it was a management actor.
+        String actor = fromActor(log);
+        assertTrue("Actor is not a manangement actor:" + actor, actor.startsWith("mng"));
+    }
+
+    public void testBindingCreateOnTopicViaManagementConsole() throws IOException, JMException
+    {
+        //Remove any previous queue declares
+        _monitor.markDiscardPoint();
+
+        _jmxUtils.createQueue("test", getName(), null, false);
+
+        ManagedExchange managedExchange = _jmxUtils.getManagedExchange("amq.topic");
+
+        managedExchange.createNewBinding(getName(), getName());
+
+        List results = waitAndFindMatches("BND-1001");
+
+        assertEquals("Unexpected number of bindings logged", 2, results.size());
+
+        String log = getLogMessage(results, 0);
+
+        // Validate correct binding
+        String subject = fromSubject(log);
+        assertEquals("Incorrect queue named in create", getName(), AbstractTestLogSubject.getSlice("qu", subject));
+        assertEquals("Incorrect routing key in create", getName(), AbstractTestLogSubject.getSlice("rk", subject));
+
+        // Validate it was a management actor.
+        String actor = fromActor(log);
+        assertTrue("Actor is not a manangement actor:" + actor, actor.startsWith("mng"));
+    }
+
+    public void testBindingCreateOnFanoutViaManagementConsole() throws IOException, JMException
+    {
+        //Remove any previous queue declares
+        _monitor.markDiscardPoint();
+
+        _jmxUtils.createQueue("test", getName(), null, false);
+
+        ManagedExchange managedExchange = _jmxUtils.getManagedExchange("amq.fanout");
+
+        managedExchange.createNewBinding(getName(), getName());
+
+        List results = waitAndFindMatches("BND-1001");
+
+        assertEquals("Unexpected number of bindings logged", 2, results.size());
+
+        String log = getLogMessage(results, 0);
+
+        // Validate correct binding
+        String subject = fromSubject(log);
+        assertEquals("Incorrect queue named in create", getName(), AbstractTestLogSubject.getSlice("qu", subject));
+        assertEquals("Incorrect routing key in create", getName(), AbstractTestLogSubject.getSlice("rk", subject));
+
+        // Validate it was a management actor.
+        String actor = fromActor(log);
+        assertTrue("Actor is not a manangement actor:" + actor, actor.startsWith("mng"));
+    }
+
+    /**
+     * Description:
+     * Bindings can be deleted so that a queue can be rebound with a different set of values. This can be performed via the Management Console
+     * Input:
+     *
+     * 1. Running Broker
+     * 2. Management Console connected
+     * 3. Management Console is used to perform unbind.
+     * Output:
+     *
+     *  BND-1002 : Deleted
+     *
+     * Validation Steps:
+     * 4. The BND ID is correct
+     * 5. There must have been a BND-1001 Create message first.
+     * 6. This will be the last message for the given binding
+     *
+     * @throws java.io.IOException          - if there is a problem reseting the log monitor or an issue with the JMX Connection
+     * @throws javax.management.JMException - {@see #createExchange and ManagedBroker.unregisterExchange}
+     */
+    public void testUnRegisterExchangeViaManagementConsole() throws IOException, JMException
+    {
+        //Remove any previous queue declares
+        _monitor.markDiscardPoint();
+
+        _jmxUtils.createExchange("test", getName(), "direct", false);
+
+        ManagedBroker managedBroker = _jmxUtils.getManagedBroker("test");
+
+        managedBroker.unregisterExchange(getName());
+
+        List results = waitAndFindMatches("EXH-1002");
+
+        assertEquals("More than one exchange deletion found", 1, results.size());
+
+        String log = getLog(results.get(0));
+
+        // Validate correct binding
+        String subject = fromSubject(log);
+        assertEquals("Incorrect exchange named in delete", "direct/" + getName(), AbstractTestLogSubject.getSlice("ex", subject));
+
+        // Validate it was a management actor.
+        String actor = fromActor(log);
+        assertTrue("Actor is not a manangement actor:" + actor, actor.startsWith("mng"));
+    }
+
+}
diff --git a/java/systests/src/main/java/org/apache/qpid/systest/management/jmx/ManagementLoggingTest.java b/java/systests/src/main/java/org/apache/qpid/systest/management/jmx/ManagementLoggingTest.java
new file mode 100644
index 0000000000..950b002b87
--- /dev/null
+++ b/java/systests/src/main/java/org/apache/qpid/systest/management/jmx/ManagementLoggingTest.java
@@ -0,0 +1,330 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.qpid.systest.management.jmx;
+
+
+import org.apache.qpid.server.configuration.BrokerProperties;
+import org.apache.qpid.server.logging.AbstractTestLogging;
+import org.apache.qpid.server.model.Port;
+import org.apache.qpid.server.model.Transport;
+import org.apache.qpid.test.utils.JMXTestUtils;
+import org.apache.qpid.test.utils.TestBrokerConfiguration;
+import org.apache.qpid.test.utils.TestSSLConstants;
+import org.apache.qpid.util.LogMonitor;
+
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * Management Console Test Suite
+ *
+ * The Management Console test suite validates that the follow log messages as specified in the Functional Specification.
+ *
+ * This suite of tests validate that the management console messages occur correctly and according to the following format:
+ *
+ * MNG-1001 :  Management Startup
+ * MNG-1002 : Starting :  : Listening on port 
+ * MNG-1003 : Shutting down :  : port 
+ * MNG-1004 :  Management Ready
+ * MNG-1005 :  Management Stopped
+ * MNG-1006 : Using SSL Keystore : 
+ * MNG-1007 : Open : User 
+ * MNG-1008 : Close : User 
+ */
+public class ManagementLoggingTest extends AbstractTestLogging
+{
+    private static final String MNG_PREFIX = "MNG-";
+
+    public void setUp() throws Exception
+    {
+        setLogMessagePrefix();
+
+        // We either do this here or have a null check in tearDown.
+        // As when this test is run against profiles other than java it will NPE
+        _monitor = new LogMonitor(_outputFile);
+        //We explicitly do not call super.setUp as starting up the broker is
+        //part of the test case.
+
+    }
+
+    /**
+     * Description:
+     * Using the startup configuration validate that the management startup
+     * message is logged correctly.
+     * Input:
+     * Standard configuration with management enabled
+     * Output:
+     *
+     *  MNG-1001 : Startup
+     *
+     * Constraints:
+     * This is the FIRST message logged by MNG
+     * Validation Steps:
+     *
+     * 1. The BRK ID is correct
+     * 2. This is the FIRST message logged by MNG
+     */
+    public void testManagementStartupEnabled() throws Exception
+    {
+        // This test only works on java brokers
+        if (isJavaBroker())
+        {
+            startBrokerAndCreateMonitor(true, false);
+
+            // Ensure we have received the MNG log msg.
+            waitForMessage("MNG-1001");
+
+            List results = findMatches(MNG_PREFIX);
+            // Validation
+
+            assertTrue("MNGer message not logged", results.size() > 0);
+
+            String log = getLogMessage(results, 0);
+
+            //1
+            validateMessageID("MNG-1001", log);
+
+            //2
+            //There will be 2 copies of the startup message (one via SystemOut, and one via Log4J)
+            results = findMatches("MNG-1001");
+            assertEquals("Unexpected startup message count.",
+                         2, results.size());
+
+            //3
+            assertEquals("Startup log message is not 'Startup'.", "JMX Management Startup",
+                         getMessageString(log));
+        }
+    }
+
+    /**
+     * Description:
+     * Verify that when management is disabled in the configuration file the
+     * startup message is not logged.
+     * Input:
+     * Standard configuration with management disabled
+     * Output:
+     * NO MNG messages
+     * Validation Steps:
+     *
+     * 1. Validate that no MNG messages are produced.
+     */
+    public void testManagementStartupDisabled() throws Exception
+    {
+        if (isJavaBroker())
+        {
+            startBrokerAndCreateMonitor(false, false);
+
+            List results = findMatches(MNG_PREFIX);
+            // Validation
+
+            assertEquals("MNGer messages logged", 0, results.size());
+        }
+    }
+
+    /**
+     * The two MNG-1002 messages are logged at the same time so lets test them
+     * at the same time.
+     *
+     * Description:
+     * Using the default configuration validate that the RMI Registry socket is
+     * correctly reported as being opened
+     *
+     * Input:
+     * The default configuration file
+     * Output:
+     *
+     *  MESSAGE MNG-1002 : Starting : RMI Registry : Listening on port 8999
+     *
+     * Constraints:
+     * The RMI ConnectorServer and Registry log messages do not have a prescribed order
+     * Validation Steps:
+     *
+     * 1. The MNG ID is correct
+     * 2. The specified port is the correct '8999'
+     *
+     * Description:
+     * Using the default configuration validate that the RMI ConnectorServer
+     * socket is correctly reported as being opened
+     *
+     * Input:
+     * The default configuration file
+     * Output:
+     *
+     *  MESSAGE MNG-1002 : Starting : RMI ConnectorServer : Listening on port 9099
+     *
+     * Constraints:
+     * The RMI ConnectorServer and Registry log messages do not have a prescribed order
+     * Validation Steps:
+     *
+     * 1. The MNG ID is correct
+     * 2. The specified port is the correct '9099'
+     */
+    public void testManagementStartupRMIEntries() throws Exception
+    {
+        if (isJavaBroker())
+        {
+            startBrokerAndCreateMonitor(true, false);
+
+            List results = waitAndFindMatches("MNG-1002");
+            // Validation
+
+            //There will be 4 startup messages (two via SystemOut, and two via Log4J)
+            assertEquals("Unexpected MNG-1002 message count", 4, results.size());
+
+            String log = getLogMessage(results, 0);
+
+            //1
+            validateMessageID("MNG-1002", log);
+
+            //Check the RMI Registry port is as expected
+            int mPort = getManagementPort(getPort());
+            assertTrue("RMI Registry port not as expected(" + mPort + ").:" + getMessageString(log),
+                       getMessageString(log).endsWith(String.valueOf(mPort)));
+
+            log = getLogMessage(results, 2);
+
+            //1
+            validateMessageID("MNG-1002", log);
+
+            // We expect the RMI Registry port (the defined 'management port') to be
+            // 100 lower than the JMX RMIConnector Server Port (the actual JMX server)
+            int jmxPort = mPort + JMXPORT_CONNECTORSERVER_OFFSET;
+            assertTrue("JMX RMIConnectorServer port not as expected(" + jmxPort + ").:" + getMessageString(log),
+                       getMessageString(log).endsWith(String.valueOf(jmxPort)));
+        }
+    }
+
+    /**
+     * Description:
+     * Using the default configuration with SSL enabled for the management port the SSL Keystore path should be reported via MNG-1006
+     * Input:
+     * Management SSL enabled default configuration.
+     * Output:
+     *
+     *  MESSAGE MNG-1006 : Using SSL Keystore : test_resources/ssl/keystore.jks
+     *
+     * Validation Steps:
+     *
+     * 1. The MNG ID is correct
+     * 2. The keystore path is as specified in the configuration
+     */
+    public void testManagementStartupSSLKeystore() throws Exception
+    {
+        if (isJavaBroker())
+        {
+            setSystemProperty("javax.net.debug", "ssl");
+            startBrokerAndCreateMonitor(true, true);
+
+            List results = waitAndFindMatches("MNG-1006");
+
+            assertTrue("MNGer message not logged", results.size() > 0);
+
+            String log = getLogMessage(results, 0);
+
+            //1
+            validateMessageID("MNG-1006", log);
+
+            // Validate we only have two MNG-1002 (one via stdout, one via log4j)
+            results = findMatches("MNG-1006");
+            assertEquals("Upexpected SSL Keystore message count",
+                         2, results.size());
+
+            // Validate the keystore path is as expected
+            assertTrue("SSL Keystore entry expected.:" + getMessageString(log),
+                       getMessageString(log).endsWith(TestSSLConstants.BROKER_KEYSTORE));
+        }
+    }
+
+    /**
+     * Description: Tests the management connection open/close are logged correctly.
+     *
+     * Output:
+     *
+     *  MESSAGE MNG-1007 : Open : User 
+     *  MESSAGE MNG-1008 : Close : User 
+     *
+     * Validation Steps:
+     *
+     * 1. The MNG ID is correct
+     * 2. The message and username are correct
+     */
+    public void testManagementUserOpenClose() throws Exception
+    {
+        if (isJavaBroker())
+        {
+            setSystemProperty(BrokerProperties.PROPERTY_USE_CUSTOM_RMI_SOCKET_FACTORY, "false");
+            startBrokerAndCreateMonitor(true, false);
+
+            final JMXTestUtils jmxUtils = new JMXTestUtils(this);
+            List openResults = null;
+            List closeResults = null;
+            try
+            {
+                jmxUtils.setUp();
+                jmxUtils.open();
+                openResults = waitAndFindMatches("MNG-1007");
+            }
+            finally
+            {
+                if (jmxUtils != null)
+                {
+                    jmxUtils.close();
+                    closeResults = waitAndFindMatches("MNG-1008");
+                }
+            }
+
+            assertNotNull("Management Open results null", openResults.size());
+            assertEquals("Management Open logged unexpected number of times", 1, openResults.size());
+
+            assertNotNull("Management Close results null", closeResults.size());
+            assertEquals("Management Close logged unexpected number of times", 1, closeResults.size());
+
+            final String openMessage = getMessageString(getLogMessage(openResults, 0));
+            assertTrue("Unexpected open message " + openMessage, openMessage.endsWith("Open : User admin"));
+            final String closeMessage = getMessageString(getLogMessage(closeResults, 0));
+            assertTrue("Unexpected close message " + closeMessage, closeMessage.endsWith("Close : User admin"));
+        }
+    }
+
+    private void startBrokerAndCreateMonitor(boolean managementEnabled, boolean useManagementSSL) throws Exception
+    {
+        TestBrokerConfiguration config = getBrokerConfiguration();
+
+        if (managementEnabled)
+        {
+            config.addJmxManagementConfiguration();
+        }
+
+        if(useManagementSSL)
+        {
+            // This test requires we have an ssl connection
+            config.setObjectAttribute(TestBrokerConfiguration.ENTRY_NAME_JMX_PORT, Port.TRANSPORTS, Collections.singleton(Transport.SSL));
+
+            setSystemProperty("javax.net.ssl.keyStore", "test-profiles/test_resources/ssl/java_broker_keystore.jks");
+            setSystemProperty("javax.net.ssl.keyStorePassword", "password");
+        }
+
+        startBroker();
+
+        // Now we can create the monitor as _outputFile will now be defined
+        _monitor = new LogMonitor(_outputFile);
+    }
+}
diff --git a/java/systests/src/main/java/org/apache/qpid/systest/management/jmx/QueueManagementTest.java b/java/systests/src/main/java/org/apache/qpid/systest/management/jmx/QueueManagementTest.java
new file mode 100644
index 0000000000..0d3289d1bd
--- /dev/null
+++ b/java/systests/src/main/java/org/apache/qpid/systest/management/jmx/QueueManagementTest.java
@@ -0,0 +1,778 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.qpid.systest.management.jmx;
+
+import org.apache.commons.lang.time.FastDateFormat;
+
+import org.apache.log4j.Logger;
+import org.apache.qpid.client.AMQSession;
+import org.apache.qpid.configuration.ClientProperties;
+import org.apache.qpid.framing.AMQShortString;
+import org.apache.qpid.management.common.mbeans.ManagedBroker;
+import org.apache.qpid.management.common.mbeans.ManagedQueue;
+import org.apache.qpid.server.queue.AMQQueueFactory;
+import org.apache.qpid.server.queue.NotificationCheckTest;
+import org.apache.qpid.server.queue.SimpleAMQQueueTest;
+import org.apache.qpid.test.client.destination.AddressBasedDestinationTest;
+import org.apache.qpid.test.utils.JMXTestUtils;
+import org.apache.qpid.test.utils.QpidBrokerTestCase;
+
+import javax.jms.Connection;
+import javax.jms.Destination;
+import javax.jms.JMSException;
+import javax.jms.Message;
+import javax.jms.MessageConsumer;
+import javax.jms.MessageListener;
+import javax.jms.Queue;
+import javax.jms.Session;
+import javax.jms.TextMessage;
+import javax.management.Notification;
+import javax.management.NotificationListener;
+import javax.management.openmbean.CompositeData;
+import javax.management.openmbean.TabularData;
+import javax.naming.NamingException;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.SortedSet;
+import java.util.TreeSet;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicInteger;
+import java.util.concurrent.atomic.AtomicReference;
+
+/**
+ * Tests the JMX API for the Managed Queue.
+ *
+ */
+public class QueueManagementTest extends QpidBrokerTestCase
+{
+
+    private static final Logger LOGGER = Logger.getLogger(QueueManagementTest.class);
+
+    private static final String VIRTUAL_HOST = "test";
+    private static final String TEST_QUEUE_DESCRIPTION = "my description";
+
+    private JMXTestUtils _jmxUtils;
+    private Connection _connection;
+    private Session _session;
+
+    private String _sourceQueueName;
+    private String _destinationQueueName;
+    private Destination _sourceQueue;
+    private Destination _destinationQueue;
+    private ManagedQueue _managedSourceQueue;
+    private ManagedQueue _managedDestinationQueue;
+
+    public void setUp() throws Exception
+    {
+        _jmxUtils = new JMXTestUtils(this);
+        _jmxUtils.setUp();
+
+        super.setUp();
+        _sourceQueueName = getTestQueueName() + "_src";
+        _destinationQueueName = getTestQueueName() + "_dest";
+
+        createConnectionAndSession();
+
+        _sourceQueue = _session.createQueue(_sourceQueueName);
+        _destinationQueue = _session.createQueue(_destinationQueueName);
+        createQueueOnBroker(_sourceQueue);
+        createQueueOnBroker(_destinationQueue);
+
+        _jmxUtils.open();
+
+        createManagementInterfacesForQueues();
+    }
+
+    public void tearDown() throws Exception
+    {
+        if (_jmxUtils != null)
+        {
+            _jmxUtils.close();
+        }
+        super.tearDown();
+    }
+
+    public void testQueueAttributes() throws Exception
+    {
+        Queue queue = _session.createQueue(getTestQueueName());
+        createQueueOnBroker(queue);
+
+        final String queueName = queue.getQueueName();
+
+        final ManagedQueue managedQueue = _jmxUtils.getManagedQueue(queueName);
+        assertEquals("Unexpected name", queueName, managedQueue.getName());
+        assertEquals("Unexpected queue type", "standard", managedQueue.getQueueType());
+    }
+
+    public void testExclusiveQueueHasJmsClientIdAsOwner() throws Exception
+    {
+        Queue tmpQueue = _session.createTemporaryQueue();
+
+        final String queueName = tmpQueue.getQueueName();
+
+        final ManagedQueue managedQueue = _jmxUtils.getManagedQueue(queueName);
+        assertNotNull(_connection.getClientID());
+        assertEquals("Unexpected owner", _connection.getClientID(), managedQueue.getOwner());
+    }
+
+    public void testNonExclusiveQueueHasNoOwner() throws Exception
+    {
+        Queue nonExclusiveQueue = _session.createQueue(getTestQueueName());
+        createQueueOnBroker(nonExclusiveQueue);
+
+        final String queueName = nonExclusiveQueue.getQueueName();
+
+        final ManagedQueue managedQueue = _jmxUtils.getManagedQueue(queueName);
+        assertNull("Unexpected owner", managedQueue.getOwner());
+    }
+
+    public void testSetNewQueueDescriptionOnExistingQueue() throws Exception
+    {
+        Queue queue = _session.createQueue(getTestQueueName());
+        createQueueOnBroker(queue);
+
+        final String queueName = queue.getQueueName();
+
+        final ManagedQueue managedQueue = _jmxUtils.getManagedQueue(queueName);
+        assertNull("Unexpected description", managedQueue.getDescription());
+
+        managedQueue.setDescription(TEST_QUEUE_DESCRIPTION);
+        assertEquals(TEST_QUEUE_DESCRIPTION, managedQueue.getDescription());
+    }
+
+    public void testNewQueueWithDescription() throws Exception
+    {
+        String queueName = getTestQueueName();
+        Map arguments = Collections.singletonMap(AMQQueueFactory.X_QPID_DESCRIPTION, (Object)TEST_QUEUE_DESCRIPTION);
+        ((AMQSession)_session).createQueue(AMQShortString.valueOf(queueName), false, true, false, arguments);
+
+        final ManagedQueue managedQueue = _jmxUtils.getManagedQueue(queueName);
+        assertEquals(TEST_QUEUE_DESCRIPTION, managedQueue.getDescription());
+    }
+
+    /**
+     * Requires persistent store.
+     */
+    public void testQueueDescriptionSurvivesRestart() throws Exception
+    {
+        String queueName = getTestQueueName();
+        Map arguments = Collections.singletonMap(AMQQueueFactory.X_QPID_DESCRIPTION, (Object)TEST_QUEUE_DESCRIPTION);
+
+        ((AMQSession)_session).createQueue(AMQShortString.valueOf(queueName), false, true, false, arguments);
+
+        ManagedQueue managedQueue = _jmxUtils.getManagedQueue(queueName);
+        assertEquals(TEST_QUEUE_DESCRIPTION, managedQueue.getDescription());
+
+        restartBroker();
+
+        managedQueue = _jmxUtils.getManagedQueue(queueName);
+        assertEquals(TEST_QUEUE_DESCRIPTION, managedQueue.getDescription());
+    }
+
+    /**
+     * Tests queue creation with {@link AMQQueueFactory#X_QPID_MAXIMUM_DELIVERY_COUNT} argument.  Also tests
+     * that the attribute is exposed correctly through {@link ManagedQueue#getMaximumDeliveryCount()}.
+     */
+    public void testCreateQueueWithMaximumDeliveryCountSet() throws Exception
+    {
+        final String queueName = getName();
+        final ManagedBroker managedBroker = _jmxUtils.getManagedBroker(VIRTUAL_HOST);
+
+        final Integer deliveryCount = 1;
+        final Map arguments = Collections.singletonMap(AMQQueueFactory.X_QPID_MAXIMUM_DELIVERY_COUNT, (Object)deliveryCount);
+        managedBroker.createNewQueue(queueName, null, true, arguments);
+
+        // Ensure the queue exists
+        assertNotNull("Queue object name expected to exist", _jmxUtils.getQueueObjectName(VIRTUAL_HOST, queueName));
+        assertNotNull("Manager queue expected to be available", _jmxUtils.getManagedQueue(queueName));
+
+        final ManagedQueue managedQueue = _jmxUtils.getManagedQueue(queueName);
+        assertEquals("Unexpected maximum delivery count", deliveryCount, managedQueue.getMaximumDeliveryCount());
+    }
+
+    public void testCreateQueueWithAlertingThresholdsSet() throws Exception
+    {
+        final String queueName = getName();
+        final ManagedBroker managedBroker = _jmxUtils.getManagedBroker(VIRTUAL_HOST);
+
+        final Long maximumMessageCount = 100l;
+        final Long maximumMessageSize = 200l;
+        final Long maximumQueueDepth = 300l;
+        final Long maximumMessageAge = 400l;
+        final Map arguments = new HashMap();
+        arguments.put(AMQQueueFactory.X_QPID_MAXIMUM_MESSAGE_COUNT, maximumMessageCount);
+        arguments.put(AMQQueueFactory.X_QPID_MAXIMUM_MESSAGE_SIZE, maximumMessageSize);
+        arguments.put(AMQQueueFactory.X_QPID_MAXIMUM_QUEUE_DEPTH, maximumQueueDepth);
+        arguments.put(AMQQueueFactory.X_QPID_MAXIMUM_MESSAGE_AGE, maximumMessageAge);
+
+        managedBroker.createNewQueue(queueName, null, true, arguments);
+
+        // Ensure the queue exists
+        assertNotNull("Queue object name expected to exist", _jmxUtils.getQueueObjectName(VIRTUAL_HOST, queueName));
+        assertNotNull("Manager queue expected to be available", _jmxUtils.getManagedQueue(queueName));
+
+        ManagedQueue managedQueue = _jmxUtils.getManagedQueue(queueName);
+        assertEquals("Unexpected maximum message count", maximumMessageCount, managedQueue.getMaximumMessageCount());
+        assertEquals("Unexpected maximum message size", maximumMessageSize, managedQueue.getMaximumMessageSize());
+        assertEquals("Unexpected maximum queue depth", maximumQueueDepth, managedQueue.getMaximumQueueDepth());
+        assertEquals("Unexpected maximum message age", maximumMessageAge, managedQueue.getMaximumMessageAge());
+    }
+
+    /**
+     * Requires 0-10 as relies on ADDR addresses.
+     * @see AddressBasedDestinationTest for the testing of message routing to the alternate exchange
+     */
+    public void testGetSetAlternateExchange() throws Exception
+    {
+        String queueName = getTestQueueName();
+        String altExchange = "amq.fanout";
+        String addrWithAltExch = String.format("ADDR:%s;{create:always,node:{type:queue,x-declare:{alternate-exchange:'%s'}}}", queueName, altExchange);
+        Queue queue = _session.createQueue(addrWithAltExch);
+
+        createQueueOnBroker(queue);
+
+        final ManagedQueue managedQueue = _jmxUtils.getManagedQueue(queueName);
+        assertEquals("Newly created queue does not have expected alternate exchange", altExchange, managedQueue.getAlternateExchange());
+
+        String newAltExch = "amq.topic";
+        managedQueue.setAlternateExchange(newAltExch);
+        assertEquals("Unexpected alternate exchange after set", newAltExch, managedQueue.getAlternateExchange());
+    }
+
+    /**
+     * Requires 0-10 as relies on ADDR addresses.
+     */
+    public void testRemoveAlternateExchange() throws Exception
+    {
+        String queueName = getTestQueueName();
+        String altExchange = "amq.fanout";
+        String addrWithAltExch = String.format("ADDR:%s;{create:always,node:{type:queue,x-declare:{alternate-exchange:'%s'}}}", queueName, altExchange);
+        Queue queue = _session.createQueue(addrWithAltExch);
+
+        createQueueOnBroker(queue);
+
+        final ManagedQueue managedQueue = _jmxUtils.getManagedQueue(queueName);
+        assertEquals("Newly created queue does not have expected alternate exchange", altExchange, managedQueue.getAlternateExchange());
+
+        managedQueue.setAlternateExchange("");
+        assertNull("Unexpected alternate exchange after set", managedQueue.getAlternateExchange());
+    }
+
+    /**
+     * Requires persistent store
+     * Requires 0-10 as relies on ADDR addresses.
+     */
+    public void testAlternateExchangeSurvivesRestart() throws Exception
+    {
+        String nonMandatoryExchangeName = "exch" + getName();
+
+        final ManagedBroker managedBroker = _jmxUtils.getManagedBroker(VIRTUAL_HOST);
+        managedBroker.createNewExchange(nonMandatoryExchangeName, "fanout", true);
+
+        String queueName1 = getTestQueueName() + "1";
+        String altExchange1 = "amq.fanout";
+        String addr1WithAltExch = String.format("ADDR:%s;{create:always,node:{durable: true,type:queue,x-declare:{alternate-exchange:'%s'}}}", queueName1, altExchange1);
+        Queue queue1 = _session.createQueue(addr1WithAltExch);
+
+        String queueName2 = getTestQueueName() + "2";
+        String addr2WithoutAltExch = String.format("ADDR:%s;{create:always,node:{durable: true,type:queue}}", queueName2);
+        Queue queue2 = _session.createQueue(addr2WithoutAltExch);
+
+        createQueueOnBroker(queue1);
+        createQueueOnBroker(queue2);
+
+        ManagedQueue managedQueue1 = _jmxUtils.getManagedQueue(queueName1);
+        assertEquals("Newly created queue1 does not have expected alternate exchange", altExchange1, managedQueue1.getAlternateExchange());
+
+        ManagedQueue managedQueue2 = _jmxUtils.getManagedQueue(queueName2);
+        assertNull("Newly created queue2 does not have expected alternate exchange", managedQueue2.getAlternateExchange());
+
+        String altExchange2 = nonMandatoryExchangeName;
+        managedQueue2.setAlternateExchange(altExchange2);
+
+        restartBroker();
+
+        managedQueue1 = _jmxUtils.getManagedQueue(queueName1);
+        assertEquals("Queue1 does not have expected alternate exchange after restart", altExchange1, managedQueue1.getAlternateExchange());
+
+        managedQueue2 = _jmxUtils.getManagedQueue(queueName2);
+        assertEquals("Queue2 does not have expected updated alternate exchange after restart", altExchange2, managedQueue2.getAlternateExchange());
+    }
+
+    /**
+     * Tests the ability to receive queue alerts as JMX notifications.
+     *
+     * @see NotificationCheckTest
+     * @see SimpleAMQQueueTest#testNotificationFiredAsync()
+     * @see SimpleAMQQueueTest#testNotificationFiredOnEnqueue()
+     */
+    public void testQueueNotification() throws Exception
+    {
+        final String queueName = getName();
+        final long maximumMessageCount = 3;
+
+        Queue queue = _session.createQueue(queueName);
+        createQueueOnBroker(queue);
+
+        ManagedQueue managedQueue = _jmxUtils.getManagedQueue(queueName);
+        managedQueue.setMaximumMessageCount(maximumMessageCount);
+
+        RecordingNotificationListener listener = new RecordingNotificationListener(1);
+
+        _jmxUtils.addNotificationListener(_jmxUtils.getQueueObjectName(VIRTUAL_HOST, queueName), listener, null, null);
+
+        // Send two messages - this should *not* trigger the notification
+        sendMessage(_session, queue, 2);
+
+        assertEquals("Premature notification received", 0, listener.getNumberOfNotificationsReceived());
+
+        // A further message should trigger the message count alert
+        sendMessage(_session, queue, 1);
+
+        listener.awaitExpectedNotifications(5, TimeUnit.SECONDS);
+
+        assertEquals("Unexpected number of JMX notifications received", 1, listener.getNumberOfNotificationsReceived());
+
+        Notification notification = listener.getLastNotification();
+        assertEquals("Unexpected notification message", "MESSAGE_COUNT_ALERT 3: Maximum count on queue threshold (3) breached.", notification.getMessage());
+    }
+
+    /**
+     * Tests {@link ManagedQueue#viewMessages(long, long)} interface.
+     */
+    public void testViewSingleMessage() throws Exception
+    {
+        final List sentMessages = sendMessage(_session, _sourceQueue, 1);
+        syncSession(_session);
+        final Message sentMessage = sentMessages.get(0);
+
+        assertEquals("Unexpected queue depth", 1, _managedSourceQueue.getMessageCount().intValue());
+
+        // Check the contents of the message
+        final TabularData tab = _managedSourceQueue.viewMessages(1l, 1l);
+        assertEquals("Unexpected number of rows in table", 1, tab.size());
+        final Iterator rowItr = (Iterator) tab.values().iterator();
+
+        final CompositeData row1 = rowItr.next();
+        assertNotNull("Message should have AMQ message id", row1.get(ManagedQueue.MSG_AMQ_ID));
+        assertEquals("Unexpected queue position", 1l, row1.get(ManagedQueue.MSG_QUEUE_POS));
+        assertEquals("Unexpected redelivered flag", Boolean.FALSE, row1.get(ManagedQueue.MSG_REDELIVERED));
+
+        // Check the contents of header (encoded in a string array)
+        final String[] headerArray = (String[]) row1.get(ManagedQueue.MSG_HEADER);
+        assertNotNull("Expected message header array", headerArray);
+        final Map headers = headerArrayToMap(headerArray);
+
+        final String expectedJMSMessageID = isBroker010() ? sentMessage.getJMSMessageID().replace("ID:", "") : sentMessage.getJMSMessageID();
+        final String expectedFormattedJMSTimestamp = FastDateFormat.getInstance(ManagedQueue.JMSTIMESTAMP_DATETIME_FORMAT).format(sentMessage.getJMSTimestamp());
+        assertEquals("Unexpected JMSMessageID within header", expectedJMSMessageID, headers.get("JMSMessageID"));
+        assertEquals("Unexpected JMSPriority within header", String.valueOf(sentMessage.getJMSPriority()), headers.get("JMSPriority"));
+        assertEquals("Unexpected JMSTimestamp within header", expectedFormattedJMSTimestamp, headers.get("JMSTimestamp"));
+    }
+
+    /**
+     * Tests {@link ManagedQueue#moveMessages(long, long, String)} interface.
+     */
+    public void testMoveMessagesBetweenQueues() throws Exception
+    {
+        final int numberOfMessagesToSend = 10;
+
+        sendMessage(_session, _sourceQueue, numberOfMessagesToSend);
+        syncSession(_session);
+        assertEquals("Unexpected queue depth after send", numberOfMessagesToSend, _managedSourceQueue.getMessageCount().intValue());
+
+        List amqMessagesIds = getAMQMessageIdsOn(_managedSourceQueue, 1, numberOfMessagesToSend);
+
+        // Move first three messages to destination
+        long fromMessageId = amqMessagesIds.get(0);
+        long toMessageId = amqMessagesIds.get(2);
+        _managedSourceQueue.moveMessages(fromMessageId, toMessageId, _destinationQueueName);
+
+        assertEquals("Unexpected queue depth on destination queue after first move", 3, _managedDestinationQueue.getMessageCount().intValue());
+        assertEquals("Unexpected queue depth on source queue after first move", 7, _managedSourceQueue.getMessageCount().intValue());
+
+        // Now move a further two messages to destination
+        fromMessageId = amqMessagesIds.get(7);
+        toMessageId = amqMessagesIds.get(8);
+        _managedSourceQueue.moveMessages(fromMessageId, toMessageId, _destinationQueueName);
+        assertEquals("Unexpected queue depth on destination queue after second move", 5, _managedDestinationQueue.getMessageCount().intValue());
+        assertEquals("Unexpected queue depth on source queue after second move", 5, _managedSourceQueue.getMessageCount().intValue());
+
+        assertMessageIndicesOn(_destinationQueue, 0, 1, 2, 7, 8);
+    }
+
+    /**
+     * Tests {@link ManagedQueue#copyMessages(long, long, String)} interface.
+     */
+    public void testCopyMessagesBetweenQueues() throws Exception
+    {
+        final int numberOfMessagesToSend = 10;
+        sendMessage(_session, _sourceQueue, numberOfMessagesToSend);
+        syncSession(_session);
+        assertEquals("Unexpected queue depth after send", numberOfMessagesToSend, _managedSourceQueue.getMessageCount().intValue());
+
+        List amqMessagesIds = getAMQMessageIdsOn(_managedSourceQueue, 1, numberOfMessagesToSend);
+
+        // Copy first three messages to destination
+        long fromMessageId = amqMessagesIds.get(0);
+        long toMessageId = amqMessagesIds.get(2);
+        _managedSourceQueue.copyMessages(fromMessageId, toMessageId, _destinationQueueName);
+
+        assertEquals("Unexpected queue depth on destination queue after first copy", 3, _managedDestinationQueue.getMessageCount().intValue());
+        assertEquals("Unexpected queue depth on source queue after first copy", numberOfMessagesToSend, _managedSourceQueue.getMessageCount().intValue());
+
+        // Now copy a further two messages to destination
+        fromMessageId = amqMessagesIds.get(7);
+        toMessageId = amqMessagesIds.get(8);
+        _managedSourceQueue.copyMessages(fromMessageId, toMessageId, _destinationQueueName);
+        assertEquals("Unexpected queue depth on destination queue after second copy", 5, _managedDestinationQueue.getMessageCount().intValue());
+        assertEquals("Unexpected queue depth on source queue after second copy", numberOfMessagesToSend, _managedSourceQueue.getMessageCount().intValue());
+
+        assertMessageIndicesOn(_destinationQueue, 0, 1, 2, 7, 8);
+    }
+
+    public void testMoveMessagesBetweenQueuesWithActiveConsumerOnSourceQueue() throws Exception
+    {
+        setTestClientSystemProperty(ClientProperties.MAX_PREFETCH_PROP_NAME, new Integer(1).toString());
+        Connection asyncConnection = getConnection();
+        asyncConnection.start();
+
+        final int numberOfMessagesToSend = 50;
+        sendMessage(_session, _sourceQueue, numberOfMessagesToSend);
+        syncSession(_session);
+        assertEquals("Unexpected queue depth after send", numberOfMessagesToSend, _managedSourceQueue.getMessageCount().intValue());
+
+        List amqMessagesIds = getAMQMessageIdsOn(_managedSourceQueue, 1, numberOfMessagesToSend);
+
+        long fromMessageId = amqMessagesIds.get(0);
+        long toMessageId = amqMessagesIds.get(numberOfMessagesToSend - 1);
+
+        CountDownLatch consumerReadToHalfwayLatch = new CountDownLatch(numberOfMessagesToSend / 2);
+        AtomicInteger totalConsumed = new AtomicInteger(0);
+        startAsyncConsumerOn(_sourceQueue, asyncConnection, consumerReadToHalfwayLatch, totalConsumed);
+
+        boolean halfwayPointReached = consumerReadToHalfwayLatch.await(5000, TimeUnit.MILLISECONDS);
+        assertTrue("Did not read half of messages within time allowed", halfwayPointReached);
+
+        _managedSourceQueue.moveMessages(fromMessageId, toMessageId, _destinationQueueName);
+
+        asyncConnection.stop();
+
+        // The exact number of messages moved will be non deterministic, as the number of messages processed
+        // by the consumer cannot be predicted.  There is also the possibility that a message can remain
+        // on the source queue.  This situation will arise if a message has been acquired by the consumer, but not
+        // yet delivered to the client application (i.e. MessageListener#onMessage()) when the Connection#stop() occurs.
+        //
+        // The number of messages moved + the number consumed + any messages remaining on source should
+        // *always* be equal to the number we originally sent.
+
+        int numberOfMessagesReadByConsumer = totalConsumed.intValue();
+        int numberOfMessagesOnDestinationQueue = _managedDestinationQueue.getMessageCount().intValue();
+        int numberOfMessagesRemainingOnSourceQueue = _managedSourceQueue.getMessageCount().intValue();
+
+        LOGGER.debug("Async consumer read : " + numberOfMessagesReadByConsumer
+                + " Number of messages moved to destination : " + numberOfMessagesOnDestinationQueue
+                + " Number of messages remaining on source : " + numberOfMessagesRemainingOnSourceQueue);
+        assertEquals("Unexpected number of messages after move", numberOfMessagesToSend, numberOfMessagesReadByConsumer + numberOfMessagesOnDestinationQueue + numberOfMessagesRemainingOnSourceQueue);
+    }
+
+    public void testMoveMessagesBetweenQueuesWithActiveConsumerOnDestinationQueue() throws Exception
+    {
+        setTestClientSystemProperty(ClientProperties.MAX_PREFETCH_PROP_NAME, new Integer(1).toString());
+        Connection asyncConnection = getConnection();
+        asyncConnection.start();
+
+        final int numberOfMessagesToSend = 50;
+        sendMessage(_session, _sourceQueue, numberOfMessagesToSend);
+        syncSession(_session);
+        assertEquals("Unexpected queue depth after send", numberOfMessagesToSend, _managedSourceQueue.getMessageCount().intValue());
+
+        List amqMessagesIds = getAMQMessageIdsOn(_managedSourceQueue, 1, numberOfMessagesToSend);
+        long fromMessageId = amqMessagesIds.get(0);
+        long toMessageId = amqMessagesIds.get(numberOfMessagesToSend - 1);
+
+        AtomicInteger totalConsumed = new AtomicInteger(0);
+        CountDownLatch allMessagesConsumedLatch = new CountDownLatch(numberOfMessagesToSend);
+        startAsyncConsumerOn(_destinationQueue, asyncConnection, allMessagesConsumedLatch, totalConsumed);
+
+        _managedSourceQueue.moveMessages(fromMessageId, toMessageId, _destinationQueueName);
+
+        allMessagesConsumedLatch.await(5000, TimeUnit.MILLISECONDS);
+        assertEquals("Did not consume all messages from destination queue", numberOfMessagesToSend, totalConsumed.intValue());
+    }
+
+    /**
+     * Tests {@link ManagedQueue#moveMessages(long, long, String)} interface.
+     */
+    public void testMoveMessageBetweenQueuesWithBrokerRestart() throws Exception
+    {
+        final int numberOfMessagesToSend = 1;
+
+        sendMessage(_session, _sourceQueue, numberOfMessagesToSend);
+        syncSession(_session);
+        assertEquals("Unexpected queue depth after send", numberOfMessagesToSend, _managedSourceQueue.getMessageCount().intValue());
+
+        restartBroker();
+
+        createManagementInterfacesForQueues();
+        createConnectionAndSession();
+
+        List amqMessagesIds = getAMQMessageIdsOn(_managedSourceQueue, 1, numberOfMessagesToSend);
+
+        // Move messages to destination
+        long messageId = amqMessagesIds.get(0);
+        _managedSourceQueue.moveMessages(messageId, messageId, _destinationQueueName);
+
+        assertEquals("Unexpected queue depth on destination queue after move", 1, _managedDestinationQueue.getMessageCount().intValue());
+        assertEquals("Unexpected queue depth on source queue after move", 0, _managedSourceQueue.getMessageCount().intValue());
+
+        assertMessageIndicesOn(_destinationQueue, 0);
+    }
+
+    /**
+     * Tests {@link ManagedQueue#copyMessages(long, long, String)} interface.
+     */
+    public void testCopyMessageBetweenQueuesWithBrokerRestart() throws Exception
+    {
+        final int numberOfMessagesToSend = 1;
+
+        sendMessage(_session, _sourceQueue, numberOfMessagesToSend);
+        syncSession(_session);
+        assertEquals("Unexpected queue depth after send", numberOfMessagesToSend, _managedSourceQueue.getMessageCount().intValue());
+
+        restartBroker();
+
+        createManagementInterfacesForQueues();
+        createConnectionAndSession();
+
+        List amqMessagesIds = getAMQMessageIdsOn(_managedSourceQueue, 1, numberOfMessagesToSend);
+
+        // Move messages to destination
+        long messageId = amqMessagesIds.get(0);
+        _managedSourceQueue.copyMessages(messageId, messageId, _destinationQueueName);
+
+        assertEquals("Unexpected queue depth on destination queue after copy", 1, _managedDestinationQueue.getMessageCount().intValue());
+        assertEquals("Unexpected queue depth on source queue after copy", 1, _managedSourceQueue.getMessageCount().intValue());
+
+        assertMessageIndicesOn(_destinationQueue, 0);
+    }
+
+    /**
+     * Tests {@link ManagedQueue#deleteMessages(long, long)} interface.
+     */
+    public void testDeleteMessages() throws Exception
+    {
+        final int numberOfMessagesToSend = 15;
+
+        sendMessage(_session, _sourceQueue, numberOfMessagesToSend);
+        syncSession(_session);
+        assertEquals("Unexpected queue depth after send", numberOfMessagesToSend, _managedSourceQueue.getMessageCount().intValue());
+        List amqMessagesIds = getAMQMessageIdsOn(_managedSourceQueue, 1, numberOfMessagesToSend);
+        // Current expected queue state, in terms of message header indices: [0,1,2,3,4,5,6,7,8,9,10,11,12,13,14]
+
+        // Delete the first message (Remember the amqMessagesIds list, and the message indices added as a property when sending, are both 0-based index)
+        long fromMessageId = amqMessagesIds.get(0);
+        long toMessageId = fromMessageId;
+        _managedSourceQueue.deleteMessages(fromMessageId, toMessageId);
+        assertEquals("Unexpected message count after first deletion", numberOfMessagesToSend - 1, _managedSourceQueue.getMessageCount().intValue());
+        // Current expected queue state, in terms of message header indices: [X,1,2,3,4,5,6,7,8,9,10,11,12,13,14]
+
+        // Delete the 9th-10th messages, in the middle of the queue
+        fromMessageId = amqMessagesIds.get(8);
+        toMessageId = amqMessagesIds.get(9);
+        _managedSourceQueue.deleteMessages(fromMessageId, toMessageId);
+        assertEquals("Unexpected message count after third deletion", numberOfMessagesToSend - 3, _managedSourceQueue.getMessageCount().intValue());
+        // Current expected queue state, in terms of message header indices: [X,1,2,3,4,5,6,7,X,X,10,11,12,13,14]
+
+        // Delete the 11th and 12th messages, but still include the IDs for the 9th and 10th messages in the
+        // range to ensure their IDs are 'skipped' until the matching messages are found
+        fromMessageId = amqMessagesIds.get(8);
+        toMessageId = amqMessagesIds.get(11);
+        _managedSourceQueue.deleteMessages(fromMessageId, toMessageId);
+        assertEquals("Unexpected message count after fourth deletion", numberOfMessagesToSend - 5, _managedSourceQueue.getMessageCount().intValue());
+        // Current expected queue state, in terms of message header indices: [X,1,2,3,4,5,6,7,X,X,X,X,12,13,14]
+
+        // Delete the 8th message and the 13th message, including the IDs for the 9th-12th messages in the
+        // range to ensure their IDs are 'skipped' and the other matching message is found
+        fromMessageId = amqMessagesIds.get(7);
+        toMessageId = amqMessagesIds.get(12);
+        _managedSourceQueue.deleteMessages(fromMessageId, toMessageId);
+        assertEquals("Unexpected message count after fourth deletion", numberOfMessagesToSend - 7, _managedSourceQueue.getMessageCount().intValue());
+        // Current expected queue state, in terms of message header indices: [X,1,2,3,4,5,6,X,X,X,X,X,X,13,14]
+
+        // Delete the last message message
+        fromMessageId = amqMessagesIds.get(numberOfMessagesToSend -1);
+        toMessageId = fromMessageId;
+        _managedSourceQueue.deleteMessages(fromMessageId, toMessageId);
+        assertEquals("Unexpected message count after second deletion", numberOfMessagesToSend - 8, _managedSourceQueue.getMessageCount().intValue());
+        // Current expected queue state, in terms of message header indices: [X,1,2,3,4,5,6,X,X,X,X,X,X,13,X]
+
+        // Verify the message indices with a consumer
+        assertMessageIndicesOn(_sourceQueue, 1,2,3,4,5,6,13);
+    }
+
+    @Override
+    public Message createNextMessage(Session session, int messageNumber) throws JMSException
+    {
+        Message message = session.createTextMessage(getContentForMessageNumber(messageNumber));
+        message.setIntProperty(INDEX, messageNumber);
+        return message;
+    }
+
+    private void startAsyncConsumerOn(Destination queue, Connection asyncConnection,
+            final CountDownLatch requiredNumberOfMessagesRead, final AtomicInteger totalConsumed) throws Exception
+    {
+        Session session = asyncConnection.createSession(false, Session.AUTO_ACKNOWLEDGE);
+        MessageConsumer consumer = session.createConsumer(queue);
+        consumer.setMessageListener(new MessageListener()
+        {
+
+            @Override
+            public void onMessage(Message arg0)
+            {
+                totalConsumed.incrementAndGet();
+                requiredNumberOfMessagesRead.countDown();
+            }
+        });
+    }
+
+    private void assertMessageIndicesOn(Destination queue, int... expectedIndices) throws Exception
+    {
+        MessageConsumer consumer = _session.createConsumer(queue);
+
+        for (int i : expectedIndices)
+        {
+            TextMessage message = (TextMessage)consumer.receive(1000);
+            assertNotNull("Expected message with index " + i, message);
+            assertEquals("Expected message with index " + i, i, message.getIntProperty(INDEX));
+            assertEquals("Expected message content", getContentForMessageNumber(i), message.getText());
+        }
+
+        assertNull("Unexpected message encountered", consumer.receive(1000));
+    }
+
+    private List getAMQMessageIdsOn(ManagedQueue managedQueue, long startIndex, long endIndex) throws Exception
+    {
+        final SortedSet messageIds = new TreeSet();
+
+        final TabularData tab = managedQueue.viewMessages(startIndex, endIndex);
+        final Iterator rowItr = (Iterator) tab.values().iterator();
+        while(rowItr.hasNext())
+        {
+            final CompositeData row = rowItr.next();
+            long amqMessageId = (Long)row.get(ManagedQueue.MSG_AMQ_ID);
+            messageIds.add(amqMessageId);
+        }
+
+        return new ArrayList(messageIds);
+    }
+
+    /**
+     *
+     * Utility method to convert array of Strings in the form x = y into a
+     * map with key/value x => y.
+     *
+     */
+    private Map headerArrayToMap(final String[] headerArray)
+    {
+        final Map headerMap = new HashMap();
+        final List headerList = Arrays.asList(headerArray);
+        for (Iterator iterator = headerList.iterator(); iterator.hasNext();)
+        {
+            final String nameValuePair = iterator.next();
+            final String[] nameValue = nameValuePair.split(" *= *", 2);
+            headerMap.put(nameValue[0], nameValue[1]);
+        }
+        return headerMap;
+    }
+
+    private void createQueueOnBroker(Destination destination) throws JMSException
+    {
+        _session.createConsumer(destination).close(); // Create a consumer only to cause queue creation
+    }
+
+    private void syncSession(Session session) throws Exception
+    {
+        ((AMQSession)session).sync();
+    }
+
+    private void createConnectionAndSession() throws JMSException,
+            NamingException
+    {
+        _connection = getConnection();
+        _connection.start();
+        _session = _connection.createSession(true, Session.SESSION_TRANSACTED);
+    }
+
+    private void createManagementInterfacesForQueues()
+    {
+        _managedSourceQueue = _jmxUtils.getManagedQueue(_sourceQueueName);
+        _managedDestinationQueue = _jmxUtils.getManagedQueue(_destinationQueueName);
+    }
+
+    private String getContentForMessageNumber(int msgCount)
+    {
+        return "Message count " + msgCount;
+    }
+
+    private final class RecordingNotificationListener implements NotificationListener
+    {
+        private final CountDownLatch _notificationReceivedLatch;
+        private final AtomicInteger _numberOfNotifications;
+        private final AtomicReference _lastNotification;
+
+        private RecordingNotificationListener(int expectedNumberOfNotifications)
+        {
+            _notificationReceivedLatch = new CountDownLatch(expectedNumberOfNotifications);
+            _numberOfNotifications = new AtomicInteger(0);
+            _lastNotification = new AtomicReference();
+        }
+
+        @Override
+        public void handleNotification(Notification notification, Object handback)
+        {
+            _lastNotification.set(notification);
+            _numberOfNotifications.incrementAndGet();
+            _notificationReceivedLatch.countDown();
+        }
+
+        public int getNumberOfNotificationsReceived()
+        {
+            return _numberOfNotifications.get();
+        }
+
+        public Notification getLastNotification()
+        {
+            return _lastNotification.get();
+        }
+
+        public void awaitExpectedNotifications(long timeout, TimeUnit timeunit) throws InterruptedException
+        {
+            _notificationReceivedLatch.await(timeout, timeunit);
+        }
+    }
+
+}
diff --git a/java/systests/src/main/java/org/apache/qpid/systest/management/jmx/StatisticsTest.java b/java/systests/src/main/java/org/apache/qpid/systest/management/jmx/StatisticsTest.java
new file mode 100644
index 0000000000..72fbd65acc
--- /dev/null
+++ b/java/systests/src/main/java/org/apache/qpid/systest/management/jmx/StatisticsTest.java
@@ -0,0 +1,210 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.qpid.systest.management.jmx;
+
+import java.util.List;
+
+import javax.jms.Connection;
+import javax.jms.MessageConsumer;
+import javax.jms.Queue;
+import javax.jms.Session;
+
+import org.apache.qpid.client.AMQConnection;
+import org.apache.qpid.client.AMQSession;
+import org.apache.qpid.management.common.mbeans.ManagedBroker;
+import org.apache.qpid.management.common.mbeans.ManagedConnection;
+import org.apache.qpid.management.common.mbeans.ServerInformation;
+import org.apache.qpid.test.utils.JMXTestUtils;
+import org.apache.qpid.test.utils.QpidBrokerTestCase;
+
+public class StatisticsTest extends QpidBrokerTestCase
+{
+    private static final String TEST_VIRTUALHOST1 = "test1";
+    private static final String TEST_VIRTUALHOST2 = "test2";
+
+    private static final String TEST_USER = "admin";
+    private static final String TEST_PASSWORD = "admin";
+    private static final int MESSAGE_COUNT_TEST = 5;
+    private static final int MESSAGE_COUNT_DEV = 9;
+
+    private JMXTestUtils _jmxUtils;
+    private Connection _vhost1Connection, _vhost2Connection;
+    private Session _vhost1Session, _vhost2Session;
+    private Queue _vhost1Queue, _vhost2Queue;
+    protected String _brokerUrl;
+
+    @Override
+    public void setUp() throws Exception
+    {
+        createTestVirtualHost(0, TEST_VIRTUALHOST1);
+        createTestVirtualHost(0, TEST_VIRTUALHOST2);
+
+        _jmxUtils = new JMXTestUtils(this, TEST_USER, TEST_PASSWORD);
+        _jmxUtils.setUp();
+
+        super.setUp();
+
+        _brokerUrl = getBroker().toString();
+        _vhost1Connection = new AMQConnection(_brokerUrl, TEST_USER, TEST_PASSWORD, "clientid", TEST_VIRTUALHOST1);
+        _vhost2Connection = new AMQConnection(_brokerUrl, TEST_USER, TEST_PASSWORD, "clientid", TEST_VIRTUALHOST2);
+        _vhost1Connection.start();
+        _vhost2Connection.start();
+
+        _vhost1Session = _vhost1Connection.createSession(true, Session.SESSION_TRANSACTED);
+        _vhost2Session = _vhost2Connection.createSession(true, Session.SESSION_TRANSACTED);
+
+        _vhost1Queue = _vhost2Session.createQueue(getTestQueueName());
+        _vhost2Queue = _vhost1Session.createQueue(getTestQueueName());
+
+        //Create queues by opening and closing consumers
+        final MessageConsumer vhost1Consumer = _vhost1Session.createConsumer(_vhost2Queue);
+        vhost1Consumer.close();
+        final MessageConsumer vhost2Consumer = _vhost2Session.createConsumer(_vhost1Queue);
+        vhost2Consumer.close();
+
+        _jmxUtils.open();
+    }
+
+    @Override
+    public void tearDown() throws Exception
+    {
+        _jmxUtils.close();
+
+        super.tearDown();
+    }
+
+    public void testInitialStatisticValues() throws Exception
+    {
+        //Check initial values
+        checkSingleConnectionOnVHostStatistics(TEST_VIRTUALHOST1, 0, 0, 0, 0);
+        checkVHostStatistics(TEST_VIRTUALHOST1, 0, 0, 0, 0);
+        checkSingleConnectionOnVHostStatistics(TEST_VIRTUALHOST2, 0, 0, 0, 0);
+        checkVHostStatistics(TEST_VIRTUALHOST2, 0, 0, 0, 0);
+        checkBrokerStatistics(0, 0, 0, 0);
+    }
+
+    public void testSendOnSingleVHost() throws Exception
+    {
+        sendMessagesAndSync(_vhost1Session, _vhost2Queue, MESSAGE_COUNT_TEST);
+
+        //Check values
+        checkSingleConnectionOnVHostStatistics(TEST_VIRTUALHOST1, MESSAGE_COUNT_TEST, 0, MESSAGE_COUNT_TEST * DEFAULT_MESSAGE_SIZE, 0);
+        checkVHostStatistics(TEST_VIRTUALHOST1, MESSAGE_COUNT_TEST, 0, MESSAGE_COUNT_TEST * DEFAULT_MESSAGE_SIZE, 0);
+        checkSingleConnectionOnVHostStatistics(TEST_VIRTUALHOST2, 0, 0, 0, 0);
+        checkVHostStatistics(TEST_VIRTUALHOST2, 0, 0, 0, 0);
+        checkBrokerStatistics(MESSAGE_COUNT_TEST, 0, MESSAGE_COUNT_TEST * DEFAULT_MESSAGE_SIZE, 0);
+    }
+
+    public void testSendOnTwoVHosts() throws Exception
+    {
+        sendMessagesAndSync(_vhost1Session, _vhost2Queue, MESSAGE_COUNT_TEST);
+        sendMessagesAndSync(_vhost2Session, _vhost1Queue, MESSAGE_COUNT_DEV);
+
+        //Check values
+        checkSingleConnectionOnVHostStatistics(TEST_VIRTUALHOST1, MESSAGE_COUNT_TEST, 0, MESSAGE_COUNT_TEST * DEFAULT_MESSAGE_SIZE, 0);
+        checkVHostStatistics(TEST_VIRTUALHOST1, MESSAGE_COUNT_TEST, 0, MESSAGE_COUNT_TEST * DEFAULT_MESSAGE_SIZE, 0);
+        checkSingleConnectionOnVHostStatistics(TEST_VIRTUALHOST2,  MESSAGE_COUNT_DEV, 0, MESSAGE_COUNT_DEV * DEFAULT_MESSAGE_SIZE, 0);
+        checkVHostStatistics(TEST_VIRTUALHOST2,  MESSAGE_COUNT_DEV, 0, MESSAGE_COUNT_DEV * DEFAULT_MESSAGE_SIZE, 0);
+        checkBrokerStatistics(MESSAGE_COUNT_TEST + MESSAGE_COUNT_DEV, 0, (MESSAGE_COUNT_TEST + MESSAGE_COUNT_DEV) * DEFAULT_MESSAGE_SIZE, 0);
+    }
+
+    public void testSendAndConsumeOnSingleVHost() throws Exception
+    {
+        sendMessagesAndSync(_vhost1Session, _vhost2Queue, MESSAGE_COUNT_TEST);
+        consumeMessages(_vhost1Session, _vhost2Queue, MESSAGE_COUNT_TEST);
+
+        //Check values
+        checkSingleConnectionOnVHostStatistics(TEST_VIRTUALHOST1, MESSAGE_COUNT_TEST, MESSAGE_COUNT_TEST, MESSAGE_COUNT_TEST * DEFAULT_MESSAGE_SIZE, MESSAGE_COUNT_TEST * DEFAULT_MESSAGE_SIZE);
+        checkVHostStatistics(TEST_VIRTUALHOST1, MESSAGE_COUNT_TEST, MESSAGE_COUNT_TEST, MESSAGE_COUNT_TEST * DEFAULT_MESSAGE_SIZE, MESSAGE_COUNT_TEST * DEFAULT_MESSAGE_SIZE);
+        checkSingleConnectionOnVHostStatistics(TEST_VIRTUALHOST2, 0, 0, 0, 0);
+        checkVHostStatistics(TEST_VIRTUALHOST2, 0, 0, 0, 0);
+        checkBrokerStatistics(MESSAGE_COUNT_TEST, MESSAGE_COUNT_TEST, MESSAGE_COUNT_TEST * DEFAULT_MESSAGE_SIZE, MESSAGE_COUNT_TEST * DEFAULT_MESSAGE_SIZE);
+    }
+
+    public void testSendAndConsumeOnTwoVHosts() throws Exception
+    {
+        sendMessagesAndSync(_vhost1Session, _vhost2Queue, MESSAGE_COUNT_TEST);
+        sendMessagesAndSync(_vhost2Session, _vhost1Queue, MESSAGE_COUNT_DEV);
+        consumeMessages(_vhost1Session, _vhost2Queue, MESSAGE_COUNT_TEST);
+        consumeMessages(_vhost2Session, _vhost1Queue, MESSAGE_COUNT_DEV);
+
+        //Check values
+        checkSingleConnectionOnVHostStatistics(TEST_VIRTUALHOST1, MESSAGE_COUNT_TEST, MESSAGE_COUNT_TEST, MESSAGE_COUNT_TEST * DEFAULT_MESSAGE_SIZE, MESSAGE_COUNT_TEST * DEFAULT_MESSAGE_SIZE);
+        checkVHostStatistics(TEST_VIRTUALHOST1, MESSAGE_COUNT_TEST, MESSAGE_COUNT_TEST, MESSAGE_COUNT_TEST * DEFAULT_MESSAGE_SIZE, MESSAGE_COUNT_TEST * DEFAULT_MESSAGE_SIZE);
+        checkSingleConnectionOnVHostStatistics(TEST_VIRTUALHOST2,  MESSAGE_COUNT_DEV, MESSAGE_COUNT_DEV, MESSAGE_COUNT_DEV * DEFAULT_MESSAGE_SIZE, MESSAGE_COUNT_DEV * DEFAULT_MESSAGE_SIZE);
+        checkVHostStatistics(TEST_VIRTUALHOST2,  MESSAGE_COUNT_DEV, MESSAGE_COUNT_DEV, MESSAGE_COUNT_DEV * DEFAULT_MESSAGE_SIZE, MESSAGE_COUNT_DEV * DEFAULT_MESSAGE_SIZE);
+        checkBrokerStatistics(MESSAGE_COUNT_TEST + MESSAGE_COUNT_DEV, MESSAGE_COUNT_TEST + MESSAGE_COUNT_DEV, (MESSAGE_COUNT_TEST + MESSAGE_COUNT_DEV) * DEFAULT_MESSAGE_SIZE, (MESSAGE_COUNT_TEST + MESSAGE_COUNT_DEV) * DEFAULT_MESSAGE_SIZE);
+    }
+
+    private void sendMessagesAndSync(Session session, Queue queue, int numberOfMessages) throws Exception
+    {
+        //Send messages via connection on and sync
+        sendMessage(session, queue, numberOfMessages);
+        ((AMQSession)session).sync();
+    }
+
+    private void consumeMessages(Session session, Queue queue, int numberOfMessages) throws Exception
+    {
+        //consume the messages on the virtual host
+        final MessageConsumer consumer = session.createConsumer(queue);
+        for (int i = 0 ; i < numberOfMessages ; i++)
+        {
+            assertNotNull("an expected message was not received", consumer.receive(1500));
+        }
+        session.commit();
+        consumer.close();
+    }
+
+    private void checkSingleConnectionOnVHostStatistics(String vHostName, long messagesSent, long messagesReceived, long dataSent, long dataReceived)
+    {
+        List managedConnections = _jmxUtils.getManagedConnections(vHostName);
+        assertEquals(1, managedConnections.size());
+
+        ManagedConnection managedConnection = managedConnections.get(0);
+
+        assertEquals(messagesSent, managedConnection.getTotalMessagesReceived());
+        assertEquals(messagesReceived, managedConnection.getTotalMessagesDelivered());
+
+        assertEquals(dataSent, managedConnection.getTotalDataReceived());
+        assertEquals(dataReceived, managedConnection.getTotalDataDelivered());
+    }
+
+    private void checkVHostStatistics(String vHostName, long messagesSent, long messagesReceived, long dataSent, long dataReceived)
+    {
+        ManagedBroker vhost = _jmxUtils.getManagedBroker(vHostName);
+
+        assertEquals(messagesSent, vhost.getTotalMessagesReceived());
+        assertEquals(messagesReceived, vhost.getTotalMessagesDelivered());
+
+        assertEquals(dataSent, vhost.getTotalDataReceived());
+        assertEquals(dataReceived, vhost.getTotalDataDelivered());
+    }
+
+    private void checkBrokerStatistics(long messagesSent, long messagesReceived, long dataSent, long dataReceived)
+    {
+        ServerInformation broker = _jmxUtils.getServerInformation();
+
+        assertEquals(messagesSent, broker.getTotalMessagesReceived());
+        assertEquals(messagesReceived, broker.getTotalMessagesDelivered());
+
+        assertEquals(dataSent, broker.getTotalDataReceived());
+        assertEquals(dataReceived, broker.getTotalDataDelivered());
+    }
+}
diff --git a/java/systests/src/main/java/org/apache/qpid/systest/management/jmx/UserManagementTest.java b/java/systests/src/main/java/org/apache/qpid/systest/management/jmx/UserManagementTest.java
new file mode 100644
index 0000000000..7eff1c89ee
--- /dev/null
+++ b/java/systests/src/main/java/org/apache/qpid/systest/management/jmx/UserManagementTest.java
@@ -0,0 +1,260 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.qpid.systest.management.jmx;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileReader;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.jms.Connection;
+import javax.jms.JMSException;
+
+import org.apache.qpid.management.common.mbeans.UserManagement;
+import org.apache.qpid.server.model.Port;
+import org.apache.qpid.server.model.Protocol;
+import org.apache.qpid.server.model.Transport;
+import org.apache.qpid.server.plugin.AuthenticationManagerFactory;
+import org.apache.qpid.server.security.auth.manager.AbstractPrincipalDatabaseAuthManagerFactory;
+import org.apache.qpid.server.security.auth.manager.PlainPasswordFileAuthenticationManagerFactory;
+import org.apache.qpid.test.utils.JMXTestUtils;
+import org.apache.qpid.test.utils.QpidBrokerTestCase;
+import org.apache.qpid.test.utils.TestBrokerConfiguration;
+import org.apache.qpid.tools.security.Passwd;
+
+/**
+ * System test for User Management.
+ *
+ */
+public class UserManagementTest extends QpidBrokerTestCase
+{
+    private static final String TEST_NEWPASSWORD = "newpassword";
+    private static final String TEST_PASSWORD = "password";
+    private JMXTestUtils _jmxUtils;
+    private String _testUserName;
+    private File _passwordFile;
+    private UserManagement _userManagement;
+    private Passwd _passwd;
+
+    public void setUp() throws Exception
+    {
+        _passwd = createPasswordEncodingUtility();
+        _passwordFile = createTemporaryPasswordFileWithJmxAdminUser();
+
+        Map newAttributes = new HashMap();
+        newAttributes.put(AuthenticationManagerFactory.ATTRIBUTE_TYPE, getAuthenticationManagerType());
+        newAttributes.put(AbstractPrincipalDatabaseAuthManagerFactory.ATTRIBUTE_PATH, _passwordFile.getAbsolutePath());
+        getBrokerConfiguration().setObjectAttributes(TestBrokerConfiguration.ENTRY_NAME_AUTHENTICATION_PROVIDER, newAttributes);
+
+        _jmxUtils = new JMXTestUtils(this);
+        _jmxUtils.setUp();
+
+        super.setUp();
+        _jmxUtils.open();
+
+        _testUserName = getTestName() + System.currentTimeMillis();
+
+        _userManagement = _jmxUtils.getUserManagement();
+    }
+
+
+    public void tearDown() throws Exception
+    {
+        try
+        {
+            if (_jmxUtils != null)
+            {
+                _jmxUtils.close();
+            }
+        }
+        finally
+        {
+            super.tearDown();
+        }
+    }
+
+    public void testCreateUser() throws Exception
+    {
+        final int initialNumberOfUsers = _userManagement.viewUsers().size();
+        assertFileDoesNotContainsPasswordForUser(_testUserName);
+
+        boolean success = _userManagement.createUser(_testUserName, TEST_PASSWORD);
+        assertTrue("Should have been able to create new user " + _testUserName, success);
+        assertEquals("Unexpected number of users after add", initialNumberOfUsers + 1, _userManagement.viewUsers().size());
+
+        assertFileContainsPasswordForUser(_testUserName);
+    }
+
+    public void testJmsLoginForNewUser() throws Exception
+    {
+        assertJmsConnectionFails(_testUserName, TEST_PASSWORD);
+        testCreateUser();
+
+        assertJmsConnectionSucceeds(_testUserName, TEST_PASSWORD);
+    }
+
+    public void testDeleteUser() throws Exception
+    {
+        final int initialNumberOfUsers = _userManagement.viewUsers().size();
+
+        testCreateUser();
+
+        boolean success = _userManagement.deleteUser(_testUserName);
+        assertTrue("Should have been able to delete new user " + _testUserName, success);
+        assertEquals("Unexpected number of users after delete", initialNumberOfUsers, _userManagement.viewUsers().size());
+        assertFileDoesNotContainsPasswordForUser(_testUserName);
+    }
+
+    public void testJmsLoginNotPossibleForDeletedUser() throws Exception
+    {
+        testDeleteUser();
+
+        assertJmsConnectionFails(_testUserName, TEST_PASSWORD);
+    }
+
+    public void testSetPassword() throws Exception
+    {
+        testCreateUser();
+
+        _userManagement.setPassword(_testUserName, TEST_NEWPASSWORD);
+
+        assertFileContainsPasswordForUser(_testUserName);
+    }
+
+    public void testJmsLoginForPasswordChangedUser() throws Exception
+    {
+        testSetPassword();
+
+        assertJmsConnectionSucceeds(_testUserName, TEST_NEWPASSWORD);
+        assertJmsConnectionFails(_testUserName, TEST_PASSWORD);
+    }
+
+    public void testReload() throws Exception
+    {
+        writePasswordFile(_passwordFile, JMXTestUtils.DEFAULT_USERID, JMXTestUtils.DEFAULT_PASSWORD, _testUserName, TEST_PASSWORD);
+
+        assertJmsConnectionFails(_testUserName, TEST_PASSWORD);
+
+        _userManagement.reloadData();
+
+        assertJmsConnectionSucceeds(_testUserName, TEST_PASSWORD);
+    }
+
+    protected Passwd createPasswordEncodingUtility()
+    {
+        return new Passwd()
+        {
+            @Override
+            public String getOutput(String username, String password)
+            {
+                return username + ":" + password;
+            }
+        };
+    }
+
+    protected String getAuthenticationManagerType()
+    {
+        return PlainPasswordFileAuthenticationManagerFactory.PROVIDER_TYPE;
+    }
+
+    private File createTemporaryPasswordFileWithJmxAdminUser() throws Exception
+    {
+        File passwordFile = File.createTempFile("passwd", "pwd");
+        passwordFile.deleteOnExit();
+        writePasswordFile(passwordFile, JMXTestUtils.DEFAULT_USERID, JMXTestUtils.DEFAULT_PASSWORD);
+        return passwordFile;
+    }
+
+    private void writePasswordFile(File passwordFile, String... userNamePasswordPairs) throws Exception
+    {
+        FileWriter writer = null;
+        try
+        {
+            writer = new FileWriter(passwordFile);
+            for (int i = 0; i < userNamePasswordPairs.length; i=i+2)
+            {
+                String username = userNamePasswordPairs[i];
+                String password = userNamePasswordPairs[i+1];
+                writer.append(_passwd.getOutput(username, password) + "\n");
+            }
+        }
+        finally
+        {
+            writer.close();
+        }
+    }
+
+
+    private void assertFileContainsPasswordForUser(String username) throws IOException
+    {
+        assertTrue("Could not find password for user " + username + " within " + _passwordFile, passwordFileContainsUser(username));
+    }
+
+    private void assertFileDoesNotContainsPasswordForUser(String username) throws IOException
+    {
+        assertFalse("Could not find password for user " + username + " within " + _passwordFile, passwordFileContainsUser(username));
+    }
+
+    private boolean passwordFileContainsUser(String username) throws IOException
+    {
+        BufferedReader reader = null;
+        try
+        {
+            reader = new BufferedReader(new FileReader(_passwordFile));
+            String line = reader.readLine();
+            while(line != null)
+            {
+                if (line.startsWith(username))
+                {
+                    return true;
+                }
+                line = reader.readLine();
+            }
+
+            return false;
+        }
+        finally
+        {
+            reader.close();
+        }
+    }
+
+    private void assertJmsConnectionSucceeds(String username, String password) throws Exception
+    {
+        Connection connection = getConnection(username, password);
+        assertNotNull(connection);
+    }
+
+    private void assertJmsConnectionFails(String username, String password) throws Exception
+    {
+        try
+        {
+            getConnection(username, password);
+            fail("Exception not thrown");
+        }
+        catch (JMSException e)
+        {
+            // PASS
+        }
+    }
+}
diff --git a/java/systests/src/main/java/org/apache/qpid/systest/management/jmx/UserManagementWithBase64MD5PasswordsTest.java b/java/systests/src/main/java/org/apache/qpid/systest/management/jmx/UserManagementWithBase64MD5PasswordsTest.java
new file mode 100644
index 0000000000..1423bc557e
--- /dev/null
+++ b/java/systests/src/main/java/org/apache/qpid/systest/management/jmx/UserManagementWithBase64MD5PasswordsTest.java
@@ -0,0 +1,37 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.qpid.systest.management.jmx;
+
+import org.apache.qpid.server.security.auth.manager.Base64MD5PasswordFileAuthenticationManagerFactory;
+import org.apache.qpid.tools.security.Passwd;
+
+public class UserManagementWithBase64MD5PasswordsTest extends UserManagementTest
+{
+    @Override
+    protected Passwd createPasswordEncodingUtility()
+    {
+        return new Passwd();
+    }
+
+    @Override
+    protected String getAuthenticationManagerType()
+    {
+        return Base64MD5PasswordFileAuthenticationManagerFactory.PROVIDER_TYPE;
+    }
+}
diff --git a/java/systests/src/main/java/org/apache/qpid/systest/rest/Asserts.java b/java/systests/src/main/java/org/apache/qpid/systest/rest/Asserts.java
new file mode 100644
index 0000000000..16253139ce
--- /dev/null
+++ b/java/systests/src/main/java/org/apache/qpid/systest/rest/Asserts.java
@@ -0,0 +1,270 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.qpid.systest.rest;
+
+import static junit.framework.Assert.assertEquals;
+import static junit.framework.Assert.assertNotNull;
+
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.Map;
+
+import javax.jms.JMSException;
+
+import org.apache.qpid.client.AMQConnection;
+import org.apache.qpid.server.model.Binding;
+import org.apache.qpid.server.model.Broker;
+import org.apache.qpid.server.model.Connection;
+import org.apache.qpid.server.model.Exchange;
+import org.apache.qpid.server.model.LifetimePolicy;
+import org.apache.qpid.server.model.Port;
+import org.apache.qpid.server.model.Protocol;
+import org.apache.qpid.server.model.Queue;
+import org.apache.qpid.server.model.State;
+import org.apache.qpid.server.model.VirtualHost;
+
+public class Asserts
+{
+    public static final String STATISTICS_ATTRIBUTE = "statistics";
+
+    public static void assertVirtualHost(String virtualHostName, Map virtualHost)
+    {
+        assertNotNull("Virtualhost " + virtualHostName + " data are not found", virtualHost);
+        assertAttributesPresent(virtualHost, VirtualHost.AVAILABLE_ATTRIBUTES, VirtualHost.TIME_TO_LIVE,
+                VirtualHost.CREATED, VirtualHost.UPDATED, VirtualHost.SUPPORTED_QUEUE_TYPES, VirtualHost.STORE_PATH, VirtualHost.CONFIG_PATH);
+
+        assertEquals("Unexpected value of attribute " + VirtualHost.NAME, virtualHostName, virtualHost.get(VirtualHost.NAME));
+        assertNotNull("Unexpected value of attribute " + VirtualHost.ID, virtualHost.get(VirtualHost.ID));
+        assertEquals("Unexpected value of attribute " + VirtualHost.STATE, State.ACTIVE.name(),
+                virtualHost.get(VirtualHost.STATE));
+        assertEquals("Unexpected value of attribute " + VirtualHost.DURABLE, Boolean.TRUE,
+                virtualHost.get(VirtualHost.DURABLE));
+        assertEquals("Unexpected value of attribute " + VirtualHost.LIFETIME_POLICY, LifetimePolicy.PERMANENT.name(),
+                virtualHost.get(VirtualHost.LIFETIME_POLICY));
+        assertEquals("Unexpected value of attribute " + VirtualHost.DEAD_LETTER_QUEUE_ENABLED, Boolean.FALSE,
+                virtualHost.get(VirtualHost.DEAD_LETTER_QUEUE_ENABLED));
+
+        @SuppressWarnings("unchecked")
+        Collection exchangeTypes = (Collection) virtualHost.get(VirtualHost.SUPPORTED_EXCHANGE_TYPES);
+        assertEquals("Unexpected value of attribute " + VirtualHost.SUPPORTED_EXCHANGE_TYPES,
+                new HashSet(Arrays.asList("headers", "topic", "direct", "fanout")),
+                new HashSet(exchangeTypes));
+
+        @SuppressWarnings("unchecked")
+        Map statistics = (Map) virtualHost.get(STATISTICS_ATTRIBUTE);
+        Asserts.assertAttributesPresent(statistics, VirtualHost.AVAILABLE_STATISTICS, VirtualHost.BYTES_RETAINED,
+                VirtualHost.LOCAL_TRANSACTION_BEGINS, VirtualHost.LOCAL_TRANSACTION_ROLLBACKS,
+                VirtualHost.MESSAGES_RETAINED, VirtualHost.STATE_CHANGED, VirtualHost.XA_TRANSACTION_BRANCH_ENDS,
+                VirtualHost.XA_TRANSACTION_BRANCH_STARTS, VirtualHost.XA_TRANSACTION_BRANCH_SUSPENDS);
+
+    }
+
+    public static void assertQueue(String queueName, String queueType, Map queueData)
+    {
+        assertQueue(queueName, queueType, queueData, null);
+    }
+
+    public static void assertQueue(String queueName, String queueType, Map queueData, Map expectedAttributes)
+    {
+        assertNotNull("Queue " + queueName + " is not found!", queueData);
+        Asserts.assertAttributesPresent(queueData, Queue.AVAILABLE_ATTRIBUTES, Queue.CREATED, Queue.UPDATED,
+                Queue.DESCRIPTION, Queue.TIME_TO_LIVE, Queue.ALTERNATE_EXCHANGE, Queue.OWNER, Queue.NO_LOCAL, Queue.LVQ_KEY,
+                Queue.SORT_KEY, Queue.MESSAGE_GROUP_KEY, Queue.MESSAGE_GROUP_DEFAULT_GROUP,
+                Queue.MESSAGE_GROUP_SHARED_GROUPS, Queue.PRIORITIES);
+
+        assertEquals("Unexpected value of queue attribute " + Queue.NAME, queueName, queueData.get(Queue.NAME));
+        assertNotNull("Unexpected value of queue attribute " + Queue.ID, queueData.get(Queue.ID));
+        assertEquals("Unexpected value of queue attribute " + Queue.STATE, State.ACTIVE.name(), queueData.get(Queue.STATE));
+        assertEquals("Unexpected value of queue attribute " + Queue.LIFETIME_POLICY, LifetimePolicy.PERMANENT.name(),
+                queueData.get(Queue.LIFETIME_POLICY));
+        assertEquals("Unexpected value of queue attribute " + Queue.TYPE, queueType, queueData.get(Queue.TYPE));
+        if (expectedAttributes == null)
+        {
+            assertEquals("Unexpected value of queue attribute " + Queue.EXCLUSIVE, Boolean.FALSE, queueData.get(Queue.EXCLUSIVE));
+            assertEquals("Unexpected value of queue attribute " + Queue.MAXIMUM_DELIVERY_ATTEMPTS, 0,
+                    queueData.get(Queue.MAXIMUM_DELIVERY_ATTEMPTS));
+            assertEquals("Unexpected value of queue attribute " + Queue.QUEUE_FLOW_CONTROL_SIZE_BYTES, 0,
+                    queueData.get(Queue.QUEUE_FLOW_CONTROL_SIZE_BYTES));
+            assertEquals("Unexpected value of queue attribute " + Queue.QUEUE_FLOW_RESUME_SIZE_BYTES, 0,
+                    queueData.get(Queue.QUEUE_FLOW_RESUME_SIZE_BYTES));
+            assertEquals("Unexpected value of queue attribute " + Queue.QUEUE_FLOW_STOPPED, Boolean.FALSE,
+                    queueData.get(Queue.QUEUE_FLOW_STOPPED));
+        }
+        else
+        {
+            for (Map.Entry attribute : expectedAttributes.entrySet())
+            {
+                assertEquals("Unexpected value of " + queueName + " queue attribute " + attribute.getKey(),
+                        attribute.getValue(), queueData.get(attribute.getKey()));
+            }
+        }
+
+        assertNotNull("Unexpected value of queue attribute statistics", queueData.get(Asserts.STATISTICS_ATTRIBUTE));
+        @SuppressWarnings("unchecked")
+        Map statistics = (Map) queueData.get(Asserts.STATISTICS_ATTRIBUTE);
+        Asserts.assertAttributesPresent(statistics, Queue.AVAILABLE_STATISTICS, Queue.DISCARDS_TTL_BYTES,
+                Queue.DISCARDS_TTL_MESSAGES, Queue.STATE_CHANGED);
+    }
+
+    public static void assertAttributesPresent(Map data, String[] attributes)
+    {
+        for (String name : attributes)
+        {
+            assertNotNull("Attribute " + name + " is not present", data.get(name));
+        }
+    }
+
+    public static void assertAttributesPresent(Map data, Collection attributes,
+            String... unsupportedAttributes)
+    {
+        for (String name : attributes)
+        {
+            boolean unsupported = false;
+            for (String unsupportedAttribute : unsupportedAttributes)
+            {
+                if (unsupportedAttribute.equals(name))
+                {
+                    unsupported = true;
+                    break;
+                }
+            }
+            if (unsupported)
+            {
+                continue;
+            }
+            assertNotNull("Attribute " + name + " is not present", data.get(name));
+        }
+    }
+
+    public static void assertConnection(Map connectionData, AMQConnection connection) throws JMSException
+    {
+        assertNotNull("Unexpected connection data", connectionData);
+        assertAttributesPresent(connectionData, Connection.AVAILABLE_ATTRIBUTES, Connection.STATE, Connection.DURABLE,
+                Connection.LIFETIME_POLICY, Connection.TIME_TO_LIVE, Connection.CREATED, Connection.UPDATED,
+                Connection.INCOMING, Connection.REMOTE_PROCESS_NAME, Connection.REMOTE_PROCESS_PID,
+                Connection.LOCAL_ADDRESS, Connection.PROPERTIES);
+
+        assertEquals("Unexpected value of connection attribute " + Connection.SESSION_COUNT_LIMIT,
+                (int) connection.getMaximumChannelCount(), connectionData.get(Connection.SESSION_COUNT_LIMIT));
+        assertEquals("Unexpected value of connection attribute " + Connection.CLIENT_ID, "clientid",
+                connectionData.get(Connection.CLIENT_ID));
+        assertEquals("Unexpected value of connection attribute " + Connection.PRINCIPAL, "guest",
+                connectionData.get(Connection.PRINCIPAL));
+
+        @SuppressWarnings("unchecked")
+        Map statistics = (Map) connectionData.get(STATISTICS_ATTRIBUTE);
+        assertAttributesPresent(statistics, Connection.AVAILABLE_STATISTICS, Connection.LOCAL_TRANSACTION_BEGINS,
+                Connection.LOCAL_TRANSACTION_ROLLBACKS, Connection.STATE_CHANGED, Connection.XA_TRANSACTION_BRANCH_ENDS,
+                Connection.XA_TRANSACTION_BRANCH_STARTS, Connection.XA_TRANSACTION_BRANCH_SUSPENDS);
+        assertEquals("Unexpected value of connection statistics attribute " + Connection.SESSION_COUNT, 1,
+                statistics.get(Connection.SESSION_COUNT));
+    }
+
+    public static void assertPortAttributes(Map port)
+    {
+
+        assertNotNull("Unexpected value of attribute " + Port.ID, port.get(Port.ID));
+        assertEquals("Unexpected value of attribute " + Port.DURABLE, Boolean.FALSE, port.get(Port.DURABLE));
+        assertEquals("Unexpected value of attribute " + Port.LIFETIME_POLICY, LifetimePolicy.PERMANENT.name(),
+                port.get(Broker.LIFETIME_POLICY));
+        assertEquals("Unexpected value of attribute " + Port.STATE, State.ACTIVE.name(), port.get(Port.STATE));
+        assertEquals("Unexpected value of attribute " + Port.TIME_TO_LIVE, 0, port.get(Port.TIME_TO_LIVE));
+
+        @SuppressWarnings("unchecked")
+        Collection protocols = (Collection) port.get(Port.PROTOCOLS);
+        assertNotNull("Unexpected value of attribute " + Port.PROTOCOLS, protocols);
+        boolean isAMQPPort = false;
+        for (String protocolName : protocols)
+        {
+            if (Protocol.valueOf(protocolName).isAMQP())
+            {
+                isAMQPPort = true;
+                break;
+            }
+        }
+        if (isAMQPPort)
+        {
+            assertAttributesPresent(port, Port.AVAILABLE_ATTRIBUTES, Port.CREATED, Port.UPDATED, Port.AUTHENTICATION_MANAGER);
+            assertNotNull("Unexpected value of attribute " + Port.BINDING_ADDRESS, port.get(Port.BINDING_ADDRESS));
+        }
+        else
+        {
+            assertAttributesPresent(port, Port.AVAILABLE_ATTRIBUTES, Port.CREATED, Port.UPDATED, Port.AUTHENTICATION_MANAGER,
+                    Port.BINDING_ADDRESS, Port.TCP_NO_DELAY, Port.SEND_BUFFER_SIZE, Port.RECEIVE_BUFFER_SIZE,
+                    Port.NEED_CLIENT_AUTH, Port.WANT_CLIENT_AUTH);
+        }
+
+        @SuppressWarnings("unchecked")
+        Collection transports = (Collection) port.get(Port.TRANSPORTS);
+        assertEquals("Unexpected value of attribute " + Port.TRANSPORTS, new HashSet(Arrays.asList("TCP")),
+                new HashSet(transports));
+    }
+
+    public static void assertDurableExchange(String exchangeName, String type, Map exchangeData)
+    {
+        assertExchange(exchangeName, type, exchangeData);
+
+        assertEquals("Unexpected value of exchange attribute " + Exchange.DURABLE, Boolean.TRUE,
+                exchangeData.get(Exchange.DURABLE));
+    }
+
+    public static void assertExchange(String exchangeName, String type, Map exchangeData)
+    {
+        assertNotNull("Exchange " + exchangeName + " is not found!", exchangeData);
+        assertAttributesPresent(exchangeData, Exchange.AVAILABLE_ATTRIBUTES, Exchange.CREATED, Exchange.UPDATED,
+                Exchange.ALTERNATE_EXCHANGE, Exchange.TIME_TO_LIVE);
+
+        assertEquals("Unexpected value of exchange attribute " + Exchange.NAME, exchangeName,
+                exchangeData.get(Exchange.NAME));
+        assertNotNull("Unexpected value of exchange attribute " + Exchange.ID, exchangeData.get(VirtualHost.ID));
+        assertEquals("Unexpected value of exchange attribute " + Exchange.STATE, State.ACTIVE.name(),
+                exchangeData.get(Exchange.STATE));
+
+        assertEquals("Unexpected value of exchange attribute " + Exchange.LIFETIME_POLICY, LifetimePolicy.PERMANENT.name(),
+                exchangeData.get(Exchange.LIFETIME_POLICY));
+        assertEquals("Unexpected value of exchange attribute " + Exchange.TYPE, type, exchangeData.get(Exchange.TYPE));
+        assertNotNull("Unexpected value of exchange attribute statistics", exchangeData.get(STATISTICS_ATTRIBUTE));
+
+        @SuppressWarnings("unchecked")
+        Map statistics = (Map) exchangeData.get(STATISTICS_ATTRIBUTE);
+        assertAttributesPresent(statistics, Exchange.AVAILABLE_STATISTICS, Exchange.STATE_CHANGED, Exchange.PRODUCER_COUNT);
+    }
+
+    public static void assertBinding(String bindingName, String queueName, String exchange, Map binding)
+    {
+        assertNotNull("Binding map should not be null", binding);
+        assertAttributesPresent(binding, Binding.AVAILABLE_ATTRIBUTES, Binding.STATE, Binding.TIME_TO_LIVE,
+                Binding.CREATED, Binding.UPDATED);
+
+        assertEquals("Unexpected binding attribute " + Binding.NAME, bindingName, binding.get(Binding.NAME));
+        assertEquals("Unexpected binding attribute " + Binding.QUEUE, queueName, binding.get(Binding.QUEUE));
+        assertEquals("Unexpected binding attribute " + Binding.EXCHANGE, exchange, binding.get(Binding.EXCHANGE));
+        assertEquals("Unexpected binding attribute " + Binding.LIFETIME_POLICY, LifetimePolicy.PERMANENT.name(),
+                binding.get(Binding.LIFETIME_POLICY));
+    }
+
+    public static void assertBinding(String queueName, String exchange, Map binding)
+    {
+        assertBinding(queueName, queueName, exchange, binding);
+    }
+
+}
diff --git a/java/systests/src/main/java/org/apache/qpid/systest/rest/AuthenticationProviderRestTest.java b/java/systests/src/main/java/org/apache/qpid/systest/rest/AuthenticationProviderRestTest.java
new file mode 100644
index 0000000000..a171b4459b
--- /dev/null
+++ b/java/systests/src/main/java/org/apache/qpid/systest/rest/AuthenticationProviderRestTest.java
@@ -0,0 +1,73 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.qpid.systest.rest;
+
+import java.util.List;
+import java.util.Map;
+
+import org.apache.qpid.server.model.AuthenticationProvider;
+import org.apache.qpid.server.model.LifetimePolicy;
+import org.apache.qpid.server.model.State;
+import org.apache.qpid.server.model.User;
+
+public class AuthenticationProviderRestTest extends QpidRestTestCase
+{
+
+    public void testGet() throws Exception
+    {
+        List> providerDetails = getRestTestHelper().getJsonAsList("/rest/authenticationprovider");
+        assertNotNull("Providers details cannot be null", providerDetails);
+        assertEquals("Unexpected number of providers", 1, providerDetails.size());
+        for (Map provider : providerDetails)
+        {
+            assertProvider("PrincipalDatabaseAuthenticationManager", provider);
+            Map data = getRestTestHelper().getJsonAsSingletonList("/rest/authenticationprovider/"
+                    + provider.get(AuthenticationProvider.NAME));
+            assertNotNull("Cannot load data for " + provider.get(AuthenticationProvider.NAME), data);
+            assertProvider("PrincipalDatabaseAuthenticationManager", data);
+        }
+    }
+
+    private void assertProvider(String type, Map provider)
+    {
+        Asserts.assertAttributesPresent(provider, AuthenticationProvider.AVAILABLE_ATTRIBUTES,
+                AuthenticationProvider.CREATED, AuthenticationProvider.UPDATED, AuthenticationProvider.DESCRIPTION,
+                AuthenticationProvider.TIME_TO_LIVE);
+        assertEquals("Unexpected value of provider attribute " + AuthenticationProvider.STATE, State.ACTIVE.name(),
+                provider.get(AuthenticationProvider.STATE));
+        assertEquals("Unexpected value of provider attribute " + AuthenticationProvider.LIFETIME_POLICY,
+                LifetimePolicy.PERMANENT.name(), provider.get(AuthenticationProvider.LIFETIME_POLICY));
+        assertEquals("Unexpected value of provider attribute " + AuthenticationProvider.DURABLE, Boolean.TRUE,
+                provider.get(AuthenticationProvider.DURABLE));
+        assertEquals("Unexpected value of provider attribute " + AuthenticationProvider.TYPE, type,
+                provider.get(AuthenticationProvider.TYPE));
+
+        @SuppressWarnings("unchecked")
+        List> users = (List>) provider.get("users");
+        assertNotNull("Users are not found", users);
+        assertTrue("Unexpected number of users", users.size() > 1);
+        for (Map user : users)
+        {
+            assertNotNull("Attribute " + User.ID, user.get(User.ID));
+            assertNotNull("Attribute " + User.NAME, user.get(User.NAME));
+        }
+    }
+}
diff --git a/java/systests/src/main/java/org/apache/qpid/systest/rest/BasicAuthRestTest.java b/java/systests/src/main/java/org/apache/qpid/systest/rest/BasicAuthRestTest.java
new file mode 100644
index 0000000000..0574b6cc24
--- /dev/null
+++ b/java/systests/src/main/java/org/apache/qpid/systest/rest/BasicAuthRestTest.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.systest.rest;
+
+import static org.apache.qpid.test.utils.TestSSLConstants.TRUSTSTORE;
+import static org.apache.qpid.test.utils.TestSSLConstants.TRUSTSTORE_PASSWORD;
+
+import java.io.IOException;
+import java.net.HttpURLConnection;
+import java.util.Collections;
+
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.commons.configuration.ConfigurationException;
+import org.apache.qpid.server.model.Port;
+import org.apache.qpid.server.model.Protocol;
+import org.apache.qpid.test.utils.TestBrokerConfiguration;
+
+public class BasicAuthRestTest extends QpidRestTestCase
+{
+    private static final String USERNAME = "admin";
+
+    @Override
+    public void setUp() throws Exception
+    {
+        setSystemProperty("javax.net.debug", "ssl");
+
+        //don't call super method, we will configure the broker in the test before doing so
+    }
+
+    @Override
+    protected void customizeConfiguration() throws ConfigurationException, IOException
+    {
+        //do nothing, we will configure this locally
+    }
+
+    private void configure(boolean useSsl) throws ConfigurationException, IOException
+    {
+        getRestTestHelper().setUseSsl(useSsl);
+        if (useSsl)
+        {
+            getBrokerConfiguration().setObjectAttribute(TestBrokerConfiguration.ENTRY_NAME_HTTP_PORT, Port.PROTOCOLS, Collections.singleton(Protocol.HTTPS));
+        }
+        super.customizeConfiguration();
+    }
+
+    private void verifyGetBrokerAttempt(int responseCode) throws IOException
+    {
+        HttpURLConnection conn = getRestTestHelper().openManagementConnection("/rest/broker", "GET");
+        assertEquals(responseCode, conn.getResponseCode());
+    }
+
+    public void testDefaultEnabledWithHttps() throws Exception
+    {
+        configure(true);
+        super.setUp();
+        setSystemProperty("javax.net.ssl.trustStore", TRUSTSTORE);
+        setSystemProperty("javax.net.ssl.trustStorePassword", TRUSTSTORE_PASSWORD);
+
+        // Try the attempt with authentication, it should succeed because
+        // BASIC auth is enabled by default on secure connections.
+        getRestTestHelper().setUsernameAndPassword(USERNAME, USERNAME);
+        verifyGetBrokerAttempt(HttpServletResponse.SC_OK);
+    }
+
+    public void testDefaultDisabledWithHttp() throws Exception
+    {
+        configure(false);
+        super.setUp();
+
+        // Try the attempt with authentication, it should fail because
+        // BASIC auth is disabled by default on non-secure connections.
+        getRestTestHelper().setUsernameAndPassword(USERNAME, USERNAME);
+        verifyGetBrokerAttempt(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
+    }
+
+    public void testEnablingForHttp() throws Exception
+    {
+        configure(false);
+
+        getBrokerConfiguration().setObjectAttribute(TestBrokerConfiguration.ENTRY_NAME_HTTP_MANAGEMENT, "httpBasicAuthenticationEnabled", true);
+        super.setUp();
+
+        // Try the attempt with authentication, it should succeed because
+        // BASIC auth is now enabled on non-secure connections.
+        getRestTestHelper().setUsernameAndPassword(USERNAME, USERNAME);
+        verifyGetBrokerAttempt(HttpServletResponse.SC_OK);
+    }
+
+    public void testDisablingForHttps() throws Exception
+    {
+        configure(true);
+        getBrokerConfiguration().setObjectAttribute(TestBrokerConfiguration.ENTRY_NAME_HTTP_MANAGEMENT, "httpsBasicAuthenticationEnabled", false);
+        super.setUp();
+        setSystemProperty("javax.net.ssl.trustStore", TRUSTSTORE);
+        setSystemProperty("javax.net.ssl.trustStorePassword", TRUSTSTORE_PASSWORD);
+
+        // Try the attempt with authentication, it should fail because
+        // BASIC auth is now disabled on secure connections.
+        getRestTestHelper().setUsernameAndPassword(USERNAME, USERNAME);
+        verifyGetBrokerAttempt(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
+    }
+}
diff --git a/java/systests/src/main/java/org/apache/qpid/systest/rest/BindingRestTest.java b/java/systests/src/main/java/org/apache/qpid/systest/rest/BindingRestTest.java
new file mode 100644
index 0000000000..372db8f560
--- /dev/null
+++ b/java/systests/src/main/java/org/apache/qpid/systest/rest/BindingRestTest.java
@@ -0,0 +1,130 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.qpid.systest.rest;
+
+import java.net.HttpURLConnection;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.qpid.server.model.Binding;
+
+public class BindingRestTest extends QpidRestTestCase
+{
+
+    public void testGetAllBindings() throws Exception
+    {
+        List> bindings = getRestTestHelper().getJsonAsList("/rest/binding");
+        assertNotNull("Bindings cannot be null", bindings);
+        assertTrue("Unexpected number of bindings: " + bindings.size(),
+                bindings.size() >= EXPECTED_VIRTUALHOSTS.length * EXPECTED_QUEUES.length);
+        for (Map binding : bindings)
+        {
+            Asserts.assertBinding((String) binding.get(Binding.NAME), (String) binding.get(Binding.EXCHANGE), binding);
+        }
+    }
+
+    public void testGetVirtualHostBindings() throws Exception
+    {
+        List> bindings = getRestTestHelper().getJsonAsList("/rest/binding/test");
+        assertNotNull("Bindings cannot be null", bindings);
+        assertEquals("Unexpected number of bindings", EXPECTED_QUEUES.length * 2, bindings.size());
+        for (String queueName : EXPECTED_QUEUES)
+        {
+            Map searchAttributes = new HashMap();
+            searchAttributes.put(Binding.NAME, queueName);
+            searchAttributes.put(Binding.EXCHANGE, "amq.direct");
+
+            Map binding = getRestTestHelper().find(searchAttributes, bindings);
+            Asserts.assertBinding(queueName, "amq.direct", binding);
+
+            searchAttributes.put(Binding.EXCHANGE, "<>");
+
+            binding = getRestTestHelper().find(searchAttributes, bindings);
+            Asserts.assertBinding(queueName, "<>", binding);
+        }
+    }
+
+    public void testGetVirtualHostExchangeBindings() throws Exception
+    {
+        List> bindings = getRestTestHelper().getJsonAsList("/rest/binding/test/amq.direct");
+        assertNotNull("Bindings cannot be null", bindings);
+        assertEquals("Unexpected number of bindings", EXPECTED_QUEUES.length, bindings.size());
+        for (String queueName : EXPECTED_QUEUES)
+        {
+            Map binding = getRestTestHelper().find(Binding.NAME, queueName, bindings);
+            Asserts.assertBinding(queueName, "amq.direct", binding);
+        }
+    }
+
+    public void testGetVirtualHostExchangeQueueBindings() throws Exception
+    {
+        List> bindings = getRestTestHelper().getJsonAsList("/rest/binding/test/amq.direct/queue");
+        assertNotNull("Bindings cannot be null", bindings);
+        assertEquals("Unexpected number of bindings", 1, bindings.size());
+        Asserts.assertBinding("queue", "amq.direct", bindings.get(0));
+    }
+
+
+    public void testDeleteBinding() throws Exception
+    {
+        List> bindings = getRestTestHelper().getJsonAsList("/rest/binding/test/amq.direct/queue/queue");
+        assertEquals("Unexpected number of bindings", 1, bindings.size());
+        Asserts.assertBinding("queue", "amq.direct", bindings.get(0));
+
+        HttpURLConnection connection = getRestTestHelper().openManagementConnection("/rest/binding/test/amq.direct/queue/queue", "DELETE");
+        connection.connect();
+        assertEquals("Unexpected response code", 200, connection.getResponseCode());
+
+        bindings = getRestTestHelper().getJsonAsList("/rest/binding/test/amq.direct/queue/queue");
+        assertEquals("Binding should be deleted", 0, bindings.size());
+    }
+
+    public void testDeleteBindingById() throws Exception
+    {
+        Map binding = getRestTestHelper().getJsonAsSingletonList("/rest/binding/test/amq.direct/queue");
+        HttpURLConnection connection = getRestTestHelper().openManagementConnection("/rest/binding/test/amq.direct?id=" + binding.get(Binding.ID), "DELETE");
+        connection.connect();
+        assertEquals("Unexpected response code", 200, connection.getResponseCode());
+        List> bindings = getRestTestHelper().getJsonAsList("/rest/binding/test/amq.direct/queue");
+        assertEquals("Binding should be deleted", 0, bindings.size());
+    }
+
+    public void testCreateBinding() throws Exception
+    {
+        String bindingName =  getTestName();
+        Map bindingData = new HashMap();
+        bindingData.put(Binding.NAME, bindingName);
+        bindingData.put(Binding.QUEUE, "queue");
+        bindingData.put(Binding.EXCHANGE, "amq.direct");
+
+        HttpURLConnection connection = getRestTestHelper().openManagementConnection("/rest/binding/test/amq.direct/queue/" + bindingName, "PUT");
+        connection.connect();
+        getRestTestHelper().writeJsonRequest(connection, bindingData);
+        int responseCode = connection.getResponseCode();
+        connection.disconnect();
+        assertEquals("Unexpected response code", 201, responseCode);
+        Map binding = getRestTestHelper().getJsonAsSingletonList("/rest/binding/test/amq.direct/queue/" + bindingName);
+
+        Asserts.assertBinding(bindingName, "queue", "amq.direct", binding);
+    }
+
+}
diff --git a/java/systests/src/main/java/org/apache/qpid/systest/rest/BrokerRestHttpsTest.java b/java/systests/src/main/java/org/apache/qpid/systest/rest/BrokerRestHttpsTest.java
new file mode 100644
index 0000000000..13e0c1e819
--- /dev/null
+++ b/java/systests/src/main/java/org/apache/qpid/systest/rest/BrokerRestHttpsTest.java
@@ -0,0 +1,69 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.qpid.systest.rest;
+
+import static org.apache.qpid.test.utils.TestSSLConstants.TRUSTSTORE;
+import static org.apache.qpid.test.utils.TestSSLConstants.TRUSTSTORE_PASSWORD;
+
+import java.io.IOException;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.commons.configuration.ConfigurationException;
+import org.apache.qpid.server.model.Broker;
+import org.apache.qpid.server.model.Port;
+import org.apache.qpid.server.model.Protocol;
+import org.apache.qpid.server.model.Transport;
+import org.apache.qpid.test.utils.TestBrokerConfiguration;
+
+public class BrokerRestHttpsTest extends QpidRestTestCase
+{
+    @Override
+    public void setUp() throws Exception
+    {
+        setSystemProperty("javax.net.debug", "ssl");
+        super.setUp();
+        setSystemProperty("javax.net.ssl.trustStore", TRUSTSTORE);
+        setSystemProperty("javax.net.ssl.trustStorePassword", TRUSTSTORE_PASSWORD);
+    }
+
+    @Override
+    protected void customizeConfiguration() throws ConfigurationException, IOException
+    {
+        super.customizeConfiguration();
+        getRestTestHelper().setUseSsl(true);
+        Map newAttributes = new HashMap();
+        newAttributes.put(Port.PROTOCOLS, Collections.singleton(Protocol.HTTPS));
+        newAttributes.put(Port.TRANSPORTS, Collections.singleton(Transport.SSL));
+        getBrokerConfiguration().setObjectAttributes(TestBrokerConfiguration.ENTRY_NAME_HTTP_PORT,newAttributes);
+    }
+
+    public void testGetWithHttps() throws Exception
+    {
+        Map brokerDetails = getRestTestHelper().getJsonAsSingletonList("/rest/broker");
+
+        Asserts.assertAttributesPresent(brokerDetails, Broker.AVAILABLE_ATTRIBUTES, Broker.BYTES_RETAINED,
+                Broker.PROCESS_PID, Broker.SUPPORTED_STORE_TYPES, Broker.CREATED, Broker.TIME_TO_LIVE, Broker.UPDATED,
+                Broker.ACL_FILE, Broker.KEY_STORE_CERT_ALIAS, Broker.TRUST_STORE_PATH, Broker.TRUST_STORE_PASSWORD,
+                Broker.GROUP_FILE);
+    }
+}
diff --git a/java/systests/src/main/java/org/apache/qpid/systest/rest/BrokerRestTest.java b/java/systests/src/main/java/org/apache/qpid/systest/rest/BrokerRestTest.java
new file mode 100644
index 0000000000..d479d39287
--- /dev/null
+++ b/java/systests/src/main/java/org/apache/qpid/systest/rest/BrokerRestTest.java
@@ -0,0 +1,120 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.qpid.systest.rest;
+
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.qpid.common.QpidProperties;
+import org.apache.qpid.server.model.Broker;
+import org.apache.qpid.server.model.LifetimePolicy;
+import org.apache.qpid.server.model.Port;
+import org.apache.qpid.server.model.State;
+import org.apache.qpid.server.model.VirtualHost;
+import org.apache.qpid.test.utils.TestBrokerConfiguration;
+
+public class BrokerRestTest extends QpidRestTestCase
+{
+
+    private static final String BROKER_AUTHENTICATIONPROVIDERS_ATTRIBUTE = "authenticationproviders";
+    private static final String BROKER_PORTS_ATTRIBUTE = "ports";
+    private static final String BROKER_VIRTUALHOSTS_ATTRIBUTE = "virtualhosts";
+    private static final String BROKER_STATISTICS_ATTRIBUTE = "statistics";
+
+    public void testGet() throws Exception
+    {
+        Map brokerDetails = getRestTestHelper().getJsonAsSingletonList("/rest/broker");
+
+        assertBrokerAttributes(brokerDetails);
+
+        @SuppressWarnings("unchecked")
+        Map statistics = (Map) brokerDetails.get(BROKER_STATISTICS_ATTRIBUTE);
+        Asserts.assertAttributesPresent(statistics, new String[]{ "bytesIn", "messagesOut", "bytesOut", "messagesIn" });
+
+        @SuppressWarnings("unchecked")
+        List> virtualhosts = (List>) brokerDetails.get(BROKER_VIRTUALHOSTS_ATTRIBUTE);
+        assertEquals("Unexpected number of virtual hosts", 3, virtualhosts.size());
+
+        Asserts.assertVirtualHost(TEST3_VIRTUALHOST, getRestTestHelper().find(VirtualHost.NAME, TEST3_VIRTUALHOST, virtualhosts));
+        Asserts.assertVirtualHost(TEST2_VIRTUALHOST, getRestTestHelper().find(VirtualHost.NAME, TEST2_VIRTUALHOST, virtualhosts));
+        Asserts.assertVirtualHost(TEST1_VIRTUALHOST, getRestTestHelper().find(VirtualHost.NAME, TEST1_VIRTUALHOST, virtualhosts));
+
+        @SuppressWarnings("unchecked")
+        List> ports = (List>) brokerDetails.get(BROKER_PORTS_ATTRIBUTE);
+        assertEquals("Unexpected number of ports", 4, ports.size());
+
+        for (Map port : ports)
+        {
+            Asserts.assertPortAttributes(port);
+        }
+
+        Map amqpPort = getRestTestHelper().find(Port.NAME, TestBrokerConfiguration.ENTRY_NAME_AMQP_PORT, ports);
+        Map httpPort = getRestTestHelper().find(Port.NAME, TestBrokerConfiguration.ENTRY_NAME_HTTP_PORT, ports);
+
+        assertEquals("Unexpected binding address", "*", amqpPort.get(Port.BINDING_ADDRESS));
+        assertNotNull("Cannot find AMQP port", amqpPort);
+        assertNotNull("Cannot find HTTP port", httpPort);
+
+        @SuppressWarnings("unchecked")
+        Collection port1Protocols = (Collection) amqpPort.get(Port.PROTOCOLS);
+        assertFalse("AMQP protocol list cannot contain HTTP", port1Protocols.contains("HTTP"));
+
+        @SuppressWarnings("unchecked")
+        Collection port2Protocols = (Collection) httpPort.get(Port.PROTOCOLS);
+        assertEquals("Unexpected value of attribute " + Port.PROTOCOLS, new HashSet(Arrays.asList("HTTP")),
+                new HashSet(port2Protocols));
+    }
+
+    protected void assertBrokerAttributes(Map brokerDetails)
+    {
+        Asserts.assertAttributesPresent(brokerDetails, Broker.AVAILABLE_ATTRIBUTES,
+                Broker.BYTES_RETAINED, Broker.PROCESS_PID, Broker.SUPPORTED_STORE_TYPES,
+                Broker.CREATED, Broker.TIME_TO_LIVE, Broker.UPDATED, Broker.ACL_FILE,
+                Broker.KEY_STORE_PATH, Broker.KEY_STORE_PASSWORD, Broker.KEY_STORE_CERT_ALIAS,
+                Broker.TRUST_STORE_PATH, Broker.TRUST_STORE_PASSWORD, Broker.GROUP_FILE);
+
+        assertEquals("Unexpected value of attribute " + Broker.BUILD_VERSION, QpidProperties.getBuildVersion(),
+                brokerDetails.get(Broker.BUILD_VERSION));
+        assertEquals("Unexpected value of attribute " + Broker.OPERATING_SYSTEM, System.getProperty("os.name") + " "
+                + System.getProperty("os.version") + " " + System.getProperty("os.arch"),
+                brokerDetails.get(Broker.OPERATING_SYSTEM));
+        assertEquals(
+                "Unexpected value of attribute " + Broker.PLATFORM,
+                System.getProperty("java.vendor") + " "
+                        + System.getProperty("java.runtime.version", System.getProperty("java.version")),
+                brokerDetails.get(Broker.PLATFORM));
+        assertEquals("Unexpected value of attribute " + Broker.DURABLE, Boolean.TRUE, brokerDetails.get(Broker.DURABLE));
+        assertEquals("Unexpected value of attribute " + Broker.LIFETIME_POLICY, LifetimePolicy.PERMANENT.name(),
+                brokerDetails.get(Broker.LIFETIME_POLICY));
+        assertEquals("Unexpected value of attribute " + Broker.NAME, "QpidBroker", brokerDetails.get(Broker.NAME));
+        assertEquals("Unexpected value of attribute " + Broker.STATE, State.ACTIVE.name(), brokerDetails.get(Broker.STATE));
+
+        assertNotNull("Unexpected value of attribute " + Broker.ID, brokerDetails.get(Broker.ID));
+        assertNotNull("Unexpected value of attribute statistics", brokerDetails.get(BROKER_STATISTICS_ATTRIBUTE));
+        assertNotNull("Unexpected value of attribute virtualhosts", brokerDetails.get(BROKER_VIRTUALHOSTS_ATTRIBUTE));
+        assertNotNull("Unexpected value of attribute ports", brokerDetails.get(BROKER_PORTS_ATTRIBUTE));
+        assertNotNull("Unexpected value of attribute authenticationproviders", brokerDetails.get(BROKER_AUTHENTICATIONPROVIDERS_ATTRIBUTE));
+    }
+
+}
diff --git a/java/systests/src/main/java/org/apache/qpid/systest/rest/ConnectionRestTest.java b/java/systests/src/main/java/org/apache/qpid/systest/rest/ConnectionRestTest.java
new file mode 100644
index 0000000000..05c8e362a1
--- /dev/null
+++ b/java/systests/src/main/java/org/apache/qpid/systest/rest/ConnectionRestTest.java
@@ -0,0 +1,213 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.qpid.systest.rest;
+
+import java.io.IOException;
+import java.net.URLDecoder;
+import java.util.List;
+import java.util.Map;
+
+import javax.jms.Destination;
+import javax.jms.JMSException;
+import javax.jms.Message;
+import javax.jms.MessageConsumer;
+import javax.jms.MessageProducer;
+
+import org.apache.qpid.client.AMQConnection;
+import org.apache.qpid.client.AMQSession;
+import org.apache.qpid.server.model.Connection;
+import org.apache.qpid.server.model.Session;
+
+public class ConnectionRestTest extends QpidRestTestCase
+{
+    /**
+     * Message number to publish into queue
+     */
+    private static final int MESSAGE_NUMBER = 5;
+    private static final int MESSAGE_SIZE = 6;
+
+    private static final String SESSIONS_ATTRIBUTE = "sessions";
+
+    private javax.jms.Connection _connection;
+    private javax.jms.Session _session;
+
+    public void setUp() throws Exception
+    {
+        super.setUp();
+
+        _connection = getConnection();
+        _session = _connection.createSession(true, javax.jms.Session.SESSION_TRANSACTED);
+        String queueName = getTestQueueName();
+        Destination queue = _session.createQueue(queueName);
+        MessageConsumer consumer = _session.createConsumer(queue);
+        MessageProducer producer = _session.createProducer(queue);
+        _connection.start();
+
+        // send messages
+        for (int i = 0; i < MESSAGE_NUMBER; i++)
+        {
+            producer.send(_session.createTextMessage("Test-" + i));
+        }
+        _session.commit();
+
+        Message m = consumer.receive(1000l);
+        assertNotNull("Message was not received", m);
+        _session.commit();
+
+        // receive the rest of messages for rollback
+        for (int i = 0; i < MESSAGE_NUMBER - 1; i++)
+        {
+            m = consumer.receive(1000l);
+            assertNotNull("Message was not received", m);
+        }
+        _session.rollback();
+
+        // receive them again
+        for (int i = 0; i < MESSAGE_NUMBER - 1; i++)
+        {
+            m = consumer.receive(1000l);
+            assertNotNull("Message was not received", m);
+        }
+    }
+
+    public void testGetAllConnections() throws Exception
+    {
+        List> connections = getRestTestHelper().getJsonAsList("/rest/connection");
+        assertEquals("Unexpected number of connections", 1, connections.size());
+        Asserts.assertConnection(connections.get(0), (AMQConnection) _connection);
+    }
+
+    public void testGetVirtualHostConnections() throws Exception
+    {
+        List> connections = getRestTestHelper().getJsonAsList("/rest/connection/test");
+        assertEquals("Unexpected number of connections", 1, connections.size());
+        Asserts.assertConnection(connections.get(0), (AMQConnection) _connection);
+    }
+
+    public void testGetConnectionByName() throws Exception
+    {
+        // get connection name
+        String connectionName = getConnectionName();
+
+        Map connectionDetails = getRestTestHelper().getJsonAsSingletonList("/rest/connection/test/"
+                + URLDecoder.decode(connectionName, "UTF-8"));
+        assertConnection(connectionDetails);
+    }
+
+    public void testGetAllSessions() throws Exception
+    {
+        List> sessions = getRestTestHelper().getJsonAsList("/rest/session");
+        assertEquals("Unexpected number of sessions", 1, sessions.size());
+        assertSession(sessions.get(0), (AMQSession) _session);
+    }
+
+    public void testGetVirtualHostSessions() throws Exception
+    {
+        List> sessions = getRestTestHelper().getJsonAsList("/rest/session/test");
+        assertEquals("Unexpected number of sessions", 1, sessions.size());
+        assertSession(sessions.get(0), (AMQSession) _session);
+    }
+
+    public void testGetConnectionSessions() throws Exception
+    {
+        // get connection name
+        String connectionName = getConnectionName();
+
+        List> sessions = getRestTestHelper().getJsonAsList("/rest/session/test/"
+                + URLDecoder.decode(connectionName, "UTF-8"));
+        assertEquals("Unexpected number of sessions", 1, sessions.size());
+        assertSession(sessions.get(0), (AMQSession) _session);
+    }
+
+    public void testGetSessionByName() throws Exception
+    {
+        // get connection name
+        String connectionName = getConnectionName();
+
+        List> sessions = getRestTestHelper().getJsonAsList("/rest/session/test/"
+                + URLDecoder.decode(connectionName, "UTF-8") + "/" + ((AMQSession) _session).getChannelId());
+        assertEquals("Unexpected number of sessions", 1, sessions.size());
+        assertSession(sessions.get(0), (AMQSession) _session);
+    }
+
+    private void assertConnection(Map connectionDetails) throws JMSException
+    {
+        Asserts.assertConnection(connectionDetails, (AMQConnection) _connection);
+
+        @SuppressWarnings("unchecked")
+        Map statistics = (Map) connectionDetails.get(Asserts.STATISTICS_ATTRIBUTE);
+        assertEquals("Unexpected value of connection statistics attribute " + Connection.BYTES_IN, MESSAGE_NUMBER
+                * MESSAGE_SIZE, statistics.get(Connection.BYTES_IN));
+        assertEquals("Unexpected value of connection statistics attribute " + Connection.BYTES_OUT, MESSAGE_SIZE
+                + ((MESSAGE_NUMBER - 1) * MESSAGE_SIZE) * 2, statistics.get(Connection.BYTES_OUT));
+        assertEquals("Unexpected value of connection statistics attribute " + Connection.MESSAGES_IN, MESSAGE_NUMBER,
+                statistics.get(Connection.MESSAGES_IN));
+        assertEquals("Unexpected value of connection statistics attribute " + Connection.MESSAGES_OUT,
+                MESSAGE_NUMBER * 2 - 1, statistics.get(Connection.MESSAGES_OUT));
+
+        @SuppressWarnings("unchecked")
+        List> sessions = (List>) connectionDetails.get(SESSIONS_ATTRIBUTE);
+        assertNotNull("Sessions cannot be found", sessions);
+        assertEquals("Unexpected number of sessions", 1, sessions.size());
+        assertSession(sessions.get(0), (AMQSession) _session);
+    }
+
+    private void assertSession(Map sessionData, AMQSession session)
+    {
+        assertNotNull("Session map cannot be null", sessionData);
+        Asserts.assertAttributesPresent(sessionData, Session.AVAILABLE_ATTRIBUTES, Session.STATE, Session.DURABLE,
+                Session.LIFETIME_POLICY, Session.TIME_TO_LIVE, Session.CREATED, Session.UPDATED);
+        assertEquals("Unexpecte value of attribute " + Session.NAME, session.getChannelId() + "",
+                sessionData.get(Session.NAME));
+        assertEquals("Unexpecte value of attribute " + Session.PRODUCER_FLOW_BLOCKED, Boolean.FALSE,
+                sessionData.get(Session.PRODUCER_FLOW_BLOCKED));
+        assertEquals("Unexpecte value of attribute " + Session.CHANNEL_ID, session.getChannelId(),
+                sessionData.get(Session.CHANNEL_ID));
+
+        @SuppressWarnings("unchecked")
+        Map statistics = (Map) sessionData.get(Asserts.STATISTICS_ATTRIBUTE);
+        Asserts.assertAttributesPresent(statistics, Session.AVAILABLE_STATISTICS, Session.BYTES_IN, Session.BYTES_OUT,
+                Session.STATE_CHANGED, Session.UNACKNOWLEDGED_BYTES, Session.LOCAL_TRANSACTION_OPEN,
+                Session.XA_TRANSACTION_BRANCH_ENDS, Session.XA_TRANSACTION_BRANCH_STARTS,
+                Session.XA_TRANSACTION_BRANCH_SUSPENDS);
+
+        assertEquals("Unexpecte value of statistic attribute " + Session.UNACKNOWLEDGED_MESSAGES, MESSAGE_NUMBER - 1,
+                statistics.get(Session.UNACKNOWLEDGED_MESSAGES));
+        assertEquals("Unexpecte value of statistic attribute " + Session.LOCAL_TRANSACTION_BEGINS, 4,
+                statistics.get(Session.LOCAL_TRANSACTION_BEGINS));
+        assertEquals("Unexpecte value of statistic attribute " + Session.LOCAL_TRANSACTION_ROLLBACKS, 1,
+                statistics.get(Session.LOCAL_TRANSACTION_ROLLBACKS));
+        assertEquals("Unexpecte value of statistic attribute " + Session.CONSUMER_COUNT, 1,
+                statistics.get(Session.CONSUMER_COUNT));
+    }
+
+    private String getConnectionName() throws IOException
+    {
+        Map hostDetails = getRestTestHelper().getJsonAsSingletonList("/rest/virtualhost/test");
+        @SuppressWarnings("unchecked")
+        List> connections = (List>) hostDetails
+                .get(VirtualHostRestTest.VIRTUALHOST_CONNECTIONS_ATTRIBUTE);
+        assertEquals("Unexpected number of connections", 1, connections.size());
+        Map connection = connections.get(0);
+        String connectionName = (String) connection.get(Connection.NAME);
+        return connectionName;
+    }
+}
diff --git a/java/systests/src/main/java/org/apache/qpid/systest/rest/ExchangeRestTest.java b/java/systests/src/main/java/org/apache/qpid/systest/rest/ExchangeRestTest.java
new file mode 100644
index 0000000000..ec9791db13
--- /dev/null
+++ b/java/systests/src/main/java/org/apache/qpid/systest/rest/ExchangeRestTest.java
@@ -0,0 +1,87 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.qpid.systest.rest;
+
+import java.net.URLDecoder;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.qpid.server.model.Binding;
+import org.apache.qpid.server.model.Exchange;
+
+public class ExchangeRestTest extends QpidRestTestCase
+{
+    public void testGet() throws Exception
+    {
+        List> exchanges = getRestTestHelper().getJsonAsList("/rest/exchange");
+        assertNotNull("Exchanges cannot be null", exchanges);
+        assertTrue("Unexpected number of exchanges", exchanges.size() >= EXPECTED_VIRTUALHOSTS.length * EXPECTED_EXCHANGES.length);
+        for (Map exchange : exchanges)
+        {
+            Asserts.assertExchange((String) exchange.get(Exchange.NAME), (String) exchange.get(Exchange.TYPE), exchange);
+        }
+    }
+
+    public void testGetHostExchanges() throws Exception
+    {
+        List> exchanges = getRestTestHelper().getJsonAsList("/rest/exchange/test");
+        assertNotNull("Users cannot be null", exchanges);
+        assertEquals("Unexpected number of exchanges", exchanges.size(), EXPECTED_EXCHANGES.length);
+        for (String exchangeName : EXPECTED_EXCHANGES)
+        {
+            Map exchange = getRestTestHelper().find(Exchange.NAME, exchangeName, exchanges);
+            assertExchange(exchangeName, exchange);
+        }
+    }
+
+    public void testGetHostExchangeByName() throws Exception
+    {
+        for (String exchangeName : EXPECTED_EXCHANGES)
+        {
+            Map exchange = getRestTestHelper().getJsonAsSingletonList("/rest/exchange/test/"
+                    + URLDecoder.decode(exchangeName, "UTF-8"));
+            assertExchange(exchangeName, exchange);
+        }
+    }
+
+    private void assertExchange(String exchangeName, Map exchange)
+    {
+        assertNotNull("Exchange with name " + exchangeName + " is not found", exchange);
+        String type = (String) exchange.get(Exchange.TYPE);
+        Asserts.assertExchange(exchangeName, type, exchange);
+        if ("direct".equals(type))
+        {
+            assertBindings(exchange);
+        }
+    }
+
+    private void assertBindings(Map exchange)
+    {
+        @SuppressWarnings("unchecked")
+        List> bindings = (List>) exchange.get("bindings");
+        for (String queueName : EXPECTED_QUEUES)
+        {
+            Map binding = getRestTestHelper().find(Binding.NAME, queueName, bindings);
+            Asserts.assertBinding(queueName, (String) exchange.get(Exchange.NAME), binding);
+        }
+    }
+
+}
diff --git a/java/systests/src/main/java/org/apache/qpid/systest/rest/GroupProviderRestTest.java b/java/systests/src/main/java/org/apache/qpid/systest/rest/GroupProviderRestTest.java
new file mode 100644
index 0000000000..861bf8cb71
--- /dev/null
+++ b/java/systests/src/main/java/org/apache/qpid/systest/rest/GroupProviderRestTest.java
@@ -0,0 +1,160 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.qpid.systest.rest;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+
+import org.apache.qpid.server.model.Broker;
+import org.apache.qpid.server.model.Group;
+import org.apache.qpid.server.model.GroupProvider;
+import org.apache.qpid.server.model.LifetimePolicy;
+import org.apache.qpid.server.model.State;
+import org.apache.qpid.server.model.UUIDGenerator;
+
+public class GroupProviderRestTest extends QpidRestTestCase
+{
+    private static final String FILE_GROUP_MANAGER = "FileGroupManager";
+    private File _groupFile;
+
+    @Override
+    public void setUp() throws Exception
+    {
+        _groupFile = createTemporaryGroupFile();
+
+        getBrokerConfiguration().setBrokerAttribute(Broker.GROUP_FILE, _groupFile.getAbsolutePath());
+
+        super.setUp();
+    }
+
+    @Override
+    public void tearDown() throws Exception
+    {
+        super.tearDown();
+
+        if (_groupFile != null)
+        {
+            if (_groupFile.exists())
+            {
+                _groupFile.delete();
+            }
+        }
+    }
+
+    public void testGet() throws Exception
+    {
+        List> providerDetails = getRestTestHelper().getJsonAsList("/rest/groupprovider");
+        assertNotNull("Providers details cannot be null", providerDetails);
+        assertEquals("Unexpected number of providers", 1, providerDetails.size());
+        for (Map provider : providerDetails)
+        {
+            assertProvider(FILE_GROUP_MANAGER, provider);
+            Map data = getRestTestHelper().getJsonAsSingletonList("/rest/groupprovider/"
+                    + provider.get(GroupProvider.NAME));
+            assertNotNull("Cannot load data for " + provider.get(GroupProvider.NAME), data);
+            assertProvider(FILE_GROUP_MANAGER, data);
+        }
+    }
+
+    public void testCreateNewGroup() throws Exception
+    {
+        String groupName = "newGroup";
+
+        Map data = getRestTestHelper().getJsonAsSingletonList("/rest/groupprovider/" + FILE_GROUP_MANAGER);
+        assertNotNull("Cannot load data for provider", data);
+
+        getRestTestHelper().assertNumberOfGroups(data, 1);
+
+        getRestTestHelper().createGroup(groupName, FILE_GROUP_MANAGER);
+
+        data = getRestTestHelper().getJsonAsSingletonList("/rest/groupprovider/" + FILE_GROUP_MANAGER);
+        assertNotNull("Cannot load data for provider", data);
+
+        getRestTestHelper().assertNumberOfGroups(data, 2);
+    }
+
+    public void testRemoveGroup() throws Exception
+    {
+        String groupName = "myGroup";
+
+        Map data = getRestTestHelper().getJsonAsSingletonList("/rest/groupprovider/" + FILE_GROUP_MANAGER);
+        assertNotNull("Cannot load data for provider", data);
+
+        getRestTestHelper().assertNumberOfGroups(data, 1);
+
+        getRestTestHelper().removeGroup(groupName, FILE_GROUP_MANAGER);
+
+        data = getRestTestHelper().getJsonAsSingletonList("/rest/groupprovider/" + FILE_GROUP_MANAGER);
+        assertNotNull("Cannot load data for provider", data);
+
+        getRestTestHelper().assertNumberOfGroups(data, 0);
+    }
+
+
+    private void assertProvider(String type, Map provider)
+    {
+        Asserts.assertAttributesPresent(provider, GroupProvider.AVAILABLE_ATTRIBUTES,
+                GroupProvider.CREATED, GroupProvider.UPDATED, GroupProvider.DESCRIPTION,
+                GroupProvider.TIME_TO_LIVE);
+        assertEquals("Unexpected value of provider attribute " + GroupProvider.STATE, State.ACTIVE.name(),
+                provider.get(GroupProvider.STATE));
+        assertEquals("Unexpected value of provider attribute " + GroupProvider.LIFETIME_POLICY,
+                LifetimePolicy.PERMANENT.name(), provider.get(GroupProvider.LIFETIME_POLICY));
+        assertEquals("Unexpected value of provider attribute " + GroupProvider.DURABLE, Boolean.TRUE,
+                provider.get(GroupProvider.DURABLE));
+        assertEquals("Unexpected value of provider attribute " + GroupProvider.TYPE, type,
+                provider.get(GroupProvider.TYPE));
+
+        final String name = (String) provider.get(GroupProvider.NAME);
+        assertEquals("Unexpected value of provider attribute " + GroupProvider.NAME, type,
+                name);
+
+        @SuppressWarnings("unchecked")
+        List> groups = (List>) provider.get("groups");
+        assertNotNull("Groups were not found", groups);
+        assertEquals("Unexpected number of groups", 1, groups.size());
+        for (Map group : groups)
+        {
+
+            final String groupName = (String) group.get(Group.NAME);
+            assertNotNull("Attribute " + Group.NAME, groupName);
+
+            assertNotNull("Attribute " + Group.ID, group.get(Group.ID));
+            assertEquals("Attribute " + Group.ID, UUIDGenerator.generateGroupUUID(name, groupName).toString(), group.get(Group.ID));
+        }
+    }
+
+    private File createTemporaryGroupFile() throws Exception
+    {
+        File groupFile = File.createTempFile("group", "grp");
+        groupFile.deleteOnExit();
+
+        Properties props = new Properties();
+        props.put("myGroup.users", "guest");
+
+        props.store(new FileOutputStream(groupFile), "test group file");
+
+        return groupFile;
+    }
+}
diff --git a/java/systests/src/main/java/org/apache/qpid/systest/rest/GroupRestTest.java b/java/systests/src/main/java/org/apache/qpid/systest/rest/GroupRestTest.java
new file mode 100644
index 0000000000..d3f93cc0fe
--- /dev/null
+++ b/java/systests/src/main/java/org/apache/qpid/systest/rest/GroupRestTest.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.systest.rest;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+
+import org.apache.qpid.server.model.Broker;
+import org.apache.qpid.server.model.GroupMember;
+
+public class GroupRestTest extends QpidRestTestCase
+{
+    private static final String GROUP_NAME = "myGroup";
+    private static final String FILE_GROUP_MANAGER = "FileGroupManager";
+    private static final String EXISTING_MEMBER = "user1";
+    private static final String NEW_MEMBER = "user2";
+
+    private File _groupFile;
+
+    @Override
+    public void setUp() throws Exception
+    {
+        _groupFile = createTemporaryGroupFile();
+
+        getBrokerConfiguration().setBrokerAttribute(Broker.GROUP_FILE, _groupFile.getAbsolutePath());
+
+        super.setUp();
+    }
+
+    @Override
+    public void tearDown() throws Exception
+    {
+        super.tearDown();
+
+        if (_groupFile != null)
+        {
+            if (_groupFile.exists())
+            {
+                _groupFile.delete();
+            }
+        }
+    }
+
+    public void testGet() throws Exception
+    {
+        Map group = getRestTestHelper().getJsonAsSingletonList("/rest/group/FileGroupManager/myGroup");
+        List> groupmembers = (List>) group.get("groupmembers");
+        assertEquals(1, groupmembers.size());
+
+        Map member1 = groupmembers.get(0);
+        assertEquals(EXISTING_MEMBER, (String)member1.get(GroupMember.NAME));
+    }
+
+    public void testCreateNewMemberOfGroup() throws Exception
+    {
+        Map group = getRestTestHelper().getJsonAsSingletonList("/rest/group/FileGroupManager/myGroup");
+        getRestTestHelper().assertNumberOfGroupMembers(group, 1);
+
+        getRestTestHelper().createNewGroupMember(FILE_GROUP_MANAGER, GROUP_NAME, NEW_MEMBER);
+
+        group = getRestTestHelper().getJsonAsSingletonList("/rest/group/FileGroupManager/myGroup");
+        getRestTestHelper().assertNumberOfGroupMembers(group, 2);
+    }
+
+    public void testRemoveMemberFromGroup() throws Exception
+    {
+        Map group = getRestTestHelper().getJsonAsSingletonList("/rest/group/FileGroupManager/myGroup");
+        getRestTestHelper().assertNumberOfGroupMembers(group, 1);
+
+        getRestTestHelper().removeMemberFromGroup(FILE_GROUP_MANAGER, GROUP_NAME, EXISTING_MEMBER);
+
+        group = getRestTestHelper().getJsonAsSingletonList("/rest/group/FileGroupManager/myGroup");
+        getRestTestHelper().assertNumberOfGroupMembers(group, 0);
+    }
+
+    private File createTemporaryGroupFile() throws Exception
+    {
+        File groupFile = File.createTempFile("group", "grp");
+        groupFile.deleteOnExit();
+
+        Properties props = new Properties();
+        props.put(GROUP_NAME + ".users", EXISTING_MEMBER);
+
+        props.store(new FileOutputStream(groupFile), "test group file");
+
+        return groupFile;
+    }
+}
diff --git a/java/systests/src/main/java/org/apache/qpid/systest/rest/LogRecordsRestTest.java b/java/systests/src/main/java/org/apache/qpid/systest/rest/LogRecordsRestTest.java
new file mode 100644
index 0000000000..a2f9d3189c
--- /dev/null
+++ b/java/systests/src/main/java/org/apache/qpid/systest/rest/LogRecordsRestTest.java
@@ -0,0 +1,42 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.qpid.systest.rest;
+
+import java.util.List;
+import java.util.Map;
+
+public class LogRecordsRestTest extends QpidRestTestCase
+{
+    public void testGet() throws Exception
+    {
+        List> logs = getRestTestHelper().getJsonAsList("/rest/logrecords");
+        assertNotNull("Logs data cannot be null", logs);
+        assertTrue("Logs are not found", logs.size() > 0);
+        Map record = getRestTestHelper().find("message", "[Broker] BRK-1004 : Qpid Broker Ready", logs);
+
+        assertNotNull("BRK-1004 message is not found", record);
+        assertNotNull("Message id cannot be null", record.get("id"));
+        assertNotNull("Message timestamp cannot be null", record.get("timestamp"));
+        assertEquals("Unexpected log level", "INFO", record.get("level"));
+        assertEquals("Unexpected thread", "main", record.get("thread"));
+        assertEquals("Unexpected logger", "qpid.message.broker.ready", record.get("logger"));
+    }
+}
diff --git a/java/systests/src/main/java/org/apache/qpid/systest/rest/MessagesRestTest.java b/java/systests/src/main/java/org/apache/qpid/systest/rest/MessagesRestTest.java
new file mode 100644
index 0000000000..fb6bfca1d8
--- /dev/null
+++ b/java/systests/src/main/java/org/apache/qpid/systest/rest/MessagesRestTest.java
@@ -0,0 +1,354 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.qpid.systest.rest;
+
+import java.io.IOException;
+import java.net.HttpURLConnection;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.TimeUnit;
+
+import javax.jms.BytesMessage;
+import javax.jms.Connection;
+import javax.jms.DeliveryMode;
+import javax.jms.Destination;
+import javax.jms.Message;
+import javax.jms.MessageProducer;
+import javax.jms.Session;
+
+import org.codehaus.jackson.JsonParseException;
+import org.codehaus.jackson.map.JsonMappingException;
+
+public class MessagesRestTest extends QpidRestTestCase
+{
+
+    /**
+     * Message number to publish into queue
+     */
+    private static final int MESSAGE_NUMBER = 12;
+
+    private Connection _connection;
+    private Session _session;
+    private MessageProducer _producer;
+    private long _startTime;
+    private long _ttl;
+
+    public void setUp() throws Exception
+    {
+        super.setUp();
+        _startTime = System.currentTimeMillis();
+        _connection = getConnection();
+        _session = _connection.createSession(true, Session.SESSION_TRANSACTED);
+        String queueName = getTestQueueName();
+        Destination queue = _session.createQueue(queueName);
+        _session.createConsumer(queue);
+        _producer = _session.createProducer(queue);
+
+        _ttl = TimeUnit.DAYS.toMillis(1);
+        for (int i = 0; i < MESSAGE_NUMBER; i++)
+        {
+            Message m = _session.createTextMessage("Test-" + i);
+            m.setIntProperty("index", i);
+            if (i % 2 == 0)
+            {
+                _producer.send(m);
+            }
+            else
+            {
+                _producer.send(m, DeliveryMode.NON_PERSISTENT, 5, _ttl);
+            }
+        }
+        _session.commit();
+    }
+
+    public void testGet() throws Exception
+    {
+        String queueName = getTestQueueName();
+        List> messages = getRestTestHelper().getJsonAsList("/rest/message/test/" + queueName);
+        assertNotNull("Messages are not found", messages);
+        assertEquals("Unexpected number of messages", MESSAGE_NUMBER, messages.size());
+        int position = 0;
+        for (Map message : messages)
+        {
+            assertMessage(position, message);
+            position++;
+        }
+    }
+
+    public void testGetMessageContent() throws Exception
+    {
+        String queueName = getTestQueueName();
+
+        // add bytes message
+        BytesMessage byteMessage = _session.createBytesMessage();
+        byte[] messageBytes = "Test".getBytes();
+        byteMessage.writeBytes(messageBytes);
+        byteMessage.setStringProperty("test", "value");
+        _producer.send(byteMessage);
+        _session.commit();
+
+        // get message IDs
+        List ids = getMesssageIds(queueName);
+
+        Map message = getRestTestHelper().getJsonAsMap("/rest/message/test/" + queueName + "/" + ids.get(0));
+        assertMessageAttributes(message);
+        assertMessageAttributeValues(message, true);
+
+        @SuppressWarnings("unchecked")
+        Map headers = (Map) message.get("headers");
+        assertNotNull("Message headers are not found", headers);
+        assertEquals("Unexpected message header", 0, headers.get("index"));
+
+        Long lastMessageId = ids.get(ids.size() - 1);
+        message = getRestTestHelper().getJsonAsMap("/rest/message/test/" + queueName + "/" + lastMessageId);
+        assertMessageAttributes(message);
+        assertEquals("Unexpected message attribute mimeType", "application/octet-stream", message.get("mimeType"));
+        assertEquals("Unexpected message attribute size", 4, message.get("size"));
+
+        @SuppressWarnings("unchecked")
+        Map bytesMessageHeader = (Map) message.get("headers");
+        assertNotNull("Message headers are not found", bytesMessageHeader);
+        assertEquals("Unexpected message header", "value", bytesMessageHeader.get("test"));
+
+        // get content
+        HttpURLConnection connection = getRestTestHelper().openManagementConnection("/rest/message-content/test/" + queueName + "/"
+                + lastMessageId, "GET");
+        connection.connect();
+        byte[] data = getRestTestHelper().readConnectionInputStream(connection);
+        assertTrue("Unexpected message", Arrays.equals(messageBytes, data));
+
+    }
+
+    public void testPostMoveMessages() throws Exception
+    {
+        String queueName = getTestQueueName();
+        String queueName2 = queueName + "_2";
+        Destination queue2 = _session.createQueue(queueName2);
+        _session.createConsumer(queue2);
+
+        // get message IDs
+        List ids = getMesssageIds(queueName);
+
+        // move half of the messages
+        int movedNumber = ids.size() / 2;
+        List movedMessageIds = new ArrayList();
+        for (int i = 0; i < movedNumber; i++)
+        {
+            movedMessageIds.add(ids.remove(i));
+        }
+
+        // move messages
+        HttpURLConnection connection = getRestTestHelper().openManagementConnection("/rest/message/test/" + queueName, "POST");
+
+        Map messagesData = new HashMap();
+        messagesData.put("messages", movedMessageIds);
+        messagesData.put("destinationQueue", queueName2);
+        messagesData.put("move", Boolean.TRUE);
+
+        getRestTestHelper().writeJsonRequest(connection, messagesData);
+        assertEquals("Unexpected response code", 200, connection.getResponseCode());
+
+        // check messages on target queue
+        List> messages = getRestTestHelper().getJsonAsList("/rest/message/test/" + queueName2);
+        assertNotNull("Messages are not found", messages);
+        assertEquals("Unexpected number of messages", movedMessageIds.size(), messages.size());
+        for (Long id : movedMessageIds)
+        {
+            Map message = getRestTestHelper().find("id", id.intValue(), messages);
+            assertMessageAttributes(message);
+        }
+
+        // check messages on original queue
+        messages = getRestTestHelper().getJsonAsList("/rest/message/test/" + queueName);
+        assertNotNull("Messages are not found", messages);
+        assertEquals("Unexpected number of messages", ids.size(), messages.size());
+        for (Long id : ids)
+        {
+            Map message = getRestTestHelper().find("id", id.intValue(), messages);
+            assertMessageAttributes(message);
+        }
+        for (Long id : movedMessageIds)
+        {
+            Map message = getRestTestHelper().find("id", id.intValue(), messages);
+            assertNull("Moved message " + id + " is found on original queue", message);
+        }
+    }
+
+    public void testPostCopyMessages() throws Exception
+    {
+        String queueName = getTestQueueName();
+        String queueName2 = queueName + "_2";
+        Destination queue2 = _session.createQueue(queueName2);
+        _session.createConsumer(queue2);
+
+        // get message IDs
+        List ids = getMesssageIds(queueName);
+
+        // copy half of the messages
+        int copyNumber = ids.size() / 2;
+        List copyMessageIds = new ArrayList();
+        for (int i = 0; i < copyNumber; i++)
+        {
+            copyMessageIds.add(ids.remove(i));
+        }
+
+        // copy messages
+        HttpURLConnection connection = getRestTestHelper().openManagementConnection("/rest/message/test/" + queueName, "POST");
+
+        Map messagesData = new HashMap();
+        messagesData.put("messages", copyMessageIds);
+        messagesData.put("destinationQueue", queueName2);
+
+        getRestTestHelper().writeJsonRequest(connection, messagesData);
+        assertEquals("Unexpected response code", 200, connection.getResponseCode());
+
+        // check messages on target queue
+        List> messages = getRestTestHelper().getJsonAsList("/rest/message/test/" + queueName2);
+        assertNotNull("Messages are not found", messages);
+        assertEquals("Unexpected number of messages", copyMessageIds.size(), messages.size());
+        for (Long id : copyMessageIds)
+        {
+            Map message = getRestTestHelper().find("id", id.intValue(), messages);
+            assertMessageAttributes(message);
+        }
+
+        // check messages on original queue
+        messages = getRestTestHelper().getJsonAsList("/rest/message/test/" + queueName);
+        assertNotNull("Messages are not found", messages);
+        assertEquals("Unexpected number of messages", MESSAGE_NUMBER, messages.size());
+        for (Long id : ids)
+        {
+            Map message = getRestTestHelper().find("id", id.intValue(), messages);
+            assertMessageAttributes(message);
+        }
+        for (Long id : copyMessageIds)
+        {
+            Map message = getRestTestHelper().find("id", id.intValue(), messages);
+            assertMessageAttributes(message);
+        }
+    }
+
+    public void testDeleteMessages() throws Exception
+    {
+        String queueName = getTestQueueName();
+
+        // get message IDs
+        List ids = getMesssageIds(queueName);
+
+        // delete half of the messages
+        int deleteNumber = ids.size() / 2;
+        StringBuilder queryString = new StringBuilder();
+        List deleteMessageIds = new ArrayList();
+        for (int i = 0; i < deleteNumber; i++)
+        {
+            Long id = ids.remove(i);
+            deleteMessageIds.add(id);
+            if (queryString.length() > 0)
+            {
+                queryString.append("&");
+            }
+            queryString.append("id=").append(id);
+        }
+
+        // delete messages
+        HttpURLConnection connection = getRestTestHelper().openManagementConnection(
+                "/rest/message/test/" + queueName + "?" + queryString.toString(), "DELETE");
+        connection.connect();
+        assertEquals("Unexpected response code", 200, connection.getResponseCode());
+
+        // check messages on queue
+        List> messages = getRestTestHelper().getJsonAsList("/rest/message/test/" + queueName);
+        assertNotNull("Messages are not found", messages);
+        assertEquals("Unexpected number of messages", ids.size(), messages.size());
+        for (Long id : ids)
+        {
+            Map message = getRestTestHelper().find("id", id.intValue(), messages);
+            assertMessageAttributes(message);
+        }
+        for (Long id : deleteMessageIds)
+        {
+            Map message = getRestTestHelper().find("id", id.intValue(), messages);
+            assertNull("Message with id " + id + " was not deleted", message);
+        }
+    }
+
+    private List getMesssageIds(String queueName) throws IOException, JsonParseException, JsonMappingException
+    {
+        List> messages = getRestTestHelper().getJsonAsList("/rest/message/test/" + queueName);
+        List ids = new ArrayList();
+        for (Map message : messages)
+        {
+            ids.add(((Number) message.get("id")).longValue());
+        }
+        return ids;
+    }
+
+    private void assertMessage(int position, Map message)
+    {
+        assertMessageAttributes(message);
+
+        assertEquals("Unexpected message attribute position", position, message.get("position"));
+        assertEquals("Unexpected message attribute size", position < 10 ? 6 : 7, message.get("size"));
+        boolean even = position % 2 == 0;
+        assertMessageAttributeValues(message, even);
+    }
+
+    private void assertMessageAttributeValues(Map message, boolean even)
+    {
+        if (even)
+        {
+            assertEquals("Unexpected message attribute expirationTime", 0, message.get("expirationTime"));
+            assertEquals("Unexpected message attribute priority", 4, message.get("priority"));
+            assertEquals("Unexpected message attribute persistent", Boolean.TRUE, message.get("persistent"));
+        }
+        else
+        {
+            assertEquals("Unexpected message attribute expirationTime", ((Number) message.get("timestamp")).longValue()
+                    + _ttl, message.get("expirationTime"));
+            assertEquals("Unexpected message attribute priority", 5, message.get("priority"));
+            assertEquals("Unexpected message attribute persistent", Boolean.FALSE, message.get("persistent"));
+        }
+        assertEquals("Unexpected message attribute mimeType", "text/plain", message.get("mimeType"));
+        assertEquals("Unexpected message attribute userId", "guest", message.get("userId"));
+        assertEquals("Unexpected message attribute deliveryCount", 0, message.get("deliveryCount"));
+        assertEquals("Unexpected message attribute state", "Available", message.get("state"));
+    }
+
+    private void assertMessageAttributes(Map message)
+    {
+        assertNotNull("Message map cannot be null", message);
+        assertNotNull("Unexpected message attribute deliveryCount", message.get("deliveryCount"));
+        assertNotNull("Unexpected message attribute state", message.get("state"));
+        assertNotNull("Unexpected message attribute id", message.get("id"));
+        assertNotNull("Message arrivalTime cannot be null", message.get("arrivalTime"));
+        assertNotNull("Message timestamp cannot be null", message.get("timestamp"));
+        assertTrue("Message arrivalTime cannot be null", ((Number) message.get("arrivalTime")).longValue() > _startTime);
+        assertNotNull("Message messageId cannot be null", message.get("messageId"));
+        assertNotNull("Unexpected message attribute mimeType", message.get("mimeType"));
+        assertNotNull("Unexpected message attribute userId", message.get("userId"));
+        assertNotNull("Message priority cannot be null", message.get("priority"));
+        assertNotNull("Message expirationTime cannot be null", message.get("expirationTime"));
+        assertNotNull("Message persistent cannot be null", message.get("persistent"));
+    }
+}
diff --git a/java/systests/src/main/java/org/apache/qpid/systest/rest/PortRestTest.java b/java/systests/src/main/java/org/apache/qpid/systest/rest/PortRestTest.java
new file mode 100644
index 0000000000..578565be05
--- /dev/null
+++ b/java/systests/src/main/java/org/apache/qpid/systest/rest/PortRestTest.java
@@ -0,0 +1,64 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.qpid.systest.rest;
+
+import java.net.URLDecoder;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.qpid.server.model.Port;
+import org.apache.qpid.test.utils.TestBrokerConfiguration;
+
+public class PortRestTest extends QpidRestTestCase
+{
+    public void testGet() throws Exception
+    {
+        List> ports = getRestTestHelper().getJsonAsList("/rest/port/");
+        assertNotNull("Port data cannot be null", ports);
+        assertEquals("Unexpected number of ports", 4, ports.size());
+
+        String httpPortName = TestBrokerConfiguration.ENTRY_NAME_HTTP_PORT;
+        Map portData = getRestTestHelper().find(Port.NAME, httpPortName, ports);
+        assertNotNull("Http port " + httpPortName + " is not found", portData);
+        Asserts.assertPortAttributes(portData);
+
+        String amqpPortName = TestBrokerConfiguration.ENTRY_NAME_AMQP_PORT;
+        Map amqpPortData = getRestTestHelper().find(Port.NAME, amqpPortName, ports);
+        assertNotNull("Amqp port " + amqpPortName + " is not found", amqpPortData);
+        Asserts.assertPortAttributes(amqpPortData);
+    }
+
+    public void testGetPort() throws Exception
+    {
+        List> ports = getRestTestHelper().getJsonAsList("/rest/port/");
+        assertNotNull("Ports data cannot be null", ports);
+        assertEquals("Unexpected number of ports", 4, ports.size());
+        for (Map portMap : ports)
+        {
+            String portName = (String) portMap.get(Port.NAME);
+            assertNotNull("Port name attribute is not found", portName);
+            Map portData = getRestTestHelper().getJsonAsSingletonList("/rest/port/" + URLDecoder.decode(portName, "UTF-8"));
+            assertNotNull("Port " + portName + " is not found", portData);
+            Asserts.assertPortAttributes(portData);
+        }
+    }
+
+}
diff --git a/java/systests/src/main/java/org/apache/qpid/systest/rest/QpidRestTestCase.java b/java/systests/src/main/java/org/apache/qpid/systest/rest/QpidRestTestCase.java
new file mode 100644
index 0000000000..671bdd7eb8
--- /dev/null
+++ b/java/systests/src/main/java/org/apache/qpid/systest/rest/QpidRestTestCase.java
@@ -0,0 +1,84 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.qpid.systest.rest;
+
+import java.io.IOException;
+
+import org.apache.commons.configuration.ConfigurationException;
+import org.apache.qpid.server.model.Port;
+import org.apache.qpid.test.utils.TestBrokerConfiguration;
+import org.apache.qpid.test.utils.QpidBrokerTestCase;
+
+public class QpidRestTestCase extends QpidBrokerTestCase
+{
+    public static final String TEST1_VIRTUALHOST = "test";
+    public static final String TEST2_VIRTUALHOST = "test2";
+    public static final String TEST3_VIRTUALHOST = "test3";
+
+    public static final String[] EXPECTED_VIRTUALHOSTS = { TEST1_VIRTUALHOST, TEST2_VIRTUALHOST, TEST3_VIRTUALHOST};
+    public static final String[] EXPECTED_QUEUES = { "queue", "ping" };
+    public static final String[] EXPECTED_EXCHANGES = { "amq.fanout", "amq.match", "amq.direct","amq.topic","<>" };
+
+    private RestTestHelper _restTestHelper = new RestTestHelper(findFreePort());
+
+    @Override
+    public void setUp() throws Exception
+    {
+        // Set up virtualhost config with queues and bindings to the amq.direct
+        for (String virtualhost : EXPECTED_VIRTUALHOSTS)
+        {
+            createTestVirtualHost(0, virtualhost);
+            for (String queue : EXPECTED_QUEUES)
+            {
+                setVirtualHostConfigurationProperty("virtualhosts.virtualhost." + virtualhost + ".queues.exchange", "amq.direct");
+                setVirtualHostConfigurationProperty("virtualhosts.virtualhost." + virtualhost + ".queues.queue(-1).name", queue);
+            }
+        }
+
+        customizeConfiguration();
+        super.setUp();
+    }
+
+    @Override
+    protected void tearDown() throws Exception
+    {
+        try
+        {
+            super.tearDown();
+        }
+        finally
+        {
+            getRestTestHelper().tearDown();
+        }
+    }
+
+    protected void customizeConfiguration() throws ConfigurationException, IOException
+    {
+        TestBrokerConfiguration config = getBrokerConfiguration();
+        config.addHttpManagementConfiguration();
+        config.setObjectAttribute(TestBrokerConfiguration.ENTRY_NAME_HTTP_PORT, Port.PORT, _restTestHelper.getHttpPort());
+    }
+
+    public RestTestHelper getRestTestHelper()
+    {
+        return _restTestHelper;
+    }
+}
diff --git a/java/systests/src/main/java/org/apache/qpid/systest/rest/QueueRestTest.java b/java/systests/src/main/java/org/apache/qpid/systest/rest/QueueRestTest.java
new file mode 100644
index 0000000000..1f441e7cbb
--- /dev/null
+++ b/java/systests/src/main/java/org/apache/qpid/systest/rest/QueueRestTest.java
@@ -0,0 +1,225 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.qpid.systest.rest;
+
+import java.io.IOException;
+import java.net.HttpURLConnection;
+import java.net.URLDecoder;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import javax.jms.Connection;
+import javax.jms.Destination;
+import javax.jms.Message;
+import javax.jms.MessageConsumer;
+import javax.jms.MessageProducer;
+import javax.jms.Session;
+
+import org.apache.qpid.server.model.Binding;
+import org.apache.qpid.server.model.Consumer;
+import org.apache.qpid.server.model.LifetimePolicy;
+import org.apache.qpid.server.model.Queue;
+
+public class QueueRestTest extends QpidRestTestCase
+{
+    private static final String QUEUE_ATTRIBUTE_CONSUMERS = "consumers";
+    private static final String QUEUE_ATTRIBUTE_BINDINGS = "bindings";
+
+    /**
+     * Message number to publish into queue
+     */
+    private static final int MESSAGE_NUMBER = 2;
+    private static final int MESSAGE_PAYLOAD_SIZE = 6;
+    private static final int ENQUEUED_MESSAGES = 1;
+    private static final int DEQUEUED_MESSAGES = 1;
+    private static final int ENQUEUED_BYTES = MESSAGE_PAYLOAD_SIZE;
+    private static final int DEQUEUED_BYTES = MESSAGE_PAYLOAD_SIZE;
+
+    private Connection _connection;
+
+    public void setUp() throws Exception
+    {
+        super.setUp();
+        _connection = getConnection();
+        Session session = _connection.createSession(true, Session.SESSION_TRANSACTED);
+        String queueName = getTestQueueName();
+        Destination queue = session.createQueue(queueName);
+        MessageConsumer consumer = session.createConsumer(queue);
+        MessageProducer producer = session.createProducer(queue);
+
+        for (int i = 0; i < MESSAGE_NUMBER; i++)
+        {
+            producer.send(session.createTextMessage("Test-" + i));
+        }
+        session.commit();
+        _connection.start();
+        Message m = consumer.receive(1000l);
+        assertNotNull("Message is not received", m);
+        session.commit();
+    }
+
+    public void testGetVirtualHostQueues() throws Exception
+    {
+        String queueName = getTestQueueName();
+        List> queues = getRestTestHelper().getJsonAsList("/rest/queue/test");
+        assertEquals("Unexpected number of queues", EXPECTED_QUEUES.length + 1, queues.size());
+        String[] expectedQueues = new String[EXPECTED_QUEUES.length + 1];
+        System.arraycopy(EXPECTED_QUEUES, 0, expectedQueues, 0, EXPECTED_QUEUES.length);
+        expectedQueues[EXPECTED_QUEUES.length] = queueName;
+
+        for (String name : expectedQueues)
+        {
+            Map queueDetails = getRestTestHelper().find(Queue.NAME, name, queues);
+            Asserts.assertQueue(name, "standard", queueDetails);
+
+            @SuppressWarnings("unchecked")
+            List> bindings = (List>) queueDetails.get(QUEUE_ATTRIBUTE_BINDINGS);
+            assertNotNull("Queue bindings are not found", bindings);
+            assertEquals("Unexpected number of bindings", 2, bindings.size());
+
+            Map defaultExchangeBinding = getRestTestHelper().find(Binding.EXCHANGE, "<>", bindings);
+            Map directExchangeBinding = getRestTestHelper().find(Binding.EXCHANGE, "amq.direct", bindings);
+            Asserts.assertBinding(name, "<>", defaultExchangeBinding);
+            Asserts.assertBinding(name, "amq.direct", directExchangeBinding);
+        }
+    }
+
+    public void testGetByName() throws Exception
+    {
+        String queueName = getTestQueueName();
+        Map queueDetails = getRestTestHelper().getJsonAsSingletonList("/rest/queue/test/" + queueName);
+        Asserts.assertQueue(queueName, "standard", queueDetails);
+        assertStatistics(queueDetails);
+
+        @SuppressWarnings("unchecked")
+        List> bindings = (List>) queueDetails.get(QUEUE_ATTRIBUTE_BINDINGS);
+        assertNotNull("Queue bindings are not found", bindings);
+        assertEquals("Unexpected number of bindings", 2, bindings.size());
+
+        Map defaultExchangeBinding = getRestTestHelper().find(Binding.EXCHANGE, "<>", bindings);
+        Map directExchangeBinding = getRestTestHelper().find(Binding.EXCHANGE, "amq.direct", bindings);
+        Asserts.assertBinding(queueName, "<>", defaultExchangeBinding);
+        Asserts.assertBinding(queueName, "amq.direct", directExchangeBinding);
+
+        @SuppressWarnings("unchecked")
+        List> consumers = (List>) queueDetails.get(QUEUE_ATTRIBUTE_CONSUMERS);
+        assertNotNull("Queue consumers are not found", consumers);
+        assertEquals("Unexpected number of consumers", 1, consumers.size());
+        assertConsumer(consumers.get(0));
+    }
+
+    public void testPutCreateBinding() throws Exception
+    {
+        String queueName = getTestQueueName();
+        String bindingName = queueName + 2;
+        String[] exchanges = { "amq.direct", "amq.fanout", "amq.topic", "amq.match", "<>" };
+
+        for (int i = 0; i < exchanges.length; i++)
+        {
+            createBinding(bindingName, exchanges[i], queueName);
+        }
+
+        Map queueDetails = getRestTestHelper().getJsonAsSingletonList("/rest/queue/test/" + queueName);
+        Asserts.assertQueue(queueName, "standard", queueDetails);
+
+        @SuppressWarnings("unchecked")
+        List> bindings = (List>) queueDetails.get(QUEUE_ATTRIBUTE_BINDINGS);
+        assertNotNull("Queue bindings are not found", bindings);
+        assertEquals("Unexpected number of bindings", exchanges.length + 2, bindings.size());
+
+        Map searchAttributes = new HashMap();
+        searchAttributes.put(Binding.NAME, bindingName);
+
+        for (int i = 0; i < exchanges.length; i++)
+        {
+            searchAttributes.put(Binding.EXCHANGE, exchanges[i]);
+            Map binding = getRestTestHelper().find(searchAttributes, bindings);
+            Asserts.assertBinding(bindingName, queueName, exchanges[i], binding);
+        }
+    }
+
+    private void createBinding(String bindingName, String exchangeName, String queueName) throws IOException
+    {
+        HttpURLConnection connection = getRestTestHelper().openManagementConnection(
+                "/rest/binding/test/" + URLDecoder.decode(exchangeName, "UTF-8") + "/" + queueName + "/" + bindingName,
+                "PUT");
+
+        Map bindingData = new HashMap();
+        bindingData.put(Binding.NAME, bindingName);
+        bindingData.put(Binding.EXCHANGE, exchangeName);
+        bindingData.put(Binding.QUEUE, queueName);
+
+        getRestTestHelper().writeJsonRequest(connection, bindingData);
+        assertEquals("Unexpected response code", 201, connection.getResponseCode());
+
+        connection.disconnect();
+    }
+
+    private void assertConsumer(Map consumer)
+    {
+        assertNotNull("Consumer map should not be null", consumer);
+        Asserts.assertAttributesPresent(consumer, Consumer.AVAILABLE_ATTRIBUTES, Consumer.STATE, Consumer.TIME_TO_LIVE,
+                Consumer.CREATED, Consumer.UPDATED, Consumer.SETTLEMENT_MODE, Consumer.EXCLUSIVE, Consumer.SELECTOR,
+                Consumer.NO_LOCAL);
+
+        assertEquals("Unexpected binding attribute " + Consumer.NAME, "1", consumer.get(Consumer.NAME));
+        assertEquals("Unexpected binding attribute " + Consumer.DURABLE, Boolean.FALSE, consumer.get(Consumer.DURABLE));
+        assertEquals("Unexpected binding attribute " + Consumer.LIFETIME_POLICY, LifetimePolicy.AUTO_DELETE.name(),
+                consumer.get(Consumer.LIFETIME_POLICY));
+        assertEquals("Unexpected binding attribute " + Consumer.DISTRIBUTION_MODE, "MOVE",
+                consumer.get(Consumer.DISTRIBUTION_MODE));
+
+        @SuppressWarnings("unchecked")
+        Map statistics = (Map) consumer.get(Asserts.STATISTICS_ATTRIBUTE);
+        assertNotNull("Consumer statistics is not present", statistics);
+        Asserts.assertAttributesPresent(statistics, Consumer.AVAILABLE_STATISTICS, Consumer.STATE_CHANGED);
+    }
+
+    private void assertStatistics(Map queueDetails)
+    {
+        @SuppressWarnings("unchecked")
+        Map statistics = (Map) queueDetails.get(Asserts.STATISTICS_ATTRIBUTE);
+        assertEquals("Unexpected queue statistics attribute " + Queue.PERSISTENT_DEQUEUED_MESSAGES, DEQUEUED_MESSAGES,
+                statistics.get(Queue.PERSISTENT_DEQUEUED_MESSAGES));
+        assertEquals("Unexpected queue statistics attribute " + Queue.QUEUE_DEPTH_MESSAGES, ENQUEUED_MESSAGES,
+                statistics.get(Queue.QUEUE_DEPTH_MESSAGES));
+        assertEquals("Unexpected queue statistics attribute " + Queue.CONSUMER_COUNT, 1,
+                statistics.get(Queue.CONSUMER_COUNT));
+        assertEquals("Unexpected queue statistics attribute " + Queue.CONSUMER_COUNT_WITH_CREDIT, 1,
+                statistics.get(Queue.CONSUMER_COUNT_WITH_CREDIT));
+        assertEquals("Unexpected queue statistics attribute " + Queue.BINDING_COUNT, 2, statistics.get(Queue.BINDING_COUNT));
+        assertEquals("Unexpected queue statistics attribute " + Queue.PERSISTENT_DEQUEUED_MESSAGES, DEQUEUED_MESSAGES,
+                statistics.get(Queue.PERSISTENT_DEQUEUED_MESSAGES));
+        assertEquals("Unexpected queue statistics attribute " + Queue.TOTAL_DEQUEUED_MESSAGES, DEQUEUED_MESSAGES,
+                statistics.get(Queue.TOTAL_DEQUEUED_MESSAGES));
+        assertEquals("Unexpected queue statistics attribute " + Queue.TOTAL_DEQUEUED_BYTES, DEQUEUED_BYTES,
+                statistics.get(Queue.TOTAL_DEQUEUED_BYTES));
+        assertEquals("Unexpected queue statistics attribute " + Queue.PERSISTENT_DEQUEUED_BYTES, DEQUEUED_BYTES,
+                statistics.get(Queue.TOTAL_DEQUEUED_BYTES));
+        assertEquals("Unexpected queue statistics attribute " + Queue.PERSISTENT_ENQUEUED_BYTES, ENQUEUED_BYTES
+                + DEQUEUED_BYTES, statistics.get(Queue.PERSISTENT_ENQUEUED_BYTES));
+        assertEquals("Unexpected queue statistics attribute " + Queue.TOTAL_ENQUEUED_BYTES, ENQUEUED_BYTES + DEQUEUED_BYTES,
+                statistics.get(Queue.TOTAL_ENQUEUED_BYTES));
+        assertEquals("Unexpected queue statistics attribute " + Queue.QUEUE_DEPTH_BYTES, ENQUEUED_BYTES,
+                statistics.get(Queue.QUEUE_DEPTH_BYTES));
+    }
+}
diff --git a/java/systests/src/main/java/org/apache/qpid/systest/rest/RestTestHelper.java b/java/systests/src/main/java/org/apache/qpid/systest/rest/RestTestHelper.java
new file mode 100644
index 0000000000..0db1f7e50d
--- /dev/null
+++ b/java/systests/src/main/java/org/apache/qpid/systest/rest/RestTestHelper.java
@@ -0,0 +1,452 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.qpid.systest.rest;
+
+import static org.apache.qpid.test.utils.TestSSLConstants.TRUSTSTORE;
+import static org.apache.qpid.test.utils.TestSSLConstants.TRUSTSTORE_PASSWORD;
+
+import java.io.BufferedWriter;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.HttpURLConnection;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.net.URLDecoder;
+import java.security.GeneralSecurityException;
+import java.security.KeyStore;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+
+import javax.net.ssl.HttpsURLConnection;
+import javax.net.ssl.SSLContext;
+import javax.net.ssl.SSLSocketFactory;
+import javax.net.ssl.TrustManagerFactory;
+import javax.servlet.http.HttpServletResponse;
+
+import junit.framework.Assert;
+
+import org.apache.commons.codec.binary.Base64;
+import org.apache.commons.configuration.ConfigurationException;
+import org.apache.log4j.Logger;
+import org.apache.qpid.server.security.auth.manager.AbstractPrincipalDatabaseAuthManagerFactory;
+import org.apache.qpid.ssl.SSLContextFactory;
+import org.apache.qpid.test.utils.QpidBrokerTestCase;
+import org.apache.qpid.test.utils.TestBrokerConfiguration;
+import org.codehaus.jackson.JsonGenerationException;
+import org.codehaus.jackson.JsonParseException;
+import org.codehaus.jackson.map.JsonMappingException;
+import org.codehaus.jackson.map.ObjectMapper;
+import org.codehaus.jackson.type.TypeReference;
+
+public class RestTestHelper
+{
+    private static final Logger LOGGER = Logger.getLogger(RestTestHelper.class);
+
+    private int _httpPort;
+
+    private boolean _useSsl;
+
+    private String _username;
+
+    private String _password;
+
+    private File _passwdFile;
+
+    public RestTestHelper(int httpPort)
+    {
+        _httpPort = httpPort;
+    }
+
+    public int getHttpPort()
+    {
+        return _httpPort;
+    }
+
+    private String getHostName()
+    {
+        return "localhost";
+    }
+
+    private String getProtocol()
+    {
+        return _useSsl ? "https" : "http";
+    }
+
+    public String getManagementURL()
+    {
+        return getProtocol() + "://" + getHostName() + ":" + getHttpPort();
+    }
+
+    public URL getManagementURL(String path) throws MalformedURLException
+    {
+        return new URL(getManagementURL() + path);
+    }
+
+    public HttpURLConnection openManagementConnection(String path, String method) throws IOException
+    {
+        URL url = getManagementURL(path);
+        HttpURLConnection httpCon = (HttpURLConnection) url.openConnection();
+        if(_useSsl)
+        {
+            try
+            {
+                // We have to use a SSLSocketFactory from a new SSLContext so that we don't re-use
+                // the JVM's defaults that may have been initialised in previous tests.
+
+                SSLContext sslContext = SSLContextFactory.buildClientContext(
+                        TRUSTSTORE, TRUSTSTORE_PASSWORD,
+                        KeyStore.getDefaultType(),
+                        TrustManagerFactory.getDefaultAlgorithm(),
+                        null, null, null, null, null);
+
+                SSLSocketFactory sslSocketFactory = sslContext.getSocketFactory();
+
+                ((HttpsURLConnection) httpCon).setSSLSocketFactory(sslSocketFactory);
+            }
+            catch (GeneralSecurityException e)
+            {
+                throw new RuntimeException(e);
+            }
+        }
+
+        if(_username != null)
+        {
+            String encoded = new String(new Base64().encode((_username + ":" + _password).getBytes()));
+            httpCon.setRequestProperty("Authorization", "Basic " + encoded);
+        }
+
+        httpCon.setDoOutput(true);
+        httpCon.setRequestMethod(method);
+        return httpCon;
+    }
+
+    public List> readJsonResponseAsList(HttpURLConnection connection) throws IOException,
+            JsonParseException, JsonMappingException
+    {
+        byte[] data = readConnectionInputStream(connection);
+
+        ObjectMapper mapper = new ObjectMapper();
+
+        TypeReference>> typeReference = new TypeReference>>()
+        {
+        };
+        List> providedObject = mapper.readValue(new ByteArrayInputStream(data), typeReference);
+        return providedObject;
+    }
+
+    public Map readJsonResponseAsMap(HttpURLConnection connection) throws IOException,
+            JsonParseException, JsonMappingException
+    {
+        byte[] data = readConnectionInputStream(connection);
+
+        ObjectMapper mapper = new ObjectMapper();
+
+        TypeReference> typeReference = new TypeReference>()
+        {
+        };
+        Map providedObject = mapper.readValue(new ByteArrayInputStream(data), typeReference);
+        return providedObject;
+    }
+
+    public byte[] readConnectionInputStream(HttpURLConnection connection) throws IOException
+    {
+        InputStream is = connection.getInputStream();
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        byte[] buffer = new byte[1024];
+        int len = -1;
+        while ((len = is.read(buffer)) != -1)
+        {
+            baos.write(buffer, 0, len);
+        }
+        if (LOGGER.isTraceEnabled())
+        {
+            LOGGER.trace("RESPONSE:" + new String(baos.toByteArray()));
+        }
+        return baos.toByteArray();
+    }
+
+    public void writeJsonRequest(HttpURLConnection connection, Map data) throws JsonGenerationException,
+            JsonMappingException, IOException
+    {
+        ObjectMapper mapper = new ObjectMapper();
+        mapper.writeValue(connection.getOutputStream(), data);
+    }
+
+    public Map find(String name, Object value, List> data)
+    {
+        for (Map map : data)
+        {
+            Object mapValue = map.get(name);
+            if (value.equals(mapValue))
+            {
+                return map;
+            }
+        }
+        return null;
+    }
+
+    public Map find(Map searchAttributes, List> data)
+    {
+        for (Map map : data)
+        {
+            boolean equals = true;
+            for (Map.Entry entry : searchAttributes.entrySet())
+            {
+                Object mapValue = map.get(entry.getKey());
+                if (!entry.getValue().equals(mapValue))
+                {
+                    equals = false;
+                    break;
+                }
+            }
+            if (equals)
+            {
+                return map;
+            }
+        }
+        return null;
+    }
+
+    public Map getJsonAsSingletonList(String path) throws IOException
+    {
+        List> response = getJsonAsList(path);
+
+        Assert.assertNotNull("Response cannot be null", response);
+        Assert.assertEquals("Unexpected response", 1, response.size());
+        return response.get(0);
+    }
+
+    public List> getJsonAsList(String path) throws IOException, JsonParseException,
+            JsonMappingException
+    {
+        HttpURLConnection connection = openManagementConnection(path, "GET");
+        connection.connect();
+        List> response = readJsonResponseAsList(connection);
+        return response;
+    }
+
+    public Map getJsonAsMap(String path) throws IOException
+    {
+        HttpURLConnection connection = openManagementConnection(path, "GET");
+        connection.connect();
+        Map response = readJsonResponseAsMap(connection);
+        return response;
+    }
+
+    public void createNewGroupMember(String groupProviderName, String groupName, String memberName, int responseCode) throws IOException
+    {
+        HttpURLConnection connection = openManagementConnection(
+                "/rest/groupmember/" + URLDecoder.decode(groupProviderName, "UTF-8") + "/"+ URLDecoder.decode(groupName, "UTF-8") + "/" +  URLDecoder.decode(memberName, "UTF-8"),
+                "PUT");
+
+        Map groupMemberData = new HashMap();
+        // TODO add type
+        writeJsonRequest(connection, groupMemberData);
+
+        Assert.assertEquals("Unexpected response code", responseCode, connection.getResponseCode());
+
+        connection.disconnect();
+    }
+
+    public void createNewGroupMember(String groupProviderName, String groupName, String memberName) throws IOException
+    {
+        createNewGroupMember(groupProviderName, groupName, memberName, HttpServletResponse.SC_CREATED);
+    }
+
+    public void removeMemberFromGroup(String groupProviderName, String groupName, String memberName, int responseCode) throws IOException
+    {
+        HttpURLConnection connection = openManagementConnection(
+                "/rest/groupmember/" + URLDecoder.decode(groupProviderName, "UTF-8") + "/"+ URLDecoder.decode(groupName, "UTF-8") + "/" +  URLDecoder.decode(memberName, "UTF-8"),
+                "DELETE");
+
+        Assert.assertEquals("Unexpected response code", responseCode, connection.getResponseCode());
+
+        connection.disconnect();
+    }
+
+    public void removeMemberFromGroup(String groupProviderName, String groupName, String memberName) throws IOException
+    {
+        removeMemberFromGroup(groupProviderName, groupName, memberName, HttpServletResponse.SC_OK);
+    }
+
+    public void assertNumberOfGroupMembers(Map data, int expectedNumberOfGroupMembers)
+    {
+        @SuppressWarnings("unchecked")
+        List> groups = (List>) data.get("groupmembers");
+        if (groups == null)
+        {
+            groups = Collections.emptyList();
+        }
+
+        Assert.assertEquals("Unexpected number of group members", expectedNumberOfGroupMembers, groups.size());
+    }
+
+    public void createGroup(String groupName, String groupProviderName) throws IOException
+    {
+        createGroup(groupName, groupProviderName, HttpServletResponse.SC_CREATED);
+    }
+
+    public void createGroup(String groupName, String groupProviderName, int responseCode) throws IOException
+    {
+        HttpURLConnection connection = openManagementConnection(
+                "/rest/group/" + URLDecoder.decode(groupProviderName, "UTF-8") + "/"+ URLDecoder.decode(groupName, "UTF-8"),
+                "PUT");
+
+        Map groupData = new HashMap();
+        writeJsonRequest(connection, groupData);
+
+        Assert.assertEquals("Unexpected response code", responseCode, connection.getResponseCode());
+
+        connection.disconnect();
+    }
+
+    public void createOrUpdateUser(String username, String password) throws IOException
+    {
+        createOrUpdateUser(username, password, HttpServletResponse.SC_CREATED);
+    }
+
+    public void createOrUpdateUser(String username, String password, int responseCode) throws IOException
+    {
+        HttpURLConnection connection = openManagementConnection("/rest/user/"
+                + TestBrokerConfiguration.ENTRY_NAME_AUTHENTICATION_PROVIDER + "/" + username, "PUT");
+
+        Map data = new HashMap();
+        data.put("password", password);
+        writeJsonRequest(connection, data);
+
+        Assert.assertEquals("Unexpected response code", responseCode, connection.getResponseCode());
+
+        connection.disconnect();
+    }
+
+    public void removeGroup(String groupName, String groupProviderName, int responseCode) throws IOException
+    {
+        HttpURLConnection connection = openManagementConnection(
+                "/rest/group/" + URLDecoder.decode(groupProviderName, "UTF-8") + "/"+ URLDecoder.decode(groupName, "UTF-8"),
+                "DELETE");
+
+        Assert.assertEquals("Unexpected response code", responseCode, connection.getResponseCode());
+        connection.disconnect();
+    }
+
+    public void removeGroup(String groupName, String groupProviderName) throws IOException
+    {
+        removeGroup(groupName, groupProviderName, HttpServletResponse.SC_OK);
+    }
+
+    public void removeUserById(String id) throws IOException
+    {
+        HttpURLConnection connection = openManagementConnection("/rest/user/"
+                + TestBrokerConfiguration.ENTRY_NAME_AUTHENTICATION_PROVIDER + "?id=" + id, "DELETE");
+        Assert.assertEquals("Unexpected response code", HttpServletResponse.SC_OK, connection.getResponseCode());
+        connection.disconnect();
+    }
+
+    public void removeUser(String username, int responseCode) throws IOException
+    {
+        HttpURLConnection connection = openManagementConnection("/rest/user/"
+                + TestBrokerConfiguration.ENTRY_NAME_AUTHENTICATION_PROVIDER + "/" + username, "DELETE");
+        Assert.assertEquals("Unexpected response code", responseCode, connection.getResponseCode());
+        connection.disconnect();
+    }
+
+    public void removeUser(String username) throws IOException
+    {
+        removeUser(username, HttpServletResponse.SC_OK);
+    }
+
+    public void assertNumberOfGroups(Map data, int expectedNumberOfGroups)
+    {
+        @SuppressWarnings("unchecked")
+        List> groups = (List>) data.get("groups");
+        if (groups == null)
+        {
+            groups = Collections.emptyList();
+        }
+        Assert.assertEquals("Unexpected number of groups", expectedNumberOfGroups, groups.size());
+    }
+
+    public void setUseSsl(boolean useSsl)
+    {
+        _useSsl = useSsl;
+    }
+
+    public void setUsernameAndPassword(String username, String password)
+    {
+        _username = username;
+        _password = password;
+    }
+
+    /**
+     * Create password file that follows the convention username=password, which is deleted by {@link #tearDown()}
+     */
+    public void configureTemporaryPasswordFile(QpidBrokerTestCase testCase, String... users) throws ConfigurationException, IOException
+    {
+        _passwdFile = createTemporaryPasswdFile(users);
+
+        testCase.getBrokerConfiguration().setObjectAttribute(TestBrokerConfiguration.ENTRY_NAME_AUTHENTICATION_PROVIDER,
+                AbstractPrincipalDatabaseAuthManagerFactory.ATTRIBUTE_PATH, _passwdFile.getAbsolutePath());
+    }
+
+    public void tearDown()
+    {
+        if (_passwdFile != null)
+        {
+            if (_passwdFile.exists())
+            {
+                _passwdFile.delete();
+            }
+        }
+    }
+
+    private File createTemporaryPasswdFile(String[] users) throws IOException
+    {
+        BufferedWriter writer = null;
+        try
+        {
+            File testFile = File.createTempFile(this.getClass().getName(),"tmp");
+            testFile.deleteOnExit();
+
+            writer = new BufferedWriter(new FileWriter(testFile));
+            for (int i = 0; i < users.length; i++)
+            {
+                String username = users[i];
+                writer.write(username + ":" + username);
+                writer.newLine();
+            }
+
+            return testFile;
+
+        }
+        finally
+        {
+            if (writer != null)
+            {
+                writer.close();
+            }
+        }
+    }
+}
diff --git a/java/systests/src/main/java/org/apache/qpid/systest/rest/SaslRestTest.java b/java/systests/src/main/java/org/apache/qpid/systest/rest/SaslRestTest.java
new file mode 100644
index 0000000000..856fda9419
--- /dev/null
+++ b/java/systests/src/main/java/org/apache/qpid/systest/rest/SaslRestTest.java
@@ -0,0 +1,435 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.qpid.systest.rest;
+
+import java.io.File;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.net.HttpURLConnection;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import javax.crypto.Mac;
+import javax.crypto.spec.SecretKeySpec;
+
+import org.apache.commons.codec.binary.Base64;
+import org.apache.commons.configuration.ConfigurationException;
+import org.apache.qpid.server.plugin.AuthenticationManagerFactory;
+import org.apache.qpid.server.security.auth.manager.AbstractPrincipalDatabaseAuthManagerFactory;
+import org.apache.qpid.server.security.auth.manager.Base64MD5PasswordFileAuthenticationManagerFactory;
+import org.apache.qpid.test.utils.TestBrokerConfiguration;
+import org.apache.qpid.tools.security.Passwd;
+import org.codehaus.jackson.JsonParseException;
+import org.codehaus.jackson.map.JsonMappingException;
+
+public class SaslRestTest extends QpidRestTestCase
+{
+    @Override
+    public void startBroker()
+    {
+        // prevent broker from starting in setUp
+    }
+
+    public void startBrokerNow() throws Exception
+    {
+        super.startBroker();
+    }
+
+    public void testGetMechanismsWithBrokerPlainPasswordPrincipalDatabase() throws Exception
+    {
+        startBrokerNow();
+
+        Map saslData = getRestTestHelper().getJsonAsMap("/rest/sasl");
+        assertNotNull("mechanisms attribute is not found", saslData.get("mechanisms"));
+
+        @SuppressWarnings("unchecked")
+        List mechanisms = (List) saslData.get("mechanisms");
+        String[] expectedMechanisms = { "AMQPLAIN", "PLAIN", "CRAM-MD5" };
+        for (String mechanism : expectedMechanisms)
+        {
+            assertTrue("Mechanism " + mechanism + " is not found", mechanisms.contains(mechanism));
+        }
+        assertNull("Unexpected user was returned", saslData.get("user"));
+    }
+
+    public void testGetMechanismsWithBrokerBase64MD5FilePrincipalDatabase() throws Exception
+    {
+        configureBase64MD5FilePrincipalDatabase();
+        startBrokerNow();
+
+        Map saslData = getRestTestHelper().getJsonAsMap("/rest/sasl");
+        assertNotNull("mechanisms attribute is not found", saslData.get("mechanisms"));
+
+        @SuppressWarnings("unchecked")
+        List mechanisms = (List) saslData.get("mechanisms");
+        String[] expectedMechanisms = { "CRAM-MD5-HEX", "CRAM-MD5-HASHED" };
+        for (String mechanism : expectedMechanisms)
+        {
+            assertTrue("Mechanism " + mechanism + " is not found", mechanisms.contains(mechanism));
+        }
+        assertNull("Unexpected user was returned", saslData.get("user"));
+    }
+
+    public void testPlainSaslAuthenticationForValidCredentials() throws Exception
+    {
+        startBrokerNow();
+
+        byte[] responseBytes = generatePlainClientResponse("admin", "admin");
+        String responseData = Base64.encodeBase64String(responseBytes);
+        String parameters= "mechanism=PLAIN&response=" + responseData;
+
+        HttpURLConnection connection = getRestTestHelper().openManagementConnection("/rest/sasl", "POST");
+        OutputStream os = connection.getOutputStream();
+        os.write(parameters.getBytes());
+        os.flush();
+
+         int code = connection.getResponseCode();
+        assertEquals("Unexpected response code", 200, code);
+
+        List cookies = connection.getHeaderFields().get("Set-Cookie");
+
+        // request authenticated user details
+        connection = getRestTestHelper().openManagementConnection("/rest/sasl", "GET");
+        applyCookiesToConnection(cookies, connection);
+        Map response2 = getRestTestHelper().readJsonResponseAsMap(connection);
+        assertEquals("Unexpected user", "admin", response2.get("user"));
+    }
+
+    public void testPlainSaslAuthenticationForIncorrectPassword() throws Exception
+    {
+        startBrokerNow();
+
+        byte[] responseBytes = generatePlainClientResponse("admin", "incorrect");
+        String responseData = Base64.encodeBase64String(responseBytes);
+        String parameters= "mechanism=PLAIN&response=" + responseData;
+
+        HttpURLConnection connection = getRestTestHelper().openManagementConnection("/rest/sasl", "POST");
+        OutputStream os = connection.getOutputStream();
+        os.write(parameters.getBytes());
+        os.flush();
+
+        int code = connection.getResponseCode();
+        assertEquals("Unexpected response code", 403, code);
+
+        List cookies = connection.getHeaderFields().get("Set-Cookie");
+
+        // request authenticated user details
+        connection = getRestTestHelper().openManagementConnection("/rest/sasl", "GET");
+        applyCookiesToConnection(cookies, connection);
+        Map response2 = getRestTestHelper().readJsonResponseAsMap(connection);
+        assertNull("Unexpected user", response2.get("user"));
+    }
+
+    public void testPlainSaslAuthenticationForNonExistingUser() throws Exception
+    {
+        startBrokerNow();
+
+        byte[] responseBytes = generatePlainClientResponse("nonexisting", "admin");
+        String responseData = Base64.encodeBase64String(responseBytes);
+        String parameters= "mechanism=PLAIN&response=" + responseData;
+
+        HttpURLConnection connection = getRestTestHelper().openManagementConnection("/rest/sasl", "POST");
+        OutputStream os = connection.getOutputStream();
+        os.write(parameters.getBytes());
+        os.flush();
+
+        int code = connection.getResponseCode();
+        assertEquals("Unexpected response code", 403, code);
+
+        List cookies = connection.getHeaderFields().get("Set-Cookie");
+
+        // request authenticated user details
+        connection = getRestTestHelper().openManagementConnection("/rest/sasl", "GET");
+        applyCookiesToConnection(cookies, connection);
+        Map response2 = getRestTestHelper().readJsonResponseAsMap(connection);
+        assertNull("Unexpected user", response2.get("user"));
+    }
+
+    public void testCramMD5SaslAuthenticationForValidCredentials() throws Exception
+    {
+        startBrokerNow();
+
+        // request the challenge for CRAM-MD5
+        HttpURLConnection connection = requestSasServerChallenge("CRAM-MD5");
+        List cookies = connection.getHeaderFields().get("Set-Cookie");
+
+        // authenticate user with correct credentials
+        int code = authenticateUser(connection, "admin", "admin", "CRAM-MD5");
+        assertEquals("Unexpected response code", 200, code);
+
+        // request authenticated user details
+        connection = getRestTestHelper().openManagementConnection("/rest/sasl", "GET");
+        applyCookiesToConnection(cookies, connection);
+        Map response2 = getRestTestHelper().readJsonResponseAsMap(connection);
+        assertEquals("Unexpected user", "admin", response2.get("user"));
+    }
+
+    public void testCramMD5SaslAuthenticationForIncorrectPassword() throws Exception
+    {
+        startBrokerNow();
+
+        // request the challenge for CRAM-MD5
+        HttpURLConnection connection = requestSasServerChallenge("CRAM-MD5");
+        List cookies = connection.getHeaderFields().get("Set-Cookie");
+
+        // authenticate user with correct credentials
+        int code = authenticateUser(connection, "admin", "incorrect", "CRAM-MD5");
+        assertEquals("Unexpected response code", 403, code);
+
+        // request authenticated user details
+        connection = getRestTestHelper().openManagementConnection("/rest/sasl", "GET");
+        applyCookiesToConnection(cookies, connection);
+        Map response2 = getRestTestHelper().readJsonResponseAsMap(connection);
+        assertNull("Unexpected user", response2.get("user"));
+    }
+
+    public void testCramMD5SaslAuthenticationForNonExistingUser() throws Exception
+    {
+        startBrokerNow();
+
+        // request the challenge for CRAM-MD5
+        HttpURLConnection connection = requestSasServerChallenge("CRAM-MD5");
+        List cookies = connection.getHeaderFields().get("Set-Cookie");
+
+        // authenticate user with correct credentials
+        int code = authenticateUser(connection, "nonexisting", "admin", "CRAM-MD5");
+        assertEquals("Unexpected response code", 403, code);
+
+        // request authenticated user details
+        connection = getRestTestHelper().openManagementConnection("/rest/sasl", "GET");
+        applyCookiesToConnection(cookies, connection);
+        Map response2 = getRestTestHelper().readJsonResponseAsMap(connection);
+        assertNull("Unexpected user",  response2.get("user"));
+    }
+
+    public void testCramMD5HexSaslAuthenticationForValidCredentials() throws Exception
+    {
+        configureBase64MD5FilePrincipalDatabase();
+        startBrokerNow();
+
+        // request the challenge for CRAM-MD5-HEX
+        HttpURLConnection connection = requestSasServerChallenge("CRAM-MD5-HEX");
+        List cookies = connection.getHeaderFields().get("Set-Cookie");
+
+        // authenticate user with correct credentials
+        int code = authenticateUser(connection, "admin", "admin", "CRAM-MD5-HEX");
+        assertEquals("Unexpected response code", 200, code);
+
+        // request authenticated user details
+        connection = getRestTestHelper().openManagementConnection("/rest/sasl", "GET");
+        applyCookiesToConnection(cookies, connection);
+        Map response2 = getRestTestHelper().readJsonResponseAsMap(connection);
+        assertEquals("Unexpected user", "admin", response2.get("user"));
+    }
+
+    public void testCramMD5HexSaslAuthenticationForIncorrectPassword() throws Exception
+    {
+        configureBase64MD5FilePrincipalDatabase();
+        startBrokerNow();
+
+        HttpURLConnection connection = requestSasServerChallenge("CRAM-MD5-HEX");
+        List cookies = connection.getHeaderFields().get("Set-Cookie");
+
+        // try to authenticate user with incorrect passowrd
+        int code = authenticateUser(connection, "admin", "incorrect", "CRAM-MD5-HEX");
+        assertEquals("Unexpected response code", 403, code);
+
+        // request authenticated user details
+        connection = getRestTestHelper().openManagementConnection("/rest/sasl", "GET");
+        applyCookiesToConnection(cookies, connection);
+        Map response2 = getRestTestHelper().readJsonResponseAsMap(connection);
+        assertNull("Unexpected user", response2.get("user"));
+    }
+
+    public void testCramMD5HexSaslAuthenticationForNonExistingUser() throws Exception
+    {
+        configureBase64MD5FilePrincipalDatabase();
+        startBrokerNow();
+
+        HttpURLConnection connection = requestSasServerChallenge("CRAM-MD5-HEX");
+        List cookies = connection.getHeaderFields().get("Set-Cookie");
+
+        // try to authenticate non-existing user
+        int code = authenticateUser(connection, "nonexisting", "admin", "CRAM-MD5-HEX");
+        assertEquals("Unexpected response code", 403, code);
+
+        // request authenticated user details
+        connection = getRestTestHelper().openManagementConnection("/rest/sasl", "GET");
+        applyCookiesToConnection(cookies, connection);
+        Map response2 = getRestTestHelper().readJsonResponseAsMap(connection);
+        assertNull("Unexpected user", response2.get("user"));
+    }
+
+    private HttpURLConnection requestSasServerChallenge(String mechanism) throws IOException
+    {
+        HttpURLConnection connection = getRestTestHelper().openManagementConnection("/rest/sasl", "POST");
+        OutputStream os = connection.getOutputStream();
+        os.write(("mechanism=" + mechanism).getBytes());
+        os.flush();
+        return connection;
+    }
+
+    private int authenticateUser(HttpURLConnection requestChallengeConnection, String userName, String userPassword, String mechanism)
+            throws IOException, JsonParseException, JsonMappingException, Exception
+    {
+        // get the response
+        Map response = getRestTestHelper().readJsonResponseAsMap(requestChallengeConnection);
+        String challenge = (String) response.get("challenge");
+        assertNotNull("Challenge is not found", challenge);
+
+        // preserve cookies to have the same server session
+        List cookies = requestChallengeConnection.getHeaderFields().get("Set-Cookie");
+
+        // generate the authentication response for the challenge received
+        byte[] challengeBytes = Base64.decodeBase64(challenge);
+        byte[] responseBytes = generateClientResponse(mechanism, userName, userPassword, challengeBytes);
+        String responseData = Base64.encodeBase64String(responseBytes);
+        String requestParameters = ("id=" + response.get("id") + "&response=" + responseData);
+
+        // re-open connection
+        HttpURLConnection authenticateConnection = getRestTestHelper().openManagementConnection("/rest/sasl", "POST");
+
+        // set cookies to use the same server session
+        applyCookiesToConnection(cookies, authenticateConnection);
+        OutputStream os = authenticateConnection.getOutputStream();
+        os.write(requestParameters.getBytes());
+        os.flush();
+        return authenticateConnection.getResponseCode();
+    }
+
+    private byte[] generateClientResponse(String mechanism, String userName, String userPassword, byte[] challengeBytes) throws Exception
+    {
+        byte[] responseBytes =  null;
+        if ("CRAM-MD5-HEX".equalsIgnoreCase(mechanism))
+        {
+            responseBytes = generateCramMD5HexClientResponse(userName, userPassword, challengeBytes);
+        }
+        else if ("CRAM-MD5".equalsIgnoreCase(mechanism))
+        {
+            responseBytes = generateCramMD5ClientResponse(userName, userPassword, challengeBytes);
+        }
+        else
+        {
+            throw new RuntimeException("Not implemented test mechanism " + mechanism);
+        }
+        return responseBytes;
+    }
+
+    private void applyCookiesToConnection(List cookies, HttpURLConnection connection)
+    {
+        for (String cookie : cookies)
+        {
+            connection.addRequestProperty("Cookie", cookie.split(";", 2)[0]);
+        }
+    }
+
+    private static byte SEPARATOR = 0;
+
+    private byte[] generatePlainClientResponse(String userName, String userPassword) throws Exception
+    {
+        byte[] password = userPassword.getBytes("UTF8");
+        byte user[] = userName.getBytes("UTF8");
+        byte response[] = new byte[password.length + user.length + 2 ];
+        int size = 0;
+        response[size++] = SEPARATOR;
+        System.arraycopy(user, 0, response, size, user.length);
+        size += user.length;
+        response[size++] = SEPARATOR;
+        System.arraycopy(password, 0, response, size, password.length);
+        return response;
+    }
+
+    private byte[] generateCramMD5HexClientResponse(String userName, String userPassword, byte[] challengeBytes) throws Exception
+    {
+        String macAlgorithm = "HmacMD5";
+        byte[] digestedPasswordBytes = MessageDigest.getInstance("MD5").digest(userPassword.getBytes("UTF-8"));
+        byte[] hexEncodedDigestedPasswordBytes = toHex(digestedPasswordBytes).getBytes("UTF-8");
+        Mac mac = Mac.getInstance(macAlgorithm);
+        mac.init(new SecretKeySpec(hexEncodedDigestedPasswordBytes, macAlgorithm));
+        final byte[] messageAuthenticationCode = mac.doFinal(challengeBytes);
+        String responseAsString = userName + " " + toHex(messageAuthenticationCode);
+        return responseAsString.getBytes();
+    }
+
+    private byte[] generateCramMD5ClientResponse(String userName, String userPassword, byte[] challengeBytes) throws Exception
+    {
+        String macAlgorithm = "HmacMD5";
+        Mac mac = Mac.getInstance(macAlgorithm);
+        mac.init(new SecretKeySpec(userPassword.getBytes("UTF-8"), macAlgorithm));
+        final byte[] messageAuthenticationCode = mac.doFinal(challengeBytes);
+        String responseAsString = userName + " " + toHex(messageAuthenticationCode);
+        return responseAsString.getBytes();
+    }
+
+    private String toHex(byte[] data)
+    {
+        StringBuffer hash = new StringBuffer();
+        for (int i = 0; i < data.length; i++)
+        {
+            String hex = Integer.toHexString(0xFF & data[i]);
+            if (hex.length() == 1)
+            {
+                hash.append('0');
+            }
+            hash.append(hex);
+        }
+        return hash.toString();
+    }
+
+    private void configureBase64MD5FilePrincipalDatabase() throws IOException, ConfigurationException
+    {
+        // generate user password entry
+        String passwordFileEntry;
+        try
+        {
+            passwordFileEntry = new Passwd().getOutput("admin", "admin");
+        }
+        catch (NoSuchAlgorithmException e)
+        {
+            throw new ConfigurationException(e);
+        }
+
+        // store the entry in the file
+        File passwordFile = File.createTempFile("passwd", "pwd");
+        passwordFile.deleteOnExit();
+
+        FileWriter writer = null;
+        try
+        {
+            writer = new FileWriter(passwordFile);
+            writer.write(passwordFileEntry);
+        }
+        finally
+        {
+            writer.close();
+        }
+
+        // configure broker to use Base64MD5PasswordFilePrincipalDatabase
+        Map newAttributes = new HashMap();
+        newAttributes.put(AbstractPrincipalDatabaseAuthManagerFactory.ATTRIBUTE_PATH, passwordFile.getAbsolutePath());
+        newAttributes.put(AuthenticationManagerFactory.ATTRIBUTE_TYPE, Base64MD5PasswordFileAuthenticationManagerFactory.PROVIDER_TYPE);
+        getBrokerConfiguration().setObjectAttributes(TestBrokerConfiguration.ENTRY_NAME_AUTHENTICATION_PROVIDER, newAttributes);
+    }
+}
diff --git a/java/systests/src/main/java/org/apache/qpid/systest/rest/StructureRestTest.java b/java/systests/src/main/java/org/apache/qpid/systest/rest/StructureRestTest.java
new file mode 100644
index 0000000000..427934fac2
--- /dev/null
+++ b/java/systests/src/main/java/org/apache/qpid/systest/rest/StructureRestTest.java
@@ -0,0 +1,114 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.qpid.systest.rest;
+
+import java.util.List;
+import java.util.Map;
+
+import org.apache.qpid.server.model.Port;
+import org.apache.qpid.test.utils.TestBrokerConfiguration;
+
+public class StructureRestTest extends QpidRestTestCase
+{
+
+    public void testGet() throws Exception
+    {
+        Map structure = getRestTestHelper().getJsonAsMap("/rest/structure");
+        assertNotNull("Structure data cannot be null", structure);
+        assertNode(structure, "QpidBroker");
+
+        @SuppressWarnings("unchecked")
+        List> virtualhosts = (List>) structure.get("virtualhosts");
+        assertEquals("Unexpected number of virtual hosts", 3, virtualhosts.size());
+
+        @SuppressWarnings("unchecked")
+        List> ports = (List>) structure.get("ports");
+        assertEquals("Unexpected number of ports", 4, ports.size());
+
+        @SuppressWarnings("unchecked")
+        List> providers = (List>) structure.get("authenticationproviders");
+        assertEquals("Unexpected number of authentication providers", 1, providers.size());
+
+        for (String hostName : EXPECTED_VIRTUALHOSTS)
+        {
+            Map host = getRestTestHelper().find("name", hostName, virtualhosts);
+            assertNotNull("Host " + hostName + " is not found ", host);
+            assertNode(host, hostName);
+
+            @SuppressWarnings("unchecked")
+            List> queues = (List>) host.get("queues");
+            assertNotNull("Host " + hostName + " queues are not found ", queues);
+            for (String queueName : EXPECTED_QUEUES)
+            {
+                Map queue = getRestTestHelper().find("name", queueName, queues);
+                assertNotNull(hostName + " queue " + queueName + " is not found ", queue);
+                assertNode(queue, queueName);
+
+                @SuppressWarnings("unchecked")
+                List> bindings = (List>) queue.get("bindings");
+                assertNotNull(hostName + " queue " + queueName + " bindings are not found ", queues);
+                for (Map binding : bindings)
+                {
+                    assertNode(binding, queueName);
+                }
+            }
+
+            @SuppressWarnings("unchecked")
+            List> exchanges = (List>) host.get("exchanges");
+            assertNotNull("Host " + hostName + " exchanges are not found ", exchanges);
+            for (String exchangeName : EXPECTED_EXCHANGES)
+            {
+                Map exchange = getRestTestHelper().find("name", exchangeName, exchanges);
+                assertNotNull("Exchange " + exchangeName + " is not found ", exchange);
+                assertNode(exchange, exchangeName);
+                if ("amq.direct".equalsIgnoreCase(exchangeName) || "<>".equalsIgnoreCase(exchangeName))
+                {
+                    @SuppressWarnings("unchecked")
+                    List> bindings = (List>) exchange.get("bindings");
+                    assertNotNull(hostName + " exchange " + exchangeName + " bindings are not found ", bindings);
+                    for (String queueName : EXPECTED_QUEUES)
+                    {
+                        Map binding = getRestTestHelper().find("name", queueName, bindings);
+                        assertNotNull(hostName + " exchange " + exchangeName + " binding  " + queueName + " is not found", binding);
+                        assertNode(binding, queueName);
+                    }
+                }
+            }
+        }
+
+
+        String httpPortName = TestBrokerConfiguration.ENTRY_NAME_HTTP_PORT;
+        Map portData = getRestTestHelper().find(Port.NAME, httpPortName, ports);
+        assertNotNull("Http Port " + httpPortName + " is not found", portData);
+        assertNode(portData, httpPortName);
+
+        String amqpPortName = TestBrokerConfiguration.ENTRY_NAME_AMQP_PORT;
+        Map amqpPortData = getRestTestHelper().find(Port.NAME, amqpPortName, ports);
+        assertNotNull("Amqp port " + amqpPortName + " is not found", amqpPortData);
+        assertNode(amqpPortData, amqpPortName);
+    }
+
+    private void assertNode(Map node, String name)
+    {
+        assertEquals("Unexpected name", name, node.get("name"));
+        assertNotNull("Unexpected id", node.get("id"));
+    }
+}
diff --git a/java/systests/src/main/java/org/apache/qpid/systest/rest/UserRestTest.java b/java/systests/src/main/java/org/apache/qpid/systest/rest/UserRestTest.java
new file mode 100644
index 0000000000..017467a8be
--- /dev/null
+++ b/java/systests/src/main/java/org/apache/qpid/systest/rest/UserRestTest.java
@@ -0,0 +1,99 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.qpid.systest.rest;
+
+import java.util.List;
+import java.util.Map;
+
+import org.apache.qpid.server.model.User;
+import org.apache.qpid.test.utils.TestBrokerConfiguration;
+
+public class UserRestTest extends QpidRestTestCase
+{
+    @Override
+    public void setUp() throws Exception
+    {
+        getRestTestHelper().configureTemporaryPasswordFile(this, "user1", "user2");
+
+        super.setUp(); // do this last because it starts the broker, using the modified config
+    }
+
+    public void testGet() throws Exception
+    {
+        List> users = getRestTestHelper().getJsonAsList("/rest/user");
+        assertNotNull("Users cannot be null", users);
+        assertTrue("Unexpected number of users", users.size() > 1);
+        for (Map user : users)
+        {
+            assertUser(user);
+        }
+    }
+
+    public void testGetUserByName() throws Exception
+    {
+        List> users = getRestTestHelper().getJsonAsList("/rest/user");
+        assertNotNull("Users cannot be null", users);
+        assertTrue("Unexpected number of users", users.size() > 1);
+        for (Map user : users)
+        {
+            assertNotNull("Attribute " + User.ID, user.get(User.ID));
+            String userName = (String) user.get(User.NAME);
+            assertNotNull("Attribute " + User.NAME, userName);
+            Map userDetails = getRestTestHelper().getJsonAsSingletonList("/rest/user/"
+                    + TestBrokerConfiguration.ENTRY_NAME_AUTHENTICATION_PROVIDER + "/" + userName);
+            assertUser(userDetails);
+            assertEquals("Unexpected user name", userName, userDetails.get(User.NAME));
+        }
+    }
+
+    public void testPut() throws Exception
+    {
+        String userName = getTestName();
+        getRestTestHelper().createOrUpdateUser(userName, "newPassword");
+
+        Map userDetails = getRestTestHelper().getJsonAsSingletonList("/rest/user/"
+                + TestBrokerConfiguration.ENTRY_NAME_AUTHENTICATION_PROVIDER + "/" + userName);
+        assertUser(userDetails);
+        assertEquals("Unexpected user name", userName, userDetails.get(User.NAME));
+    }
+
+    public void testDelete() throws Exception
+    {
+        String userName = getTestName();
+        getRestTestHelper().createOrUpdateUser(userName, "newPassword");
+
+        Map userDetails = getRestTestHelper().getJsonAsSingletonList("/rest/user/"
+                + TestBrokerConfiguration.ENTRY_NAME_AUTHENTICATION_PROVIDER + "/" + userName);
+        String id = (String) userDetails.get(User.ID);
+
+        getRestTestHelper().removeUserById(id);
+
+        List> users = getRestTestHelper().getJsonAsList("/rest/user/"
+                + TestBrokerConfiguration.ENTRY_NAME_AUTHENTICATION_PROVIDER + "/" + userName);
+        assertEquals("User should be deleted", 0, users.size());
+    }
+
+    private void assertUser(Map user)
+    {
+        assertNotNull("Attribute " + User.ID, user.get(User.ID));
+        assertNotNull("Attribute " + User.NAME, user.get(User.NAME));
+    }
+}
diff --git a/java/systests/src/main/java/org/apache/qpid/systest/rest/VirtualHostRestTest.java b/java/systests/src/main/java/org/apache/qpid/systest/rest/VirtualHostRestTest.java
new file mode 100644
index 0000000000..fb2c941203
--- /dev/null
+++ b/java/systests/src/main/java/org/apache/qpid/systest/rest/VirtualHostRestTest.java
@@ -0,0 +1,576 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.qpid.systest.rest;
+
+import java.io.File;
+import java.io.IOException;
+import java.net.HttpURLConnection;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import javax.jms.Session;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.commons.configuration.ConfigurationException;
+import org.apache.commons.configuration.XMLConfiguration;
+import org.apache.qpid.client.AMQConnection;
+import org.apache.qpid.server.model.Exchange;
+import org.apache.qpid.server.model.Queue;
+import org.apache.qpid.server.model.VirtualHost;
+import org.apache.qpid.server.queue.AMQQueueFactory;
+import org.apache.qpid.test.utils.TestFileUtils;
+import org.apache.qpid.util.FileUtils;
+import org.codehaus.jackson.JsonGenerationException;
+import org.codehaus.jackson.map.JsonMappingException;
+
+public class VirtualHostRestTest extends QpidRestTestCase
+{
+    private static final String VIRTUALHOST_EXCHANGES_ATTRIBUTE = "exchanges";
+    public static final String VIRTUALHOST_QUEUES_ATTRIBUTE = "queues";
+    public static final String VIRTUALHOST_CONNECTIONS_ATTRIBUTE = "connections";
+
+    private AMQConnection _connection;
+
+    public void testGet() throws Exception
+    {
+        List> hosts = getRestTestHelper().getJsonAsList("/rest/virtualhost/");
+        assertNotNull("Hosts data cannot be null", hosts);
+        assertEquals("Unexpected number of hosts", EXPECTED_VIRTUALHOSTS.length, hosts.size());
+        for (String hostName : EXPECTED_VIRTUALHOSTS)
+        {
+            Map host = getRestTestHelper().find("name", hostName, hosts);
+            Asserts.assertVirtualHost(hostName, host);
+        }
+    }
+
+    public void testGetHost() throws Exception
+    {
+        // create AMQP connection to get connection JSON details
+        _connection = (AMQConnection) getConnection();
+        _connection.createSession(true, Session.SESSION_TRANSACTED);
+
+        Map hostDetails = getRestTestHelper().getJsonAsSingletonList("/rest/virtualhost/test");
+        Asserts.assertVirtualHost("test", hostDetails);
+
+        @SuppressWarnings("unchecked")
+        Map statistics = (Map) hostDetails.get(Asserts.STATISTICS_ATTRIBUTE);
+        assertEquals("Unexpected number of exchanges in statistics", EXPECTED_EXCHANGES.length, statistics.get(VirtualHost.EXCHANGE_COUNT));
+        assertEquals("Unexpected number of queues in statistics", EXPECTED_QUEUES.length, statistics.get(VirtualHost.QUEUE_COUNT));
+        assertEquals("Unexpected number of connections in statistics", 1, statistics.get(VirtualHost.CONNECTION_COUNT));
+
+        @SuppressWarnings("unchecked")
+        List> exchanges = (List>) hostDetails.get(VIRTUALHOST_EXCHANGES_ATTRIBUTE);
+        assertEquals("Unexpected number of exchanges", EXPECTED_EXCHANGES.length, exchanges.size());
+        Asserts.assertDurableExchange("amq.fanout", "fanout", getRestTestHelper().find(Exchange.NAME, "amq.fanout", exchanges));
+        Asserts.assertDurableExchange("amq.topic", "topic", getRestTestHelper().find(Exchange.NAME, "amq.topic", exchanges));
+        Asserts.assertDurableExchange("amq.direct", "direct", getRestTestHelper().find(Exchange.NAME, "amq.direct", exchanges));
+        Asserts.assertDurableExchange("amq.match", "headers", getRestTestHelper().find(Exchange.NAME, "amq.match", exchanges));
+        Asserts.assertDurableExchange("<>", "direct", getRestTestHelper().find(Exchange.NAME, "<>", exchanges));
+
+        @SuppressWarnings("unchecked")
+        List> queues = (List>) hostDetails.get(VIRTUALHOST_QUEUES_ATTRIBUTE);
+        assertEquals("Unexpected number of queues", EXPECTED_QUEUES.length, queues.size());
+        Map queue = getRestTestHelper().find(Queue.NAME,  "queue", queues);
+        Map ping = getRestTestHelper().find(Queue.NAME, "ping", queues);
+        Asserts.assertQueue("queue", "standard", queue);
+        Asserts.assertQueue("ping", "standard", ping);
+        assertEquals("Unexpected value of queue attribute " + Queue.DURABLE, Boolean.FALSE, queue.get(Queue.DURABLE));
+        assertEquals("Unexpected value of queue attribute " + Queue.DURABLE, Boolean.FALSE, ping.get(Queue.DURABLE));
+
+        @SuppressWarnings("unchecked")
+        List> connections = (List>) hostDetails
+                .get(VIRTUALHOST_CONNECTIONS_ATTRIBUTE);
+        assertEquals("Unexpected number of connections", 1, connections.size());
+        Asserts.assertConnection(connections.get(0), _connection);
+    }
+
+    public void testPutCreateVirtualHostUsingStoreType() throws Exception
+    {
+        String hostName = getTestName();
+        String storeType = getTestProfileMessageStoreType();
+        String storeLocation = createHost(hostName, storeType, null);
+        try
+        {
+            // make sure that the host is saved in the broker store
+            restartBroker();
+            Map hostDetails = getRestTestHelper().getJsonAsSingletonList("/rest/virtualhost/" + hostName);
+            Asserts.assertVirtualHost(hostName, hostDetails);
+            assertEquals("Unexpected store type", storeType, hostDetails.get(VirtualHost.STORE_TYPE));
+
+            assertNewVirtualHost(hostDetails);
+        }
+        finally
+        {
+            if (storeLocation != null)
+            {
+                FileUtils.delete(new File(storeLocation), true);
+            }
+        }
+    }
+
+    public void testPutCreateVirtualHostUsingConfigPath() throws Exception
+    {
+        String hostName = getTestName();
+        File configFile = TestFileUtils.createTempFile(this, hostName + "-config.xml");
+        String configPath = configFile.getAbsolutePath();
+        String storeLocation = getStoreLocation(hostName);
+        createAndSaveVirtualHostConfiguration(hostName, configFile, storeLocation);
+        createHost(hostName, null, configPath);
+        try
+        {
+            // make sure that the host is saved in the broker store
+            restartBroker();
+            Map hostDetails = getRestTestHelper().getJsonAsSingletonList("/rest/virtualhost/" + hostName);
+            Asserts.assertVirtualHost(hostName, hostDetails);
+            assertEquals("Unexpected config path", configPath, hostDetails.get(VirtualHost.CONFIG_PATH));
+
+            assertNewVirtualHost(hostDetails);
+        }
+        finally
+        {
+            if (storeLocation != null)
+            {
+                FileUtils.delete(new File(storeLocation), true);
+            }
+            configFile.delete();
+        }
+    }
+
+    public void testDeleteHost() throws Exception
+    {
+        String hostToDelete = TEST3_VIRTUALHOST;
+        HttpURLConnection connection = getRestTestHelper().openManagementConnection("/rest/virtualhost/" + hostToDelete, "DELETE");
+        connection.connect();
+        assertEquals("Unexpected response code", 200, connection.getResponseCode());
+
+        // make sure that changes are saved in the broker store
+        restartBroker();
+
+        List> hosts = getRestTestHelper().getJsonAsList("/rest/virtualhost/" + hostToDelete);
+        assertEquals("Host should be deleted", 0, hosts.size());
+    }
+
+    public void testPutCreateQueue() throws Exception
+    {
+        String queueName = getTestQueueName();
+
+        createQueue(queueName + "-standard", "standard", null);
+
+        Map sortedQueueAttributes = new HashMap();
+        sortedQueueAttributes.put(Queue.SORT_KEY, "sortme");
+        createQueue(queueName + "-sorted", "sorted", sortedQueueAttributes);
+
+        Map priorityQueueAttributes = new HashMap();
+        priorityQueueAttributes.put(Queue.PRIORITIES, 10);
+        createQueue(queueName + "-priority", "priority", priorityQueueAttributes);
+
+        Map lvqQueueAttributes = new HashMap();
+        lvqQueueAttributes.put(Queue.LVQ_KEY, "LVQ");
+        createQueue(queueName + "-lvq", "lvq", lvqQueueAttributes);
+
+        Map hostDetails = getRestTestHelper().getJsonAsSingletonList("/rest/virtualhost/test");
+
+        @SuppressWarnings("unchecked")
+        List> queues = (List>) hostDetails.get(VirtualHostRestTest.VIRTUALHOST_QUEUES_ATTRIBUTE);
+        Map standardQueue = getRestTestHelper().find(Queue.NAME, queueName + "-standard" , queues);
+        Map sortedQueue = getRestTestHelper().find(Queue.NAME, queueName + "-sorted" , queues);
+        Map priorityQueue = getRestTestHelper().find(Queue.NAME, queueName + "-priority" , queues);
+        Map lvqQueue = getRestTestHelper().find(Queue.NAME, queueName + "-lvq" , queues);
+
+        Asserts.assertQueue(queueName + "-standard", "standard", standardQueue);
+        Asserts.assertQueue(queueName + "-sorted", "sorted", sortedQueue);
+        Asserts.assertQueue(queueName + "-priority", "priority", priorityQueue);
+        Asserts.assertQueue(queueName + "-lvq", "lvq", lvqQueue);
+
+        assertEquals("Unexpected value of queue attribute " + Queue.DURABLE, Boolean.TRUE, standardQueue.get(Queue.DURABLE));
+        assertEquals("Unexpected value of queue attribute " + Queue.DURABLE, Boolean.TRUE, sortedQueue.get(Queue.DURABLE));
+        assertEquals("Unexpected value of queue attribute " + Queue.DURABLE, Boolean.TRUE, priorityQueue.get(Queue.DURABLE));
+        assertEquals("Unexpected value of queue attribute " + Queue.DURABLE, Boolean.TRUE, lvqQueue.get(Queue.DURABLE));
+
+        assertEquals("Unexpected sorted key attribute", "sortme", sortedQueue.get(Queue.SORT_KEY));
+        assertEquals("Unexpected lvq key attribute", "LVQ", lvqQueue.get(Queue.LVQ_KEY));
+        assertEquals("Unexpected priorities key attribute", 10, priorityQueue.get(Queue.PRIORITIES));
+    }
+
+    public void testPutCreateExchange() throws Exception
+    {
+        String exchangeName = getTestName();
+
+        createExchange(exchangeName + "-direct", "direct");
+        createExchange(exchangeName + "-topic", "topic");
+        createExchange(exchangeName + "-headers", "headers");
+        createExchange(exchangeName + "-fanout", "fanout");
+
+        Map hostDetails = getRestTestHelper().getJsonAsSingletonList("/rest/virtualhost/test");
+
+        @SuppressWarnings("unchecked")
+        List> exchanges = (List>) hostDetails.get(VirtualHostRestTest.VIRTUALHOST_EXCHANGES_ATTRIBUTE);
+        Map directExchange = getRestTestHelper().find(Queue.NAME, exchangeName + "-direct" , exchanges);
+        Map topicExchange = getRestTestHelper().find(Queue.NAME, exchangeName + "-topic" , exchanges);
+        Map headersExchange = getRestTestHelper().find(Queue.NAME, exchangeName + "-headers" , exchanges);
+        Map fanoutExchange = getRestTestHelper().find(Queue.NAME, exchangeName + "-fanout" , exchanges);
+
+        Asserts.assertDurableExchange(exchangeName + "-direct", "direct", directExchange);
+        Asserts.assertDurableExchange(exchangeName + "-topic", "topic", topicExchange);
+        Asserts.assertDurableExchange(exchangeName + "-headers", "headers", headersExchange);
+        Asserts.assertDurableExchange(exchangeName + "-fanout", "fanout", fanoutExchange);
+
+        assertEquals("Unexpected value of queue attribute " + Queue.DURABLE, Boolean.TRUE, directExchange.get(Queue.DURABLE));
+        assertEquals("Unexpected value of queue attribute " + Queue.DURABLE, Boolean.TRUE, topicExchange.get(Queue.DURABLE));
+        assertEquals("Unexpected value of queue attribute " + Queue.DURABLE, Boolean.TRUE, headersExchange.get(Queue.DURABLE));
+        assertEquals("Unexpected value of queue attribute " + Queue.DURABLE, Boolean.TRUE, fanoutExchange.get(Queue.DURABLE));
+
+    }
+
+    public void testPutCreateLVQWithoutKey() throws Exception
+    {
+        String queueName = getTestQueueName()+ "-lvq";
+        createQueue(queueName, "lvq", null);
+
+        Map hostDetails = getRestTestHelper().getJsonAsSingletonList("/rest/virtualhost/test");
+
+        @SuppressWarnings("unchecked")
+        List> queues = (List>) hostDetails.get(VirtualHostRestTest.VIRTUALHOST_QUEUES_ATTRIBUTE);
+        Map lvqQueue = getRestTestHelper().find(Queue.NAME, queueName  , queues);
+
+        Asserts.assertQueue(queueName , "lvq", lvqQueue);
+        assertEquals("Unexpected value of queue attribute " + Queue.DURABLE, Boolean.TRUE, lvqQueue.get(Queue.DURABLE));
+        assertEquals("Unexpected lvq key attribute", AMQQueueFactory.QPID_LVQ_KEY, lvqQueue.get(Queue.LVQ_KEY));
+    }
+
+    public void testPutCreateSortedQueueWithoutKey() throws Exception
+    {
+        String queueName = getTestQueueName() + "-sorted";
+        int responseCode = tryCreateQueue(queueName, "sorted", null);
+        assertEquals("Unexpected response code", HttpServletResponse.SC_CONFLICT, responseCode);
+
+        Map hostDetails = getRestTestHelper().getJsonAsSingletonList("/rest/virtualhost/test");
+
+        @SuppressWarnings("unchecked")
+        List> queues = (List>) hostDetails.get(VirtualHostRestTest.VIRTUALHOST_QUEUES_ATTRIBUTE);
+        Map testQueue = getRestTestHelper().find(Queue.NAME, queueName  , queues);
+
+        assertNull("Sorted queue without a key was created ", testQueue);
+    }
+
+    public void testPutCreatePriorityQueueWithoutKey() throws Exception
+    {
+        String queueName = getTestQueueName()+ "-priority";
+        createQueue(queueName, "priority", null);
+
+        Map hostDetails = getRestTestHelper().getJsonAsSingletonList("/rest/virtualhost/test");
+
+        @SuppressWarnings("unchecked")
+        List> queues = (List>) hostDetails.get(VirtualHostRestTest.VIRTUALHOST_QUEUES_ATTRIBUTE);
+        Map priorityQueue = getRestTestHelper().find(Queue.NAME, queueName  , queues);
+
+        Asserts.assertQueue(queueName , "priority", priorityQueue);
+        assertEquals("Unexpected value of queue attribute " + Queue.DURABLE, Boolean.TRUE, priorityQueue.get(Queue.DURABLE));
+        assertEquals("Unexpected number of priorities", 10, priorityQueue.get(Queue.PRIORITIES));
+    }
+
+    public void testPutCreateStandardQueueWithoutType() throws Exception
+    {
+        String queueName = getTestQueueName();
+        createQueue(queueName, null, null);
+
+        Map hostDetails = getRestTestHelper().getJsonAsSingletonList("/rest/virtualhost/test");
+
+        @SuppressWarnings("unchecked")
+        List> queues = (List>) hostDetails.get(VirtualHostRestTest.VIRTUALHOST_QUEUES_ATTRIBUTE);
+        Map queue = getRestTestHelper().find(Queue.NAME, queueName  , queues);
+
+        Asserts.assertQueue(queueName , "standard", queue);
+    }
+
+    public void testPutCreateQueueOfUnsupportedType() throws Exception
+    {
+        String queueName = getTestQueueName();
+        int responseCode = tryCreateQueue(queueName, "unsupported", null);
+        assertEquals("Unexpected response code", HttpServletResponse.SC_CONFLICT, responseCode);
+
+        Map hostDetails = getRestTestHelper().getJsonAsSingletonList("/rest/virtualhost/test");
+
+        @SuppressWarnings("unchecked")
+        List> queues = (List>) hostDetails.get(VirtualHostRestTest.VIRTUALHOST_QUEUES_ATTRIBUTE);
+        Map queue = getRestTestHelper().find(Queue.NAME, queueName  , queues);
+
+        assertNull("Queue of unsupported type was created", queue);
+    }
+
+    public void testDeleteQueue() throws Exception
+    {
+        String queueName = getTestQueueName();
+        createQueue(queueName, null, null);
+
+        HttpURLConnection connection = getRestTestHelper().openManagementConnection("/rest/queue/test/" + queueName, "DELETE");
+        connection.connect();
+        assertEquals("Unexpected response code", 200, connection.getResponseCode());
+        List> queues = getRestTestHelper().getJsonAsList("/rest/queue/test/" + queueName);
+        assertEquals("Queue should be deleted", 0, queues.size());
+    }
+
+    public void testDeleteQueueById() throws Exception
+    {
+        String queueName = getTestQueueName();
+        createQueue(queueName, null, null);
+        Map queueDetails = getRestTestHelper().getJsonAsSingletonList("/rest/queue/test/" + queueName);
+
+        HttpURLConnection connection = getRestTestHelper().openManagementConnection("/rest/queue/test?id=" + queueDetails.get(Queue.ID), "DELETE");
+        connection.connect();
+        assertEquals("Unexpected response code", 200, connection.getResponseCode());
+        List> queues = getRestTestHelper().getJsonAsList("/rest/queue/test/" + queueName);
+        assertEquals("Queue should be deleted", 0, queues.size());
+    }
+
+    public void testDeleteExchange() throws Exception
+    {
+        String exchangeName = getTestName();
+        createExchange(exchangeName, "direct");
+
+        HttpURLConnection connection = getRestTestHelper().openManagementConnection("/rest/exchange/test/" + exchangeName, "DELETE");
+        connection.connect();
+        assertEquals("Unexpected response code", 200, connection.getResponseCode());
+        List> queues = getRestTestHelper().getJsonAsList("/rest/exchange/test/" + exchangeName);
+        assertEquals("Exchange should be deleted", 0, queues.size());
+    }
+
+    public void testDeleteExchangeById() throws Exception
+    {
+        String exchangeName = getTestName();
+        createExchange(exchangeName, "direct");
+        Map echangeDetails = getRestTestHelper().getJsonAsSingletonList("/rest/exchange/test/" + exchangeName);
+
+        HttpURLConnection connection = getRestTestHelper().openManagementConnection("/rest/exchange/test?id=" + echangeDetails.get(Exchange.ID), "DELETE");
+        connection.connect();
+        assertEquals("Unexpected response code", 200, connection.getResponseCode());
+        List> queues = getRestTestHelper().getJsonAsList("/rest/exchange/test/" + exchangeName);
+        assertEquals("Exchange should be deleted", 0, queues.size());
+    }
+
+    public void testPutCreateQueueWithAttributes() throws Exception
+    {
+        String queueName = getTestQueueName();
+
+        Map attributes = new HashMap();
+        attributes.put(Queue.ALERT_REPEAT_GAP, 1000);
+        attributes.put(Queue.ALERT_THRESHOLD_MESSAGE_AGE, 3600000);
+        attributes.put(Queue.ALERT_THRESHOLD_MESSAGE_SIZE, 1000000000);
+        attributes.put(Queue.ALERT_THRESHOLD_QUEUE_DEPTH_MESSAGES, 800);
+        attributes.put(Queue.MAXIMUM_DELIVERY_ATTEMPTS, 15);
+        attributes.put(Queue.QUEUE_FLOW_CONTROL_SIZE_BYTES, 2000000000);
+        attributes.put(Queue.QUEUE_FLOW_RESUME_SIZE_BYTES, 1500000000);
+
+        createQueue(queueName + "-standard", "standard", attributes);
+
+        Map sortedQueueAttributes = new HashMap();
+        sortedQueueAttributes.putAll(attributes);
+        sortedQueueAttributes.put(Queue.SORT_KEY, "sortme");
+        createQueue(queueName + "-sorted", "sorted", sortedQueueAttributes);
+
+        Map priorityQueueAttributes = new HashMap();
+        priorityQueueAttributes.putAll(attributes);
+        priorityQueueAttributes.put(Queue.PRIORITIES, 10);
+        createQueue(queueName + "-priority", "priority", priorityQueueAttributes);
+
+        Map lvqQueueAttributes = new HashMap();
+        lvqQueueAttributes.putAll(attributes);
+        lvqQueueAttributes.put(Queue.LVQ_KEY, "LVQ");
+        createQueue(queueName + "-lvq", "lvq", lvqQueueAttributes);
+
+        Map hostDetails = getRestTestHelper().getJsonAsSingletonList("/rest/virtualhost/test");
+
+        @SuppressWarnings("unchecked")
+        List> queues = (List>) hostDetails.get(VirtualHostRestTest.VIRTUALHOST_QUEUES_ATTRIBUTE);
+        Map standardQueue = getRestTestHelper().find(Queue.NAME, queueName + "-standard" , queues);
+        Map sortedQueue = getRestTestHelper().find(Queue.NAME, queueName + "-sorted" , queues);
+        Map priorityQueue = getRestTestHelper().find(Queue.NAME, queueName + "-priority" , queues);
+        Map lvqQueue = getRestTestHelper().find(Queue.NAME, queueName + "-lvq" , queues);
+
+        attributes.put(Queue.DURABLE, Boolean.TRUE);
+        Asserts.assertQueue(queueName + "-standard", "standard", standardQueue, attributes);
+        Asserts.assertQueue(queueName + "-sorted", "sorted", sortedQueue, attributes);
+        Asserts.assertQueue(queueName + "-priority", "priority", priorityQueue, attributes);
+        Asserts.assertQueue(queueName + "-lvq", "lvq", lvqQueue, attributes);
+
+        assertEquals("Unexpected sorted key attribute", "sortme", sortedQueue.get(Queue.SORT_KEY));
+        assertEquals("Unexpected lvq key attribute", "LVQ", lvqQueue.get(Queue.LVQ_KEY));
+        assertEquals("Unexpected priorities key attribute", 10, priorityQueue.get(Queue.PRIORITIES));
+    }
+
+    @SuppressWarnings("unchecked")
+    public void testCreateQueueWithDLQEnabled() throws Exception
+    {
+        String queueName = getTestQueueName();
+
+        Map attributes = new HashMap();
+        attributes.put(AMQQueueFactory.X_QPID_DLQ_ENABLED, true);
+
+        //verify the starting state
+        Map hostDetails = getRestTestHelper().getJsonAsSingletonList("/rest/virtualhost/test");
+        List> queues = (List>) hostDetails.get(VirtualHostRestTest.VIRTUALHOST_QUEUES_ATTRIBUTE);
+        List> exchanges = (List>) hostDetails.get(VirtualHostRestTest.VIRTUALHOST_EXCHANGES_ATTRIBUTE);
+
+        assertNull("queue should not have already been present", getRestTestHelper().find(Queue.NAME, queueName , queues));
+        assertNull("queue should not have already been present", getRestTestHelper().find(Queue.NAME, queueName + "_DLQ" , queues));
+        assertNull("exchange should not have already been present", getRestTestHelper().find(Exchange.NAME, queueName + "_DLE" , exchanges));
+
+        //create the queue
+        createQueue(queueName, "standard", attributes);
+
+        //verify the new queue, as well as the DLQueue and DLExchange have been created
+        hostDetails = getRestTestHelper().getJsonAsSingletonList("/rest/virtualhost/test");
+        queues = (List>) hostDetails.get(VirtualHostRestTest.VIRTUALHOST_QUEUES_ATTRIBUTE);
+        exchanges = (List>) hostDetails.get(VirtualHostRestTest.VIRTUALHOST_EXCHANGES_ATTRIBUTE);
+
+        Map queue = getRestTestHelper().find(Queue.NAME, queueName , queues);
+        Map dlqQueue = getRestTestHelper().find(Queue.NAME, queueName + "_DLQ" , queues);
+        Map dlExchange = getRestTestHelper().find(Exchange.NAME, queueName + "_DLE" , exchanges);
+        assertNotNull("queue should not have been present", queue);
+        assertNotNull("queue should not have been present", dlqQueue);
+        assertNotNull("exchange should not have been present", dlExchange);
+
+        //verify that the alternate exchange is set as expected on the new queue
+        Map queueAttributes = new HashMap();
+        queueAttributes.put(Queue.ALTERNATE_EXCHANGE, queueName + "_DLE");
+
+        Asserts.assertQueue(queueName, "standard", queue, queueAttributes);
+        Asserts.assertQueue(queueName, "standard", queue, null);
+    }
+
+    private void createExchange(String exchangeName, String exchangeType) throws IOException
+    {
+        HttpURLConnection connection = getRestTestHelper().openManagementConnection("/rest/exchange/test/" + exchangeName, "PUT");
+
+        Map queueData = new HashMap();
+        queueData.put(Exchange.NAME, exchangeName);
+        queueData.put(Exchange.DURABLE, Boolean.TRUE);
+        queueData.put(Exchange.TYPE, exchangeType);
+
+        getRestTestHelper().writeJsonRequest(connection, queueData);
+        assertEquals("Unexpected response code", 201, connection.getResponseCode());
+
+        connection.disconnect();
+    }
+
+    private void createQueue(String queueName, String queueType, Map attributes) throws IOException,
+            JsonGenerationException, JsonMappingException
+    {
+        int responseCode = tryCreateQueue(queueName, queueType, attributes);
+        assertEquals("Unexpected response code", 201, responseCode);
+    }
+
+    private int tryCreateQueue(String queueName, String queueType, Map attributes) throws IOException,
+            JsonGenerationException, JsonMappingException
+    {
+        HttpURLConnection connection = getRestTestHelper().openManagementConnection("/rest/queue/test/" + queueName, "PUT");
+
+        Map queueData = new HashMap();
+        queueData.put(Queue.NAME, queueName);
+        queueData.put(Queue.DURABLE, Boolean.TRUE);
+        if (queueType != null)
+        {
+            queueData.put(Queue.TYPE, queueType);
+        }
+        if (attributes != null)
+        {
+            queueData.putAll(attributes);
+        }
+
+        getRestTestHelper().writeJsonRequest(connection, queueData);
+        int responseCode = connection.getResponseCode();
+        connection.disconnect();
+        return responseCode;
+    }
+
+    private String createHost(String hostName, String storeType, String configPath) throws IOException, JsonGenerationException,
+            JsonMappingException
+    {
+        String storePath = getStoreLocation(hostName);
+        int responseCode = tryCreateVirtualHost(hostName, storeType, storePath, configPath);
+        assertEquals("Unexpected response code", 201, responseCode);
+        return storePath;
+    }
+
+    private String getStoreLocation(String hostName)
+    {
+        return new File(TMP_FOLDER, "store-" + hostName + "-" + System.currentTimeMillis()).getAbsolutePath();
+    }
+
+    private int tryCreateVirtualHost(String hostName, String storeType, String storePath, String configPath) throws IOException,
+            JsonGenerationException, JsonMappingException
+    {
+        HttpURLConnection connection = getRestTestHelper().openManagementConnection("/rest/virtualhost/" + hostName, "PUT");
+
+        Map hostData = new HashMap();
+        hostData.put(VirtualHost.NAME, hostName);
+        if (storeType == null)
+        {
+            hostData.put(VirtualHost.CONFIG_PATH, configPath);
+        }
+        else
+        {
+            hostData.put(VirtualHost.STORE_PATH, storePath);
+            hostData.put(VirtualHost.STORE_TYPE, storeType);
+        }
+
+        getRestTestHelper().writeJsonRequest(connection, hostData);
+        int responseCode = connection.getResponseCode();
+        connection.disconnect();
+        return responseCode;
+    }
+
+    private XMLConfiguration createAndSaveVirtualHostConfiguration(String hostName, File configFile, String storeLocation)
+            throws ConfigurationException
+    {
+        XMLConfiguration testConfiguration = new XMLConfiguration();
+        testConfiguration.setProperty("virtualhosts.virtualhost." + hostName + ".store.class",
+                getTestProfileMessageStoreClassName());
+        testConfiguration.setProperty("virtualhosts.virtualhost." + hostName + ".store.environment-path", storeLocation);
+        testConfiguration.save(configFile);
+        return testConfiguration;
+    }
+
+    private void assertNewVirtualHost(Map hostDetails)
+    {
+        @SuppressWarnings("unchecked")
+        Map statistics = (Map) hostDetails.get(Asserts.STATISTICS_ATTRIBUTE);
+        assertEquals("Unexpected number of exchanges in statistics", EXPECTED_EXCHANGES.length,
+                statistics.get(VirtualHost.EXCHANGE_COUNT));
+        assertEquals("Unexpected number of queues in statistics", 0, statistics.get(VirtualHost.QUEUE_COUNT));
+        assertEquals("Unexpected number of connections in statistics", 0, statistics.get(VirtualHost.CONNECTION_COUNT));
+
+        @SuppressWarnings("unchecked")
+        List> exchanges = (List>) hostDetails.get(VIRTUALHOST_EXCHANGES_ATTRIBUTE);
+        assertEquals("Unexpected number of exchanges", EXPECTED_EXCHANGES.length, exchanges.size());
+        RestTestHelper restTestHelper = getRestTestHelper();
+        Asserts.assertDurableExchange("amq.fanout", "fanout", restTestHelper.find(Exchange.NAME, "amq.fanout", exchanges));
+        Asserts.assertDurableExchange("amq.topic", "topic", restTestHelper.find(Exchange.NAME, "amq.topic", exchanges));
+        Asserts.assertDurableExchange("amq.direct", "direct", restTestHelper.find(Exchange.NAME, "amq.direct", exchanges));
+        Asserts.assertDurableExchange("amq.match", "headers", restTestHelper.find(Exchange.NAME, "amq.match", exchanges));
+        Asserts.assertDurableExchange("<>", "direct", restTestHelper.find(Exchange.NAME, "<>", exchanges));
+
+        assertNull("Unexpected queues", hostDetails.get(VIRTUALHOST_QUEUES_ATTRIBUTE));
+        assertNull("Unexpected connections", hostDetails.get(VIRTUALHOST_CONNECTIONS_ATTRIBUTE));
+    }
+
+}
diff --git a/java/systests/src/main/java/org/apache/qpid/systest/rest/acl/GroupRestACLTest.java b/java/systests/src/main/java/org/apache/qpid/systest/rest/acl/GroupRestACLTest.java
new file mode 100644
index 0000000000..40ea723b1e
--- /dev/null
+++ b/java/systests/src/main/java/org/apache/qpid/systest/rest/acl/GroupRestACLTest.java
@@ -0,0 +1,197 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.qpid.systest.rest.acl;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.util.Map;
+import java.util.Properties;
+
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.commons.configuration.ConfigurationException;
+import org.apache.qpid.server.model.Broker;
+import org.apache.qpid.server.security.acl.AbstractACLTestCase;
+import org.apache.qpid.systest.rest.QpidRestTestCase;
+import org.apache.qpid.test.utils.TestBrokerConfiguration;
+
+public class GroupRestACLTest extends QpidRestTestCase
+{
+    private static final String FILE_GROUP_MANAGER = "FileGroupManager";
+
+    private static final String ALLOWED_GROUP = "allowedGroup";
+    private static final String DENIED_GROUP = "deniedGroup";
+    private static final String OTHER_GROUP = "otherGroup";
+
+    private static final String ALLOWED_USER = "webadmin";
+    private static final String DENIED_USER = "admin";
+    private static final String OTHER_USER = "admin";
+
+    private File _groupFile;
+
+    @Override
+    public void setUp() throws Exception
+    {
+        _groupFile = createTemporaryGroupFile();
+        getBrokerConfiguration().setBrokerAttribute(Broker.GROUP_FILE, _groupFile.getAbsolutePath());
+
+        //DONT call super.setUp(), the tests will start the broker after configuring it
+    }
+
+    @Override
+    protected void customizeConfiguration() throws ConfigurationException, IOException
+    {
+        super.customizeConfiguration();
+        getBrokerConfiguration().setObjectAttribute(TestBrokerConfiguration.ENTRY_NAME_HTTP_MANAGEMENT, "httpBasicAuthenticationEnabled", true);
+    }
+
+    @Override
+    public void tearDown() throws Exception
+    {
+        super.tearDown();
+
+        if (_groupFile != null)
+        {
+            if (_groupFile.exists())
+            {
+                _groupFile.delete();
+            }
+        }
+    }
+
+    private File createTemporaryGroupFile() throws Exception
+    {
+        File groupFile = File.createTempFile("group", "grp");
+        groupFile.deleteOnExit();
+
+        Properties props = new Properties();
+        props.put(ALLOWED_GROUP + ".users", ALLOWED_USER);
+        props.put(DENIED_GROUP + ".users", DENIED_USER);
+        props.put(OTHER_GROUP + ".users", OTHER_USER);
+
+        props.store(new FileOutputStream(groupFile), "test group file");
+
+        return groupFile;
+    }
+
+    public void testCreateGroup() throws Exception
+    {
+        AbstractACLTestCase.writeACLFileUtil(this, null,
+                "ACL ALLOW-LOG ALL ACCESS MANAGEMENT",
+                "ACL ALLOW-LOG " + ALLOWED_GROUP + " CREATE GROUP",
+                "ACL DENY-LOG " + DENIED_GROUP + " CREATE GROUP");
+
+        //Start the broker with the custom config
+        super.setUp();
+        getRestTestHelper().setUsernameAndPassword(ALLOWED_USER, ALLOWED_USER);
+
+        Map data = getRestTestHelper().getJsonAsSingletonList("/rest/groupprovider/" + FILE_GROUP_MANAGER);
+        getRestTestHelper().assertNumberOfGroups(data, 3);
+
+        getRestTestHelper().createGroup("newGroup", FILE_GROUP_MANAGER);
+
+        data = getRestTestHelper().getJsonAsSingletonList("/rest/groupprovider/" + FILE_GROUP_MANAGER);
+        getRestTestHelper().assertNumberOfGroups(data, 4);
+
+        getRestTestHelper().setUsernameAndPassword(DENIED_USER, DENIED_USER);
+
+        getRestTestHelper().createGroup("anotherNewGroup", FILE_GROUP_MANAGER, HttpServletResponse.SC_FORBIDDEN);
+
+        data = getRestTestHelper().getJsonAsSingletonList("/rest/groupprovider/" + FILE_GROUP_MANAGER);
+        getRestTestHelper().assertNumberOfGroups(data, 4);
+    }
+
+    public void testDeleteGroup() throws Exception
+    {
+        AbstractACLTestCase.writeACLFileUtil(this, null,
+                "ACL ALLOW-LOG ALL ACCESS MANAGEMENT",
+                "ACL ALLOW-LOG " + ALLOWED_GROUP + " DELETE GROUP",
+                "ACL DENY-LOG " + DENIED_GROUP + " DELETE GROUP");
+
+        //Start the broker with the custom config
+        super.setUp();
+        getRestTestHelper().setUsernameAndPassword(DENIED_USER, DENIED_USER);
+
+        Map data = getRestTestHelper().getJsonAsSingletonList("/rest/groupprovider/" + FILE_GROUP_MANAGER);
+        getRestTestHelper().assertNumberOfGroups(data, 3);
+
+        getRestTestHelper().removeGroup(OTHER_GROUP, FILE_GROUP_MANAGER, HttpServletResponse.SC_FORBIDDEN);
+
+        data = getRestTestHelper().getJsonAsSingletonList("/rest/groupprovider/" + FILE_GROUP_MANAGER);
+        getRestTestHelper().assertNumberOfGroups(data, 3);
+
+        getRestTestHelper().setUsernameAndPassword(ALLOWED_USER, ALLOWED_USER);
+
+        getRestTestHelper().removeGroup(OTHER_GROUP, FILE_GROUP_MANAGER);
+
+        data = getRestTestHelper().getJsonAsSingletonList("/rest/groupprovider/" + FILE_GROUP_MANAGER);
+        getRestTestHelper().assertNumberOfGroups(data, 2);
+    }
+
+    public void testUpdateGroupAddMember() throws Exception
+    {
+        AbstractACLTestCase.writeACLFileUtil(this, null,
+                "ACL ALLOW-LOG ALL ACCESS MANAGEMENT",
+                "ACL ALLOW-LOG " + ALLOWED_GROUP + " UPDATE GROUP",
+                "ACL DENY-LOG " + DENIED_GROUP + " UPDATE GROUP");
+
+        //Start the broker with the custom config
+        super.setUp();
+        getRestTestHelper().setUsernameAndPassword(DENIED_USER, DENIED_USER);
+
+        assertNumberOfGroupMembers(OTHER_GROUP, 1);
+
+        getRestTestHelper().createNewGroupMember(FILE_GROUP_MANAGER, OTHER_GROUP, "newGroupMember", HttpServletResponse.SC_FORBIDDEN);
+        assertNumberOfGroupMembers(OTHER_GROUP, 1);
+
+        getRestTestHelper().setUsernameAndPassword(ALLOWED_USER, ALLOWED_USER);
+        getRestTestHelper().createNewGroupMember(FILE_GROUP_MANAGER, OTHER_GROUP, "newGroupMember");
+        assertNumberOfGroupMembers(OTHER_GROUP, 2);
+    }
+
+    public void testUpdateGroupDeleteMember() throws Exception
+    {
+        AbstractACLTestCase.writeACLFileUtil(this, null,
+                "ACL ALLOW-LOG ALL ACCESS MANAGEMENT",
+                "ACL ALLOW-LOG " + ALLOWED_GROUP + " UPDATE GROUP",
+                "ACL DENY-LOG " + DENIED_GROUP + " UPDATE GROUP");
+
+        //Start the broker with the custom config
+        super.setUp();
+        getRestTestHelper().setUsernameAndPassword(DENIED_USER, DENIED_USER);
+
+        assertNumberOfGroupMembers(OTHER_GROUP, 1);
+
+        getRestTestHelper().removeMemberFromGroup(FILE_GROUP_MANAGER, OTHER_GROUP, OTHER_USER, HttpServletResponse.SC_FORBIDDEN);
+        assertNumberOfGroupMembers(OTHER_GROUP, 1);
+
+        getRestTestHelper().setUsernameAndPassword(ALLOWED_USER, ALLOWED_USER);
+        getRestTestHelper().removeMemberFromGroup(FILE_GROUP_MANAGER, OTHER_GROUP, OTHER_USER);
+        assertNumberOfGroupMembers(OTHER_GROUP, 0);
+    }
+
+    private void assertNumberOfGroupMembers(String groupName, int expectedNumberOfMembers) throws IOException
+    {
+        Map group = getRestTestHelper().getJsonAsSingletonList("/rest/group/FileGroupManager/" + groupName);
+        getRestTestHelper().assertNumberOfGroupMembers(group, expectedNumberOfMembers);
+    }
+}
diff --git a/java/systests/src/main/java/org/apache/qpid/systest/rest/acl/UserRestACLTest.java b/java/systests/src/main/java/org/apache/qpid/systest/rest/acl/UserRestACLTest.java
new file mode 100644
index 0000000000..12973113d8
--- /dev/null
+++ b/java/systests/src/main/java/org/apache/qpid/systest/rest/acl/UserRestACLTest.java
@@ -0,0 +1,200 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.qpid.systest.rest.acl;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.net.HttpURLConnection;
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.commons.configuration.ConfigurationException;
+import org.apache.qpid.server.model.Broker;
+import org.apache.qpid.server.security.acl.AbstractACLTestCase;
+import org.apache.qpid.systest.rest.QpidRestTestCase;
+import org.apache.qpid.test.utils.TestBrokerConfiguration;
+import org.codehaus.jackson.JsonParseException;
+import org.codehaus.jackson.map.JsonMappingException;
+
+public class UserRestACLTest extends QpidRestTestCase
+{
+    private static final String ALLOWED_GROUP = "allowedGroup";
+    private static final String DENIED_GROUP = "deniedGroup";
+    private static final String OTHER_GROUP = "otherGroup";
+
+    private static final String ALLOWED_USER = "webadmin";
+    private static final String DENIED_USER = "admin";
+    private static final String OTHER_USER = "other";
+
+    private File _groupFile;
+
+    @Override
+    public void setUp() throws Exception
+    {
+        _groupFile = createTemporaryGroupFile();
+        getBrokerConfiguration().setBrokerAttribute(Broker.GROUP_FILE, _groupFile.getAbsolutePath());
+
+        getRestTestHelper().configureTemporaryPasswordFile(this, ALLOWED_USER, DENIED_USER, OTHER_USER);
+
+        //DONT call super.setUp(), the tests will start the broker after configuring it
+    }
+
+    @Override
+    protected void customizeConfiguration() throws ConfigurationException, IOException
+    {
+        super.customizeConfiguration();
+        getBrokerConfiguration().setObjectAttribute(TestBrokerConfiguration.ENTRY_NAME_HTTP_MANAGEMENT, "httpBasicAuthenticationEnabled", true);
+    }
+
+    @Override
+    public void tearDown() throws Exception
+    {
+        super.tearDown();
+
+        if (_groupFile != null)
+        {
+            if (_groupFile.exists())
+            {
+                _groupFile.delete();
+            }
+        }
+    }
+
+    private File createTemporaryGroupFile() throws Exception
+    {
+        File groupFile = File.createTempFile("group", "grp");
+        groupFile.deleteOnExit();
+
+        Properties props = new Properties();
+        props.put(ALLOWED_GROUP + ".users", ALLOWED_USER);
+        props.put(DENIED_GROUP + ".users", DENIED_USER);
+        props.put(OTHER_GROUP + ".users", OTHER_USER);
+
+        props.store(new FileOutputStream(groupFile), "test group file");
+
+        return groupFile;
+    }
+
+    public void testAddUser() throws Exception
+    {
+        AbstractACLTestCase.writeACLFileUtil(this, null,
+                "ACL ALLOW-LOG ALL ACCESS MANAGEMENT",
+                "ACL ALLOW-LOG " + ALLOWED_GROUP + " CREATE USER",
+                "ACL DENY-LOG " + DENIED_GROUP + " CREATE USER");
+
+        //Start the broker with the custom config
+        super.setUp();
+
+        String newUser = "newUser";
+        String password = "password";
+
+        assertUserDoesNotExist(newUser);
+
+        getRestTestHelper().setUsernameAndPassword(DENIED_USER, DENIED_USER);
+
+        getRestTestHelper().createOrUpdateUser(newUser, password, HttpServletResponse.SC_FORBIDDEN);
+        assertUserDoesNotExist(newUser);
+
+        getRestTestHelper().setUsernameAndPassword(ALLOWED_USER, ALLOWED_USER);
+        getRestTestHelper().createOrUpdateUser(newUser, password);
+        assertUserExists(newUser);
+    }
+
+    public void testDeleteUser() throws Exception
+    {
+        AbstractACLTestCase.writeACLFileUtil(this, null,
+                "ACL ALLOW-LOG ALL ACCESS MANAGEMENT",
+                "ACL ALLOW-LOG " + ALLOWED_GROUP + " DELETE USER",
+                "ACL DENY-LOG " + DENIED_GROUP + " DELETE USER");
+
+        //Start the broker with the custom config
+        super.setUp();
+
+        assertUserExists(OTHER_USER);
+
+        getRestTestHelper().setUsernameAndPassword(DENIED_USER, DENIED_USER);
+        getRestTestHelper().removeUser(OTHER_USER, HttpServletResponse.SC_FORBIDDEN);
+        assertUserExists(OTHER_USER);
+
+        getRestTestHelper().setUsernameAndPassword(ALLOWED_USER, ALLOWED_USER);
+        getRestTestHelper().removeUser(OTHER_USER);
+        assertUserDoesNotExist(OTHER_USER);
+    }
+
+    public void testUpdateUser() throws Exception
+    {
+        AbstractACLTestCase.writeACLFileUtil(this, null,
+                "ACL ALLOW-LOG ALL ACCESS MANAGEMENT",
+                "ACL ALLOW-LOG " + ALLOWED_GROUP + " UPDATE USER",
+                "ACL DENY-LOG " + DENIED_GROUP + " UPDATE USER");
+
+        //Start the broker with the custom config
+        super.setUp();
+
+        String newPassword = "newPassword";
+
+        checkPassword(OTHER_USER, OTHER_USER, true);
+
+        getRestTestHelper().setUsernameAndPassword(DENIED_USER, DENIED_USER);
+        getRestTestHelper().createOrUpdateUser(OTHER_USER, newPassword, HttpServletResponse.SC_FORBIDDEN);
+
+        checkPassword(OTHER_USER, newPassword, false);
+
+        getRestTestHelper().setUsernameAndPassword(ALLOWED_USER, ALLOWED_USER);
+        getRestTestHelper().createOrUpdateUser(OTHER_USER, newPassword, HttpServletResponse.SC_OK); // expect SC_OK rather than the default SC_CREATED
+
+        checkPassword(OTHER_USER, newPassword, true);
+        checkPassword(OTHER_USER, OTHER_USER, false);
+    }
+
+    private void checkPassword(String username, String password, boolean passwordExpectedToBeCorrect) throws IOException
+    {
+        getRestTestHelper().setUsernameAndPassword(username, password);
+        HttpURLConnection connection = getRestTestHelper().openManagementConnection("/rest/user/"
+                + TestBrokerConfiguration.ENTRY_NAME_AUTHENTICATION_PROVIDER + "/", "GET");
+
+        boolean passwordIsCorrect = connection.getResponseCode() == HttpServletResponse.SC_OK;
+
+        connection.disconnect();
+
+        assertEquals(passwordExpectedToBeCorrect, passwordIsCorrect);
+    }
+
+    private void assertUserDoesNotExist(String newUser) throws JsonParseException, JsonMappingException, IOException
+    {
+        String path = "/rest/user/" + TestBrokerConfiguration.ENTRY_NAME_AUTHENTICATION_PROVIDER + "/" + newUser;
+        List> userDetailsList = getRestTestHelper().getJsonAsList(path);
+        assertTrue(userDetailsList.isEmpty());
+    }
+
+    private void assertUserExists(String username) throws IOException
+    {
+        String path = "/rest/user/" + TestBrokerConfiguration.ENTRY_NAME_AUTHENTICATION_PROVIDER + "/" + username;
+        Map userDetails = getRestTestHelper().getJsonAsSingletonList(path);
+
+        assertEquals(
+                "User returned by " + path + " should have name=" + username + ". The returned JSON was: " + userDetails,
+                username,
+                userDetails.get("name"));
+    }
+}
diff --git a/java/systests/src/main/java/org/apache/qpid/test/client/RollbackOrderTest.java b/java/systests/src/main/java/org/apache/qpid/test/client/RollbackOrderTest.java
index a53c3d3ee0..2ed3f356d3 100644
--- a/java/systests/src/main/java/org/apache/qpid/test/client/RollbackOrderTest.java
+++ b/java/systests/src/main/java/org/apache/qpid/test/client/RollbackOrderTest.java
@@ -40,19 +40,19 @@ import java.util.concurrent.atomic.AtomicBoolean;
  * Description:
  *
  * The problem that this test is exposing is that the dispatcher used to be capable
- * of holding on to a message when stopped. This ment that when the rollback was
+ * of holding on to a message when stopped. This meant that when the rollback was
  * called and the dispatcher stopped it may have hold of a message. So after all
  * the local queues(preDeliveryQueue, SynchronousQueue, PostDeliveryTagQueue)
  * have been cleared the client still had a single message, the one the
  * dispatcher was holding on to.
  *
  * As a result the TxRollback operation would run and then release the dispatcher.
- * Whilst the dispatcher would then proceed to reject the message it was holiding
+ * Whilst the dispatcher would then proceed to reject the message it was holding
  * the Broker would already have resent that message so the rejection would silently
  * fail.
  *
- * And the client would receieve that single message 'early', depending on the
- * number of messages already recevied when rollback was called.
+ * And the client would receive that single message 'early', depending on the
+ * number of messages already received when rollback was called.
  *
  *
  * Aims:
@@ -78,7 +78,7 @@ import java.util.concurrent.atomic.AtomicBoolean;
  * as expected.
  *
  * We are testing a race condition here but we can check through the log file if
- * the race condition occured. However, performing that check will only validate
+ * the race condition occurred. However, performing that check will only validate
  * the problem exists and will not be suitable as part of a system test.
  *
  */
@@ -183,18 +183,8 @@ public class RollbackOrderTest extends QpidBrokerTestCase
             }
         }
 
-//        _consumer.close();
         _connection.close();
         
         assertFalse("Exceptions thrown during test run, Check Std.err.", failed.get());
     }
-
-    @Override public void tearDown() throws Exception
-    {
-
-        drainQueue(_queue);
-
-        super.tearDown();
-    }
-
 }
diff --git a/java/systests/src/main/java/org/apache/qpid/test/client/destination/AddressBasedDestinationTest.java b/java/systests/src/main/java/org/apache/qpid/test/client/destination/AddressBasedDestinationTest.java
index e1f93b975b..22a98b6f42 100644
--- a/java/systests/src/main/java/org/apache/qpid/test/client/destination/AddressBasedDestinationTest.java
+++ b/java/systests/src/main/java/org/apache/qpid/test/client/destination/AddressBasedDestinationTest.java
@@ -29,8 +29,6 @@ import org.apache.qpid.client.AMQDestination;
 import org.apache.qpid.client.AMQSession;
 import org.apache.qpid.client.AMQSession_0_10;
 import org.apache.qpid.client.message.QpidMessageProperties;
-import org.apache.qpid.client.messaging.address.Node.ExchangeNode;
-import org.apache.qpid.client.messaging.address.Node.QueueNode;
 import org.apache.qpid.jndi.PropertiesFileInitialContextFactory;
 import org.apache.qpid.messaging.Address;
 import org.apache.qpid.test.utils.QpidBrokerTestCase;
@@ -98,7 +96,7 @@ public class AddressBasedDestinationTest extends QpidBrokerTestCase
         }
             
         assertFalse("Queue should not be created",(
-                (AMQSession_0_10)jmsSession).isQueueExist(dest, (QueueNode)dest.getSourceNode() ,true));
+                (AMQSession_0_10)jmsSession).isQueueExist(dest,false));
         
         
         // create always -------------------------------------------
@@ -107,10 +105,10 @@ public class AddressBasedDestinationTest extends QpidBrokerTestCase
         cons = jmsSession.createConsumer(dest); 
         
         assertTrue("Queue not created as expected",(
-                (AMQSession_0_10)jmsSession).isQueueExist(dest,(QueueNode)dest.getSourceNode(), true));              
+                (AMQSession_0_10)jmsSession).isQueueExist(dest, true));
         assertTrue("Queue not bound as expected",(
                 (AMQSession_0_10)jmsSession).isQueueBound("", 
-                    dest.getAddressName(),dest.getAddressName(), dest.getSourceNode().getDeclareArgs()));
+                    dest.getAddressName(),dest.getAddressName(), dest.getNode().getDeclareArgs()));
         
         // create receiver -----------------------------------------
         addr1 = "ADDR:testQueue2; { create: receiver }";
@@ -126,16 +124,16 @@ public class AddressBasedDestinationTest extends QpidBrokerTestCase
         }
             
         assertFalse("Queue should not be created",(
-                (AMQSession_0_10)jmsSession).isQueueExist(dest,(QueueNode)dest.getSourceNode(), true));
+                (AMQSession_0_10)jmsSession).isQueueExist(dest, false));
         
         
         cons = jmsSession.createConsumer(dest); 
         
         assertTrue("Queue not created as expected",(
-                (AMQSession_0_10)jmsSession).isQueueExist(dest,(QueueNode)dest.getSourceNode(), true));              
+                (AMQSession_0_10)jmsSession).isQueueExist(dest, true));
         assertTrue("Queue not bound as expected",(
                 (AMQSession_0_10)jmsSession).isQueueBound("", 
-                    dest.getAddressName(),dest.getAddressName(), dest.getSourceNode().getDeclareArgs()));
+                    dest.getAddressName(),dest.getAddressName(), dest.getNode().getDeclareArgs()));
         
         // create never --------------------------------------------
         addr1 = "ADDR:testQueue3; { create: never }";
@@ -161,7 +159,7 @@ public class AddressBasedDestinationTest extends QpidBrokerTestCase
         }
             
         assertFalse("Queue should not be created",(
-                (AMQSession_0_10)jmsSession).isQueueExist(dest,(QueueNode)dest.getSourceNode(), true));
+                (AMQSession_0_10)jmsSession).isQueueExist(dest, false));
         
         // create sender ------------------------------------------
         addr1 = "ADDR:testQueue3; { create: sender }";
@@ -177,14 +175,14 @@ public class AddressBasedDestinationTest extends QpidBrokerTestCase
                     "doesn't resolve to an exchange or a queue"));
         }
         assertFalse("Queue should not be created",(
-                (AMQSession_0_10)jmsSession).isQueueExist(dest,(QueueNode)dest.getSourceNode(), true));
+                (AMQSession_0_10)jmsSession).isQueueExist(dest, false));
         
         prod = jmsSession.createProducer(dest);
         assertTrue("Queue not created as expected",(
-                (AMQSession_0_10)jmsSession).isQueueExist(dest,(QueueNode)dest.getSourceNode(), true));              
+                (AMQSession_0_10)jmsSession).isQueueExist(dest, true));
         assertTrue("Queue not bound as expected",(
                 (AMQSession_0_10)jmsSession).isQueueBound("", 
-                    dest.getAddressName(),dest.getAddressName(), dest.getSourceNode().getDeclareArgs()));
+                    dest.getAddressName(),dest.getAddressName(), dest.getNode().getDeclareArgs()));
         
     }
  
@@ -221,7 +219,7 @@ public class AddressBasedDestinationTest extends QpidBrokerTestCase
         // Even if the consumer is closed the queue and the bindings should be intact.
         
         assertTrue("Queue not created as expected",(
-                (AMQSession_0_10)jmsSession).isQueueExist(dest,(QueueNode)dest.getSourceNode(), true));              
+                (AMQSession_0_10)jmsSession).isQueueExist(dest, true));
         
         assertTrue("Queue not bound as expected",(
                 (AMQSession_0_10)jmsSession).isQueueBound("", 
@@ -326,7 +324,7 @@ public class AddressBasedDestinationTest extends QpidBrokerTestCase
         }
         
         assertTrue("Exchange not created as expected",(
-                (AMQSession_0_10)jmsSession).isExchangeExist(dest, (ExchangeNode)dest.getTargetNode() , true));
+                (AMQSession_0_10)jmsSession).isExchangeExist(dest,true));
        
         // The existence of the queue is implicitly tested here
         assertTrue("Queue not bound as expected",(
@@ -367,7 +365,7 @@ public class AddressBasedDestinationTest extends QpidBrokerTestCase
     public void checkQueueForBindings(Session jmsSession, AMQDestination dest,String headersBinding) throws Exception
     {
     	assertTrue("Queue not created as expected",(
-                (AMQSession_0_10)jmsSession).isQueueExist(dest,(QueueNode)dest.getSourceNode(), true));              
+                (AMQSession_0_10)jmsSession).isQueueExist(dest, true));
         
         assertTrue("Queue not bound as expected",(
                 (AMQSession_0_10)jmsSession).isQueueBound("", 
@@ -506,14 +504,14 @@ public class AddressBasedDestinationTest extends QpidBrokerTestCase
         MessageConsumer cons3 = jmsSession.createConsumer(dest3);
         
         assertTrue("Destination1 was not created as expected",(
-                (AMQSession_0_10)jmsSession).isQueueExist(dest1,(QueueNode)dest1.getSourceNode(), true));              
+                (AMQSession_0_10)jmsSession).isQueueExist(dest1, true));
         
         assertTrue("Destination1 was not bound as expected",(
                 (AMQSession_0_10)jmsSession).isQueueBound("", 
                     dest1.getAddressName(),dest1.getAddressName(), null));
         
         assertTrue("Destination2 was not created as expected",(
-                (AMQSession_0_10)jmsSession).isQueueExist(dest2,(QueueNode)dest2.getSourceNode(), true));              
+                (AMQSession_0_10)jmsSession).isQueueExist(dest2,true));
         
         assertTrue("Destination2 was not bound as expected",(
                 (AMQSession_0_10)jmsSession).isQueueBound("", 
@@ -602,14 +600,14 @@ public class AddressBasedDestinationTest extends QpidBrokerTestCase
         cons.close();
         
         // Using the ADDR method to create a more complicated queue
-        String addr = "ADDR:amq.direct/x512; {create: receiver, " +
+        String addr = "ADDR:amq.direct/x512; {" +
         "link : {name : 'MY.RESP.QUEUE', " + 
         "x-declare : { auto-delete: true, exclusive: true, " +
                      "arguments : {'qpid.max_size': 1000, 'qpid.policy_type': ring} } } }";
         queue = ssn.createQueue(addr);
         
-        prod = ssn.createProducer(queue); 
         cons = ssn.createConsumer(queue);
+        prod = ssn.createProducer(queue);
         assertTrue("MY.RESP.QUEUE was not created as expected",(
                 (AMQSession_0_10)ssn).isQueueBound("amq.direct", 
                     "MY.RESP.QUEUE","x512", null));
@@ -677,8 +675,8 @@ public class AddressBasedDestinationTest extends QpidBrokerTestCase
         
         // Using the ADDR method to create a more complicated topic
         topic = ssn.createTopic(addr);
-        prod = ssn.createProducer(topic); 
         cons = ssn.createConsumer(topic);
+        prod = ssn.createProducer(topic);
         
         assertTrue("The queue was not bound to vehicle exchange using bus as the binding key",(
                 (AMQSession_0_10)ssn).isQueueBound("vehicles", 
@@ -778,7 +776,7 @@ public class AddressBasedDestinationTest extends QpidBrokerTestCase
     public void testSubscriptionForSameDestination() throws Exception
     {
         Session ssn = _connection.createSession(false,Session.AUTO_ACKNOWLEDGE);        
-        Destination dest = ssn.createTopic("ADDR:amq.topic/foo; {link:{durable:true}}");
+        Destination dest = ssn.createTopic("ADDR:amq.topic/foo");
         MessageConsumer consumer1 = ssn.createConsumer(dest);
         MessageConsumer consumer2 = ssn.createConsumer(dest);
         MessageProducer prod = ssn.createProducer(dest);
@@ -840,7 +838,8 @@ public class AddressBasedDestinationTest extends QpidBrokerTestCase
         		"}";
         
         // Using the ADDR method to create a more complicated topic
-        MessageConsumer  cons = ssn.createConsumer(new AMQAnyDestination(addr));
+        Topic topic = ssn.createTopic(addr);
+        MessageConsumer  cons = ssn.createConsumer(topic);
         
         assertTrue("The queue was not bound to MRKT exchange using NYSE.# as the binding key",(
                 (AMQSession_0_10)ssn).isQueueBound("MRKT", 
@@ -854,7 +853,7 @@ public class AddressBasedDestinationTest extends QpidBrokerTestCase
                 (AMQSession_0_10)ssn).isQueueBound("MRKT", 
                     "my-topic","CNTL.#", null));
         
-        MessageProducer prod = ssn.createProducer(ssn.createTopic(addr));
+        MessageProducer prod = ssn.createProducer(topic);
         Message msg = ssn.createTextMessage("test");
         msg.setStringProperty("qpid.subject", "NASDAQ.ABCD");
         prod.send(msg);
@@ -909,32 +908,31 @@ public class AddressBasedDestinationTest extends QpidBrokerTestCase
     {
         Session ssn = _connection.createSession(false,Session.AUTO_ACKNOWLEDGE);        
         
+        String bindingStr = "x-bindings:[{key:'NYSE.#'},{key:'NASDAQ.#'},{key:'CNTL.#'}]}}";
+
         Properties props = new Properties();
         props.setProperty("java.naming.factory.initial", "org.apache.qpid.jndi.PropertiesFileInitialContextFactory");
-        props.setProperty("destination.address1", "ADDR:amq.topic");
-        props.setProperty("destination.address2", "ADDR:amq.direct/test");                
-        String addrStr = "ADDR:amq.topic/test; {link:{name: my-topic," +
-                  "x-bindings:[{key:'NYSE.#'},{key:'NASDAQ.#'},{key:'CNTL.#'}]}}";
-        props.setProperty("destination.address3", addrStr);
-        props.setProperty("topic.address4", "hello.world");
-        addrStr = "ADDR:my_queue; {create:always,link: {x-subscribes:{exclusive: true, arguments: {a:b,x:y}}}}";
+        props.setProperty("destination.address1", "ADDR:amq.topic/test");
+        props.setProperty("destination.address2", "ADDR:amq.topic/test; {node:{" + bindingStr);
+        props.setProperty("destination.address3", "ADDR:amq.topic/test; {link:{" + bindingStr);
+        String addrStr = "ADDR:my_queue; {create:always,link: {x-subscribes:{exclusive: true, arguments: {a:b,x:y}}}}";
         props.setProperty("destination.address5", addrStr); 
         
         Context ctx = new InitialContext(props);       
 
-        for (int i=1; i < 5; i++)
+        for (int i=1; i < 4; i++)
         {
             Topic topic = (Topic) ctx.lookup("address"+i);
-            createDurableSubscriber(ctx,ssn,"address"+i,topic);
+            createDurableSubscriber(ctx,ssn,"address"+i,topic,"ADDR:amq.topic/test");
         }
         
         Topic topic = ssn.createTopic("ADDR:news.us");
-        createDurableSubscriber(ctx,ssn,"my-dest",topic);
+        createDurableSubscriber(ctx,ssn,"my-dest",topic,"ADDR:news.us");
         
         Topic namedQueue = (Topic) ctx.lookup("address5");
         try
         {
-            createDurableSubscriber(ctx,ssn,"my-queue",namedQueue);
+            createDurableSubscriber(ctx,ssn,"my-queue",namedQueue,"ADDR:amq.topic/test");
             fail("Exception should be thrown. Durable subscribers cannot be created for Queues");
         }
         catch(JMSException e)
@@ -943,16 +941,74 @@ public class AddressBasedDestinationTest extends QpidBrokerTestCase
                     e.getMessage());
         }
     }
-    
-    private void createDurableSubscriber(Context ctx,Session ssn,String destName,Topic topic) throws Exception
+
+    public void testDurableSubscription() throws Exception
+    {
+        Session session = _connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
+        Topic topic = session.createTopic("ADDR:amq.topic/" + getTestQueueName());
+        MessageProducer publisher = session.createProducer(topic);
+        MessageConsumer subscriber = session.createDurableSubscriber(topic, getTestQueueName());
+
+        TextMessage messageToSend = session.createTextMessage("Test0");
+        publisher.send(messageToSend);
+        ((AMQSession)session).sync();
+
+        Message receivedMessage = subscriber.receive(1000);
+        assertNotNull("Message has not been received", receivedMessage);
+        assertEquals("Unexpected message", messageToSend.getText(), ((TextMessage)receivedMessage).getText());
+
+        subscriber.close();
+
+        messageToSend = session.createTextMessage("Test1");
+        publisher.send(messageToSend);
+        ((AMQSession)session).sync();
+
+        subscriber = session.createDurableSubscriber(topic, getTestQueueName());
+        receivedMessage = subscriber.receive(1000);
+        assertNotNull("Message has not been received", receivedMessage);
+        assertEquals("Unexpected message", messageToSend.getText(), ((TextMessage)receivedMessage).getText());
+    }
+
+    public void testDurableSubscriptionnWithSelector() throws Exception
+    {
+        Session session = _connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
+        Topic topic = session.createTopic("ADDR:amq.topic/" + getTestQueueName());
+        MessageProducer publisher = session.createProducer(topic);
+        MessageConsumer subscriber = session.createDurableSubscriber(topic, getTestQueueName(), "id=1", false);
+
+        TextMessage messageToSend = session.createTextMessage("Test0");
+        messageToSend.setIntProperty("id", 1);
+        publisher.send(messageToSend);
+        ((AMQSession)session).sync();
+
+        Message receivedMessage = subscriber.receive(1000);
+        assertNotNull("Message has not been received", receivedMessage);
+        assertEquals("Unexpected message", messageToSend.getText(), ((TextMessage)receivedMessage).getText());
+        assertEquals("Unexpected id", 1, receivedMessage.getIntProperty("id"));
+
+        subscriber.close();
+
+        messageToSend = session.createTextMessage("Test1");
+        messageToSend.setIntProperty("id", 1);
+        publisher.send(messageToSend);
+        ((AMQSession)session).sync();
+
+        subscriber = session.createDurableSubscriber(topic, getTestQueueName(), "id=1", false);
+        receivedMessage = subscriber.receive(1000);
+        assertNotNull("Message has not been received", receivedMessage);
+        assertEquals("Unexpected message", messageToSend.getText(), ((TextMessage)receivedMessage).getText());
+        assertEquals("Unexpected id", 1, receivedMessage.getIntProperty("id"));
+    }
+
+    private void createDurableSubscriber(Context ctx,Session ssn,String destName,Topic topic, String producerAddr) throws Exception
     {        
         MessageConsumer cons = ssn.createDurableSubscriber(topic, destName);
-        MessageProducer prod = ssn.createProducer(topic);
+        MessageProducer prod = ssn.createProducer(ssn.createTopic(producerAddr));
         
         Message m = ssn.createTextMessage(destName);
         prod.send(m);
         Message msg = cons.receive(1000);
-        assertNotNull(msg);
+        assertNotNull("Message not received as expected when using Topic : " + topic,msg);
         assertEquals(destName,((TextMessage)msg).getText());
         ssn.unsubscribe(destName);
     }
@@ -977,7 +1033,7 @@ public class AddressBasedDestinationTest extends QpidBrokerTestCase
         }
         
         assertFalse("Queue not deleted as expected",(
-                (AMQSession_0_10)jmsSession).isQueueExist(dest,(QueueNode)dest.getSourceNode(), true));  
+                (AMQSession_0_10)jmsSession).isQueueExist(dest, false));
         
         
         String addr2 = "ADDR:testQueue2;{create: always, delete: receiver}";
@@ -993,7 +1049,7 @@ public class AddressBasedDestinationTest extends QpidBrokerTestCase
         }
         
         assertFalse("Queue not deleted as expected",(
-                (AMQSession_0_10)jmsSession).isQueueExist(dest,(QueueNode)dest.getSourceNode(), true));  
+                (AMQSession_0_10)jmsSession).isQueueExist(dest, false));
 
         
         String addr3 = "ADDR:testQueue3;{create: always, delete: sender}";
@@ -1010,9 +1066,7 @@ public class AddressBasedDestinationTest extends QpidBrokerTestCase
         }
         
         assertFalse("Queue not deleted as expected",(
-                (AMQSession_0_10)jmsSession).isQueueExist(dest,(QueueNode)dest.getSourceNode(), true));  
-
-        
+                (AMQSession_0_10)jmsSession).isQueueExist(dest, false));
     }
     
     /**
@@ -1094,7 +1148,7 @@ public class AddressBasedDestinationTest extends QpidBrokerTestCase
         MessageConsumer cons = ssn.createConsumer(ssn.createTopic("ADDR:amq.topic/test"));
         MessageProducer prod = ssn.createProducer(null);
         
-        Queue queue = ssn.createQueue("ADDR:amq.topic/test");
+        Topic queue = ssn.createTopic("ADDR:amq.topic/test");
         prod.send(queue,ssn.createTextMessage("A"));
         
         Message msg = cons.receive(1000);
@@ -1307,4 +1361,62 @@ public class AddressBasedDestinationTest extends QpidBrokerTestCase
         assertNotNull("message should be re-received by consumer after rollback", receivedMessage);
         jmsSession.commit();
     }
+
+    /**
+     * Test Goals :
+     *
+     * 1. Verify that link bindings are created and destroyed after creating and closing a subscriber.
+     * 2. Verify that link bindings are created and destroyed after creating and closing a subscriber.
+     */
+    public void testLinkBindingBehavior() throws Exception
+    {
+        Session jmsSession = _connection.createSession(false,Session.AUTO_ACKNOWLEDGE);
+        String addr = "ADDR:my-queue; {create: always, " +
+              "link: " +
+              "{" +
+                   "x-bindings: [{exchange : 'amq.direct', key : test}]," +
+              "}" +
+        "}";
+
+        AMQDestination dest = (AMQDestination)jmsSession.createQueue(addr);
+        MessageConsumer cons = jmsSession.createConsumer(dest);
+        AMQSession_0_10 ssn = (AMQSession_0_10)jmsSession;
+
+        assertTrue("Queue not created as expected",ssn.isQueueExist(dest, true));
+        assertTrue("Queue not bound as expected",ssn.isQueueBound("amq.direct","my-queue","test", null));
+
+        cons.close(); // closing consumer, link binding should be removed now.
+        assertTrue("Queue should still be there",ssn.isQueueExist(dest, true));
+        assertFalse("Binding should not exist anymore",ssn.isQueueBound("amq.direct","my-queue","test", null));
+
+        MessageProducer prod = jmsSession.createProducer(dest);
+        assertTrue("Queue not bound as expected",ssn.isQueueBound("amq.direct","my-queue","test", null));
+        prod.close();
+        assertFalse("Binding should not exist anymore",ssn.isQueueBound("amq.direct","my-queue","test", null));
+    }
+
+    /**
+     * Test Goals : Verifies that the subscription queue created is as specified under link properties.
+     */
+    public void testCustomizingSubscriptionQueue() throws Exception
+    {
+        Session ssn = _connection.createSession(false,Session.AUTO_ACKNOWLEDGE);
+        String xDeclareArgs = "x-declare: { exclusive: false, auto-delete: false," +
+                                           "alternate-exchange: 'amq.fanout'," +
+                                           "arguments: {'qpid.max_size': 1000,'qpid.max_count': 100}" +
+                                          "}";
+
+        String addr = "ADDR:amq.topic/test; {link: {name:my-queue, durable:true," + xDeclareArgs + "}}";
+        Destination dest = ssn.createTopic(addr);
+        MessageConsumer cons = ssn.createConsumer(dest);
+
+        String verifyAddr = "ADDR:my-queue;{ node: {durable:true, " + xDeclareArgs + "}}";
+        AMQDestination verifyDest = (AMQDestination)ssn.createQueue(verifyAddr);
+        ((AMQSession_0_10)ssn).isQueueExist(verifyDest, true);
+
+        // Verify that the producer does not delete the subscription queue.
+        MessageProducer prod = ssn.createProducer(dest);
+        prod.close();
+        ((AMQSession_0_10)ssn).isQueueExist(verifyDest, true);
+    }
 }
diff --git a/java/systests/src/main/java/org/apache/qpid/test/client/failover/FailoverTest.java b/java/systests/src/main/java/org/apache/qpid/test/client/failover/FailoverTest.java
index b82c3756f2..2875e2c6b1 100644
--- a/java/systests/src/main/java/org/apache/qpid/test/client/failover/FailoverTest.java
+++ b/java/systests/src/main/java/org/apache/qpid/test/client/failover/FailoverTest.java
@@ -24,6 +24,7 @@ package org.apache.qpid.test.client.failover;
 import org.apache.log4j.Logger;
 
 import org.apache.qpid.client.AMQConnection;
+import org.apache.qpid.client.AMQSession;
 import org.apache.qpid.jms.ConnectionListener;
 import org.apache.qpid.test.utils.FailoverBaseCase;
 
@@ -35,7 +36,6 @@ import javax.jms.MessageProducer;
 import javax.jms.Queue;
 import javax.jms.Session;
 import javax.jms.TextMessage;
-import javax.naming.NamingException;
 import java.util.Random;
 import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.TimeUnit;
@@ -75,7 +75,7 @@ public class FailoverTest extends FailoverBaseCase implements ConnectionListener
         failoverComplete = new CountDownLatch(1);
     }
 
-    protected void init(boolean transacted, int mode) throws JMSException, NamingException
+    private void init(boolean transacted, int mode) throws Exception
     {
         consumerSession = connection.createSession(transacted, mode);
         queue = consumerSession.createQueue(getName()+System.currentTimeMillis());
@@ -125,7 +125,7 @@ public class FailoverTest extends FailoverBaseCase implements ConnectionListener
         }
     }
 
-    private void sendMessages(int startIndex,int endIndex, boolean transacted) throws JMSException
+    private void sendMessages(int startIndex,int endIndex, boolean transacted) throws Exception
     {
         _logger.debug("**************** Send (Start: " + startIndex + ", End:" + endIndex + ")***********************");
         
@@ -144,6 +144,10 @@ public class FailoverTest extends FailoverBaseCase implements ConnectionListener
         {
             producerSession.commit();
         }
+        else
+        {
+            ((AMQSession)producerSession).sync();
+        }
     }
 
     public void testP2PFailover() throws Exception
@@ -163,13 +167,13 @@ public class FailoverTest extends FailoverBaseCase implements ConnectionListener
     {
         if (CLUSTERED)
         {    
-            testP2PFailover(numMessages, false,true, false);
+            testP2PFailover(numMessages, false, true, false);
         }
     }    
      
     public void testP2PFailoverTransacted() throws Exception
     {
-        testP2PFailover(numMessages, true,true, false);
+        testP2PFailover(numMessages, true,true, true);
     }
 
     public void testP2PFailoverTransactedWithMessagesLeftToConsumeAndProduce() throws Exception
@@ -177,17 +181,16 @@ public class FailoverTest extends FailoverBaseCase implements ConnectionListener
         // Currently the cluster does not support transactions that span a failover
         if (CLUSTERED)
         {
-            testP2PFailover(numMessages, false,false, false);
+            testP2PFailover(numMessages, false, false, false);
         }
     }
-
-    private void testP2PFailover(int totalMessages, boolean consumeAll, boolean produceAll , boolean transacted) throws JMSException, NamingException
+    private void testP2PFailover(int totalMessages, boolean consumeAll, boolean produceAll , boolean transacted) throws Exception
     {        
         init(transacted, Session.AUTO_ACKNOWLEDGE);
         runP2PFailover(totalMessages,consumeAll, produceAll , transacted);
     } 
-    
-    protected void runP2PFailover(int totalMessages, boolean consumeAll, boolean produceAll , boolean transacted) throws JMSException, NamingException
+
+    private void runP2PFailover(int totalMessages, boolean consumeAll, boolean produceAll , boolean transacted) throws Exception
     {
         int toProduce = totalMessages;
         
@@ -254,7 +257,7 @@ public class FailoverTest extends FailoverBaseCase implements ConnectionListener
             //evil ignore IE.
         }
     }
-   
+
     public void testClientAckFailover() throws Exception
     {
         init(false, Session.CLIENT_ACKNOWLEDGE);
diff --git a/java/systests/src/main/java/org/apache/qpid/test/client/message/JMSDestinationTest.java b/java/systests/src/main/java/org/apache/qpid/test/client/message/JMSDestinationTest.java
index 5b350d2d89..3cc15d5e9d 100644
--- a/java/systests/src/main/java/org/apache/qpid/test/client/message/JMSDestinationTest.java
+++ b/java/systests/src/main/java/org/apache/qpid/test/client/message/JMSDestinationTest.java
@@ -63,8 +63,7 @@ public class JMSDestinationTest extends QpidBrokerTestCase
 
     public void setUp() throws Exception
     {
-        //Ensure JMX management is enabled for MovedToQueue test 
-        setConfigurationProperty("management.enabled", "true");
+        getBrokerConfiguration().addJmxManagementConfiguration();
 
         super.setUp();
 
diff --git a/java/systests/src/main/java/org/apache/qpid/test/client/timeouts/SyncWaitDelayTest.java b/java/systests/src/main/java/org/apache/qpid/test/client/timeouts/SyncWaitDelayTest.java
index ee81e7c372..9bf7dbd62a 100644
--- a/java/systests/src/main/java/org/apache/qpid/test/client/timeouts/SyncWaitDelayTest.java
+++ b/java/systests/src/main/java/org/apache/qpid/test/client/timeouts/SyncWaitDelayTest.java
@@ -54,11 +54,9 @@ public class SyncWaitDelayTest extends QpidBrokerTestCase
     public void setUp() throws Exception
     {
 
-        setConfigurationProperty("virtualhosts.virtualhost." + VIRTUALHOST+".store.class", "org.apache.qpid.server.store.SlowMessageStore");
-        setConfigurationProperty("virtualhosts.virtualhost." + VIRTUALHOST+".store.delays.commitTran.post", String.valueOf(POST_COMMIT_DELAY));
-        setConfigurationProperty("management.enabled", "false");
+        setVirtualHostConfigurationProperty("virtualhosts.virtualhost." + VIRTUALHOST+".store.class", "org.apache.qpid.server.store.SlowMessageStore");
+        setVirtualHostConfigurationProperty("virtualhosts.virtualhost." + VIRTUALHOST+".store.delays.commitTran.post", String.valueOf(POST_COMMIT_DELAY));
 
-        
         super.setUp();
 
         //Set the syncWrite timeout to be just larger than the delay on the commitTran.
diff --git a/java/systests/src/main/java/org/apache/qpid/test/unit/basic/InvalidDestinationTest.java b/java/systests/src/main/java/org/apache/qpid/test/unit/basic/InvalidDestinationTest.java
index 53f37cd915..8961574d1e 100644
--- a/java/systests/src/main/java/org/apache/qpid/test/unit/basic/InvalidDestinationTest.java
+++ b/java/systests/src/main/java/org/apache/qpid/test/unit/basic/InvalidDestinationTest.java
@@ -21,16 +21,23 @@
 
 package org.apache.qpid.test.unit.basic;
 
-import org.apache.qpid.client.AMQConnection;
-import org.apache.qpid.client.AMQQueue;
-import org.apache.qpid.test.utils.QpidBrokerTestCase;
-
+import java.util.Collections;
+import java.util.Map;
+import javax.jms.Connection;
 import javax.jms.InvalidDestinationException;
+import javax.jms.JMSException;
+import javax.jms.MessageProducer;
 import javax.jms.Queue;
 import javax.jms.QueueSender;
 import javax.jms.QueueSession;
 import javax.jms.Session;
 import javax.jms.TextMessage;
+import javax.jms.Topic;
+import org.apache.qpid.client.AMQConnection;
+import org.apache.qpid.client.AMQQueue;
+import org.apache.qpid.configuration.ClientProperties;
+import org.apache.qpid.jms.ConnectionURL;
+import org.apache.qpid.test.utils.QpidBrokerTestCase;
 
 public class InvalidDestinationTest extends QpidBrokerTestCase
 {
@@ -48,21 +55,23 @@ public class InvalidDestinationTest extends QpidBrokerTestCase
         super.tearDown();
     }
 
-
-
     public void testInvalidDestination() throws Exception
     {
-        Queue invalidDestination = new AMQQueue("amq.direct","unknownQ");
-        AMQQueue validDestination = new AMQQueue("amq.direct","knownQ");
         QueueSession queueSession = _connection.createQueueSession(false, Session.AUTO_ACKNOWLEDGE);
 
+        Queue invalidDestination = queueSession.createQueue("unknownQ");
+
+        Queue validDestination = queueSession.createQueue(getTestQueueName());
+
         // This is the only easy way to create and bind a queue from the API :-(
         queueSession.createConsumer(validDestination);
+        QueueSender sender;
+        TextMessage msg= queueSession.createTextMessage("Hello");
 
-        QueueSender sender = queueSession.createSender(invalidDestination);
-        TextMessage msg = queueSession.createTextMessage("Hello");
         try
         {
+            sender = queueSession.createSender(invalidDestination);
+
             sender.send(msg);
             fail("Expected InvalidDestinationException");
         }
@@ -70,10 +79,8 @@ public class InvalidDestinationTest extends QpidBrokerTestCase
         {
             // pass
         }
-        sender.close();
 
         sender = queueSession.createSender(null);
-        invalidDestination = new AMQQueue("amq.direct","unknownQ");
 
         try
         {
@@ -86,19 +93,79 @@ public class InvalidDestinationTest extends QpidBrokerTestCase
         }
         sender.send(validDestination,msg);
         sender.close();
-        validDestination = new AMQQueue("amq.direct","knownQ");
         sender = queueSession.createSender(validDestination);
         sender.send(msg);
+    }
 
+    /**
+     * Tests that specifying the {@value ClientProperties#VERIFY_QUEUE_ON_SEND} system property
+     * results in an exception when sending to an invalid queue destination.
+     */
+    public void testInvalidDestinationOnMessageProducer() throws Exception
+    {
+        setTestSystemProperty(ClientProperties.VERIFY_QUEUE_ON_SEND, "true");
+        final AMQConnection connection = (AMQConnection) getConnection();
+        doInvalidDestinationOnMessageProducer(connection);
+    }
 
+    /**
+     * Tests that specifying the {@value ConnectionURL.OPTIONS_VERIFY_QUEUE_ON_SEND}
+     * connection URL option property results in an exception when sending to an
+     * invalid queue destination.
+     */
+    public void testInvalidDestinationOnMessageProducerURL() throws Exception
+    {
+        Map options = Collections.singletonMap(ConnectionURL.OPTIONS_VERIFY_QUEUE_ON_SEND, "true");
+        doInvalidDestinationOnMessageProducer(getConnectionWithOptions(options));
+    }
 
+    private void doInvalidDestinationOnMessageProducer(Connection connection) throws JMSException
+    {
+        Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
 
-    }
+        String invalidQueueName = getTestQueueName() + "UnknownQ";
+        Queue invalidDestination = session.createQueue(invalidQueueName);
 
+        String validQueueName = getTestQueueName() + "KnownQ";
+        Queue validDestination = session.createQueue(validQueueName);
 
-    public static junit.framework.Test suite()
-    {
+        // This is the only easy way to create and bind a queue from the API :-(
+        session.createConsumer(validDestination);
+
+        MessageProducer sender;
+        TextMessage msg = session.createTextMessage("Hello");
+        try
+        {
+            sender = session.createProducer(invalidDestination);
+            sender.send(msg);
+            fail("Expected InvalidDestinationException");
+        }
+        catch (InvalidDestinationException ex)
+        {
+            // pass
+        }
 
-        return new junit.framework.TestSuite(InvalidDestinationTest.class);
+        sender = session.createProducer(null);
+        invalidDestination = new AMQQueue("amq.direct",invalidQueueName);
+
+        try
+        {
+            sender.send(invalidDestination,msg);
+            fail("Expected InvalidDestinationException");
+        }
+        catch (InvalidDestinationException ex)
+        {
+            // pass
+        }
+        sender.send(validDestination, msg);
+        sender.close();
+        sender = session.createProducer(validDestination);
+        sender.send(msg);
+
+        //Verify sending to an 'invalid' Topic doesn't throw an exception
+        String invalidTopic = getTestQueueName() + "UnknownT";
+        Topic topic = session.createTopic(invalidTopic);
+        sender = session.createProducer(topic);
+        sender.send(msg);
     }
 }
diff --git a/java/systests/src/main/java/org/apache/qpid/test/unit/client/DynamicQueueExchangeCreateTest.java b/java/systests/src/main/java/org/apache/qpid/test/unit/client/DynamicQueueExchangeCreateTest.java
index 8577fb5b6a..4e9477f4b6 100644
--- a/java/systests/src/main/java/org/apache/qpid/test/unit/client/DynamicQueueExchangeCreateTest.java
+++ b/java/systests/src/main/java/org/apache/qpid/test/unit/client/DynamicQueueExchangeCreateTest.java
@@ -20,26 +20,59 @@
  */
 package org.apache.qpid.test.unit.client;
 
+import java.io.IOException;
+
 import org.apache.qpid.AMQException;
+import org.apache.qpid.configuration.ClientProperties;
+import org.apache.qpid.management.common.mbeans.ManagedExchange;
 import org.apache.qpid.protocol.AMQConstant;
+import org.apache.qpid.test.utils.JMXTestUtils;
 import org.apache.qpid.test.utils.QpidBrokerTestCase;
+import org.apache.qpid.url.BindingURL;
 
 import javax.jms.Connection;
 import javax.jms.JMSException;
 import javax.jms.Queue;
 import javax.jms.Session;
 
-/**
- * QPID-155
- *
- * Test to validate that setting the respective qpid.declare_queues,
- * qpid.declare_exchanges system properties functions as expected.
- */
 public class DynamicQueueExchangeCreateTest extends QpidBrokerTestCase
 {
-    public void testQueueDeclare() throws Exception
+    private JMXTestUtils _jmxUtils;
+
+    @Override
+    public void setUp() throws Exception
+    {
+        _jmxUtils = new JMXTestUtils(this);
+        _jmxUtils.setUp();
+
+        super.setUp();
+        _jmxUtils.open();
+    }
+
+    @Override
+    public void tearDown() throws Exception
     {
-        setSystemProperty("qpid.declare_queues", "false");
+        try
+        {
+            if (_jmxUtils != null)
+            {
+                _jmxUtils.close();
+            }
+        }
+        finally
+        {
+            super.tearDown();
+        }
+    }
+
+    /*
+     * Tests to validate that setting the respective qpid.declare_queues,
+     * qpid.declare_exchanges system properties functions as expected.
+     */
+
+    public void testQueueNotDeclaredDuringConsumerCreation() throws Exception
+    {
+        setSystemProperty(ClientProperties.QPID_DECLARE_QUEUES_PROP_NAME, "false");
 
         Connection connection = getConnection();
 
@@ -58,16 +91,16 @@ public class DynamicQueueExchangeCreateTest extends QpidBrokerTestCase
         }
     }
 
-    public void testExchangeDeclare() throws Exception
+    public void testExchangeNotDeclaredDuringConsumerCreation() throws Exception
     {
-        setSystemProperty("qpid.declare_exchanges", "false");
+        setSystemProperty(ClientProperties.QPID_DECLARE_EXCHANGES_PROP_NAME, "false");
 
         Connection connection = getConnection();
 
         Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
 
-        String EXCHANGE_TYPE = "test.direct";
-        Queue queue = session.createQueue("direct://" + EXCHANGE_TYPE + "/queue/queue");
+        String exchangeName = getTestQueueName();
+        Queue queue = session.createQueue("direct://" + exchangeName + "/queue/queue");
 
         try
         {
@@ -78,6 +111,50 @@ public class DynamicQueueExchangeCreateTest extends QpidBrokerTestCase
         {
             checkExceptionErrorCode(e, AMQConstant.NOT_FOUND);
         }
+
+        //verify the exchange was not declared
+        String exchangeObjectName = _jmxUtils.getExchangeObjectName("test", exchangeName);
+        assertFalse("exchange should not exist", _jmxUtils.doesManagedObjectExist(exchangeObjectName));
+    }
+
+    /**
+     * Checks that setting {@value ClientProperties#QPID_DECLARE_EXCHANGES_PROP_NAME} false results in
+     * disabling implicit ExchangeDeclares during producer creation when using a {@link BindingURL}
+     */
+    public void testExchangeNotDeclaredDuringProducerCreation() throws Exception
+    {
+        Connection connection = getConnection();
+        Session session1 = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
+        String exchangeName1 = getTestQueueName() + "1";
+
+
+        Queue queue = session1.createQueue("direct://" + exchangeName1 + "/queue/queue");
+        session1.createProducer(queue);
+
+        //close the session to ensure any previous commands were fully processed by
+        //the broker before observing their effect
+        session1.close();
+
+        //verify the exchange was declared
+        String exchangeObjectName = _jmxUtils.getExchangeObjectName("test", exchangeName1);
+        assertTrue("exchange should exist", _jmxUtils.doesManagedObjectExist(exchangeObjectName));
+
+        //Now disable the implicit exchange declares and try again
+        setSystemProperty(ClientProperties.QPID_DECLARE_EXCHANGES_PROP_NAME, "false");
+
+        Session session2 = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
+        String exchangeName2 = getTestQueueName() + "2";
+
+        Queue queue2 = session2.createQueue("direct://" + exchangeName2 + "/queue/queue");
+        session2.createProducer(queue2);
+
+        //close the session to ensure any previous commands were fully processed by
+        //the broker before observing their effect
+        session2.close();
+
+        //verify the exchange was not declared
+        String exchangeObjectName2 = _jmxUtils.getExchangeObjectName("test", exchangeName2);
+        assertFalse("exchange should not exist", _jmxUtils.doesManagedObjectExist(exchangeObjectName2));
     }
 
     private void checkExceptionErrorCode(JMSException original, AMQConstant code)
@@ -87,4 +164,71 @@ public class DynamicQueueExchangeCreateTest extends QpidBrokerTestCase
         assertTrue("Linked exception should be an AMQException", linked instanceof AMQException);
         assertEquals("Error code should be " + code.getCode(), code, ((AMQException) linked).getErrorCode());
     }
+
+    /*
+     * Tests to validate that the custom exchanges declared by the client during
+     * consumer and producer creation have the expected properties.
+     */
+
+    public void testPropertiesOfCustomExchangeDeclaredDuringProducerCreation() throws Exception
+    {
+        implTestPropertiesOfCustomExchange(true, false);
+    }
+
+    public void testPropertiesOfCustomExchangeDeclaredDuringConsumerCreation() throws Exception
+    {
+        implTestPropertiesOfCustomExchange(false, true);
+    }
+
+    private void implTestPropertiesOfCustomExchange(boolean createProducer, boolean createConsumer) throws Exception
+    {
+        Connection connection = getConnection();
+
+        Session session1 = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
+        String exchangeName1 = getTestQueueName() + "1";
+        String queueName1 = getTestQueueName() + "1";
+
+        Queue queue = session1.createQueue("direct://" + exchangeName1 + "/" + queueName1 + "/" + queueName1 + "?" + BindingURL.OPTION_EXCHANGE_AUTODELETE + "='true'");
+        if(createProducer)
+        {
+            session1.createProducer(queue);
+        }
+
+        if(createConsumer)
+        {
+            session1.createConsumer(queue);
+        }
+        session1.close();
+
+        //verify the exchange was declared to expectation
+        verifyDeclaredExchange(exchangeName1, true, false);
+
+        Session session2 = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
+        String exchangeName2 = getTestQueueName() + "2";
+        String queueName2 = getTestQueueName() + "2";
+
+        Queue queue2 = session2.createQueue("direct://" + exchangeName2 + "/" + queueName2 + "/" + queueName2 + "?" + BindingURL.OPTION_EXCHANGE_DURABLE + "='true'");
+        if(createProducer)
+        {
+            session2.createProducer(queue2);
+        }
+
+        if(createConsumer)
+        {
+            session2.createConsumer(queue2);
+        }
+        session2.close();
+
+        //verify the exchange was declared to expectation
+        verifyDeclaredExchange(exchangeName2, false, true);
+    }
+
+    private void verifyDeclaredExchange(String exchangeName, boolean isAutoDelete, boolean isDurable) throws IOException
+    {
+        String exchangeObjectName = _jmxUtils.getExchangeObjectName("test", exchangeName);
+        assertTrue("exchange should exist", _jmxUtils.doesManagedObjectExist(exchangeObjectName));
+        ManagedExchange exchange = _jmxUtils.getManagedExchange(exchangeName);
+        assertEquals(isAutoDelete, exchange.isAutoDelete());
+        assertEquals(isDurable,exchange.isDurable());
+    }
 }
diff --git a/java/systests/src/main/java/org/apache/qpid/test/unit/client/MaxDeliveryCountTest.java b/java/systests/src/main/java/org/apache/qpid/test/unit/client/MaxDeliveryCountTest.java
index bc1eead8b4..40db17f799 100644
--- a/java/systests/src/main/java/org/apache/qpid/test/unit/client/MaxDeliveryCountTest.java
+++ b/java/systests/src/main/java/org/apache/qpid/test/unit/client/MaxDeliveryCountTest.java
@@ -74,19 +74,20 @@ public class MaxDeliveryCountTest extends QpidBrokerTestCase
     public void setUp() throws Exception
     {
         //enable DLQ/maximumDeliveryCount support for all queues at the vhost level
-        setConfigurationProperty("virtualhosts.virtualhost.test.queues.maximumDeliveryCount",
+        setVirtualHostConfigurationProperty("virtualhosts.virtualhost.test.queues.maximumDeliveryCount",
                 String.valueOf(MAX_DELIVERY_COUNT));
-        setConfigurationProperty("virtualhosts.virtualhost.test.queues.deadLetterQueues",
+        setVirtualHostConfigurationProperty("virtualhosts.virtualhost.test.queues.deadLetterQueues",
                                 String.valueOf(true));
 
         //Ensure management is on
-        setConfigurationProperty("management.enabled", "true");
-        setConfigurationProperty("management.ssl.enabled", "false");
+        getBrokerConfiguration().addJmxManagementConfiguration();
 
         // Set client-side flag to allow the server to determine if messages
         // dead-lettered or requeued.
-        setTestClientSystemProperty(ClientProperties.REJECT_BEHAVIOUR_PROP_NAME, "server");
-
+        if (!isBroker010())
+        {
+            setTestClientSystemProperty(ClientProperties.REJECT_BEHAVIOUR_PROP_NAME, "server");
+        }
         super.setUp();
 
         boolean durableSub = isDurSubTest();
diff --git a/java/systests/src/main/java/org/apache/qpid/test/unit/client/channelclose/ChannelCloseOkTest.java b/java/systests/src/main/java/org/apache/qpid/test/unit/client/channelclose/ChannelCloseOkTest.java
deleted file mode 100644
index 1c9ee27b94..0000000000
--- a/java/systests/src/main/java/org/apache/qpid/test/unit/client/channelclose/ChannelCloseOkTest.java
+++ /dev/null
@@ -1,236 +0,0 @@
-/*
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- *
- */
-package org.apache.qpid.test.unit.client.channelclose;
-
-import junit.textui.TestRunner;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import org.apache.qpid.client.AMQConnection;
-import org.apache.qpid.client.AMQQueue;
-import org.apache.qpid.test.utils.QpidBrokerTestCase;
-
-import javax.jms.Destination;
-import javax.jms.ExceptionListener;
-import javax.jms.JMSException;
-import javax.jms.Message;
-import javax.jms.MessageListener;
-import javax.jms.MessageProducer;
-import javax.jms.Session;
-import javax.jms.TextMessage;
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * Due to bizarre exception handling all sessions are closed if you get
- * a channel close request and no exception listener is registered.
- * 

- * JIRA issue IBTBLZ-10. - *

- * Simulate by: - *

- * 0. Create two sessions with no exception listener. - * 1. Publish message to queue/topic that does not exist (wrong routing key). - * 2. This will cause a channel close. - * 3. Since client does not have an exception listener, currently all sessions are - * closed. - */ -public class ChannelCloseOkTest extends QpidBrokerTestCase -{ - private AMQConnection _connection; - private Destination _destination1; - private Destination _destination2; - private Session _session1; - private Session _session2; - private final List _received1 = new ArrayList(); - private final List _received2 = new ArrayList(); - - private static final Logger _log = LoggerFactory.getLogger(ChannelCloseOkTest.class); - - protected void setUp() throws Exception - { - super.setUp(); - - _connection = (AMQConnection) getConnection("guest", "guest"); - - _destination1 = new AMQQueue(_connection, "q1", true); - _destination2 = new AMQQueue(_connection, "q2", true); - _session1 = _connection.createSession(false, Session.AUTO_ACKNOWLEDGE); - _session1.createConsumer(_destination1).setMessageListener(new MessageListener() - { - public void onMessage(Message message) - { - _log.debug("consumer 1 got message [" + getTextMessage(message) + "]"); - synchronized (_received1) - { - _received1.add(message); - _received1.notify(); - } - } - }); - _session2 = _connection.createSession(false, Session.AUTO_ACKNOWLEDGE); - _session2.createConsumer(_destination2).setMessageListener(new MessageListener() - { - public void onMessage(Message message) - { - _log.debug("consumer 2 got message [" + getTextMessage(message) + "]"); - synchronized (_received2) - { - _received2.add(message); - _received2.notify(); - } - } - }); - - _connection.start(); - } - - private String getTextMessage(Message message) - { - TextMessage tm = (TextMessage) message; - try - { - return tm.getText(); - } - catch (JMSException e) - { - return "oops " + e; - } - } - - protected void tearDown() throws Exception - { - closeConnection(); - super.tearDown(); - } - - public void closeConnection() throws JMSException - { - if (_connection != null) - { - _log.info(">>>>>>>>>>>>>>.. closing"); - _connection.close(); - } - } - - public void testWithoutExceptionListener() throws Exception - { - doTest(); - } - - public void testWithExceptionListener() throws Exception - { - _connection.setExceptionListener(new ExceptionListener() - { - public void onException(JMSException jmsException) - { - _log.warn("onException - " + jmsException.getMessage()); - } - }); - - doTest(); - } - - public void doTest() throws Exception - { - // Check both sessions are ok. - sendAndWait(_session1, _destination1, "first", _received1, 1); - sendAndWait(_session2, _destination2, "second", _received2, 1); - assertEquals(1, _received1.size()); - assertEquals(1, _received2.size()); - - // Now send message to incorrect destination on session 1. - Destination destination = new AMQQueue(_connection, "incorrect"); - send(_session1, destination, "third"); // no point waiting as message will never be received. - - // Ensure both sessions are still ok. - // Send a bunch of messages as this give time for the sessions to be erroneously closed. - final int num = 300; - for (int i = 0; i < num; ++i) - { - send(_session1, _destination1, "" + i); - send(_session2, _destination2, "" + i); - } - - waitFor(_received1, num + 1); - waitFor(_received2, num + 1); - - // Note that the third message is never received as it is sent to an incorrect destination. - assertEquals(num + 1, _received1.size()); - assertEquals(num + 1, _received2.size()); - } - - private void sendAndWait(Session session, Destination destination, String message, List received, int count) - throws JMSException, InterruptedException - { - send(session, destination, message); - waitFor(received, count); - } - - private void send(Session session, Destination destination, String message) throws JMSException - { - _log.debug("sending message " + message); - MessageProducer producer1 = session.createProducer(destination); - producer1.send(session.createTextMessage(message)); - } - - private void waitFor(List received, int count) throws InterruptedException - { - long timeout = 20000; - - synchronized (received) - { - long start = System.currentTimeMillis(); - while (received.size() < count) - { - if (System.currentTimeMillis() - start > timeout) - { - fail("timeout expired waiting for messages"); - } - try - { - received.wait(timeout); - } - catch (InterruptedException e) - { - _log.info("Interrupted: " + e); - throw e; - } - - } - } - } - - private static String randomize(String in) - { - return in + System.currentTimeMillis(); - } - - public static void main(String[] args) - { - TestRunner.run(ChannelCloseOkTest.class); - } - - public static junit.framework.Test suite() - { - return new junit.framework.TestSuite(ChannelCloseOkTest.class); - } -} diff --git a/java/systests/src/main/java/org/apache/qpid/test/unit/client/channelclose/ChannelCloseTest.java b/java/systests/src/main/java/org/apache/qpid/test/unit/client/channelclose/ChannelCloseTest.java deleted file mode 100644 index c20eefd987..0000000000 --- a/java/systests/src/main/java/org/apache/qpid/test/unit/client/channelclose/ChannelCloseTest.java +++ /dev/null @@ -1,399 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * - * - */ -package org.apache.qpid.test.unit.client.channelclose; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import org.apache.qpid.AMQException; -import org.apache.qpid.client.AMQConnection; -import org.apache.qpid.client.failover.FailoverException; -import org.apache.qpid.client.protocol.AMQProtocolHandler; -import org.apache.qpid.framing.AMQFrame; -import org.apache.qpid.framing.AMQShortString; -import org.apache.qpid.framing.ChannelCloseOkBody; -import org.apache.qpid.framing.ChannelOpenBody; -import org.apache.qpid.framing.ChannelOpenOkBody; -import org.apache.qpid.framing.ExchangeDeclareBody; -import org.apache.qpid.framing.ExchangeDeclareOkBody; -import org.apache.qpid.jms.ConnectionListener; -import org.apache.qpid.protocol.AMQConstant; -import org.apache.qpid.test.utils.QpidBrokerTestCase; - -import javax.jms.Connection; -import javax.jms.ExceptionListener; -import javax.jms.JMSException; -import javax.jms.Message; -import javax.jms.MessageConsumer; -import javax.jms.MessageProducer; -import javax.jms.Queue; -import javax.jms.Session; -import javax.jms.TextMessage; - -public class ChannelCloseTest extends QpidBrokerTestCase implements ExceptionListener, ConnectionListener -{ - private static final Logger _logger = LoggerFactory.getLogger(ChannelCloseTest.class); - - private Connection _connection; - private Session _session; - private static final long SYNC_TIMEOUT = 500; - private int TEST = 0; - - /** - * Close channel, use chanel with same id ensure error. - * - * This test is only valid for non 0-10 connection . - */ - public void testReusingChannelAfterFullClosure() throws Exception - { - _connection=newConnection(); - - // Create Producer - try - { - _connection.start(); - - createChannelAndTest(1); - - // Cause it to close - try - { - _logger.info("Testing invalid exchange"); - declareExchange(1, "", "name_that_will_lookup_to_null", false); - fail("Exchange name is empty so this should fail "); - } - catch (AMQException e) - { - assertEquals("Exchange should not be found", AMQConstant.NOT_FOUND, e.getErrorCode()); - } - - // Check that - try - { - _logger.info("Testing valid exchange should fail"); - declareExchange(1, "topic", "amq.topic", false); - fail("This should not succeed as the channel should be closed "); - } - catch (AMQException e) - { - if (_logger.isInfoEnabled()) - { - _logger.info("Exception occured was:" + e.getErrorCode()); - } - - assertEquals("Connection should be closed", AMQConstant.CHANNEL_ERROR, e.getErrorCode()); - - _connection=newConnection(); - } - - checkSendingMessage(); - - _session.close(); - _connection.close(); - - } - catch (JMSException e) - { - e.printStackTrace(); - fail(e.getMessage()); - } - } - - /* - close channel and send guff then send ok no errors - REMOVE TEST - The behaviour after server has sent close is undefined. - the server should be free to fail as it may wish to reclaim its resources - immediately after close. - */ - /*public void testSendingMethodsAfterClose() throws Exception - { - // this is testing an 0.8 connection - if(isBroker08()) - { - try - { - _connection=new AMQConnection("amqp://guest:guest@CCTTest/test?brokerlist='" + _brokerlist + "'"); - - ((AMQConnection) _connection).setConnectionListener(this); - - _connection.setExceptionListener(this); - - // Change the StateManager for one that doesn't respond with Close-OKs - AMQStateManager oldStateManager=((AMQConnection) _connection).getProtocolHandler().getStateManager(); - - _session=_connection.createSession(false, Session.CLIENT_ACKNOWLEDGE); - - _connection.start(); - - // Test connection - checkSendingMessage(); - - // Set StateManager to manager that ignores Close-oks - AMQProtocolSession protocolSession= - ((AMQConnection) _connection).getProtocolHandler().getProtocolSession(); - - MethodDispatcher d = protocolSession.getMethodDispatcher(); - - MethodDispatcher wrappedDispatcher = (MethodDispatcher) - Proxy.newProxyInstance(d.getClass().getClassLoader(), - d.getClass().getInterfaces(), - new MethodDispatcherProxyHandler( - (ClientMethodDispatcherImpl) d)); - - protocolSession.setMethodDispatcher(wrappedDispatcher); - - - AMQStateManager newStateManager=new NoCloseOKStateManager(protocolSession); - newStateManager.changeState(oldStateManager.getCurrentState()); - - ((AMQConnection) _connection).getProtocolHandler().setStateManager(newStateManager); - - final int TEST_CHANNEL=1; - _logger.info("Testing Channel(" + TEST_CHANNEL + ") Creation"); - - createChannelAndTest(TEST_CHANNEL); - - // Cause it to close - try - { - _logger.info("Closing Channel - invalid exchange"); - declareExchange(TEST_CHANNEL, "", "name_that_will_lookup_to_null", false); - fail("Exchange name is empty so this should fail "); - } - catch (AMQException e) - { - assertEquals("Exchange should not be found", AMQConstant.NOT_FOUND, e.getErrorCode()); - } - - try - { - // Send other methods that should be ignored - // send them no wait as server will ignore them - _logger.info("Tested known exchange - should ignore"); - declareExchange(TEST_CHANNEL, "topic", "amq.topic", true); - - _logger.info("Tested known invalid exchange - should ignore"); - declareExchange(TEST_CHANNEL, "", "name_that_will_lookup_to_null", true); - - _logger.info("Tested known invalid exchange - should ignore"); - declareExchange(TEST_CHANNEL, "", "name_that_will_lookup_to_null", true); - - // Send sync .. server will igore and timy oue - _logger.info("Tested known invalid exchange - should ignore"); - declareExchange(TEST_CHANNEL, "", "name_that_will_lookup_to_null", false); - } - catch (AMQTimeoutException te) - { - assertEquals("Request should timeout", AMQConstant.REQUEST_TIMEOUT, te.getErrorCode()); - } - catch (AMQException e) - { - fail("This should not fail as all requests should be ignored"); - } - - _logger.info("Sending Close"); - // Send Close-ok - sendClose(TEST_CHANNEL); - - _logger.info("Re-opening channel"); - - createChannelAndTest(TEST_CHANNEL); - - // Test connection is still ok - - checkSendingMessage(); - - } - catch (JMSException e) - { - e.printStackTrace(); - fail(e.getMessage()); - } - catch (AMQException e) - { - fail(e.getMessage()); - - } - catch (URLSyntaxException e) - { - fail(e.getMessage()); - } - finally - { - try - { - _session.close(); - _connection.close(); - } - catch (JMSException e) - { - e.printStackTrace(); - fail(e.getMessage()); - } - } - } - } -*/ - private void createChannelAndTest(int channel) throws FailoverException - { - // Create A channel - try - { - createChannel(channel); - } - catch (AMQException e) - { - fail(e.getMessage()); - } - - // Test it is ok - try - { - declareExchange(channel, "topic", "amq.topic", false); - _logger.info("Tested known exchange"); - } - catch (AMQException e) - { - fail("This should not fail as this is the default exchange details"); - } - } - - private void sendClose(int channel) - { - ChannelCloseOkBody body = - ((AMQConnection) _connection).getProtocolHandler().getMethodRegistry().createChannelCloseOkBody(); - AMQFrame frame = body.generateFrame(channel); - - ((AMQConnection) _connection).getProtocolHandler().writeFrame(frame); - } - - private void checkSendingMessage() throws JMSException - { - TEST++; - _logger.info("Test creating producer which will use channel id 1"); - - Queue queue = _session.createQueue("CCT_test_validation_queue" + TEST); - - MessageConsumer consumer = _session.createConsumer(queue); - - MessageProducer producer = _session.createProducer(queue); - - final String MESSAGE = "CCT_Test_Message"; - producer.send(_session.createTextMessage(MESSAGE)); - - Message msg = consumer.receive(2000); - - assertNotNull("Received messages should not be null.", msg); - assertEquals("Message received not what we sent", MESSAGE, ((TextMessage) msg).getText()); - } - - private Connection newConnection() - { - Connection connection = null; - try - { - connection = getConnection(); - - ((AMQConnection) connection).setConnectionListener(this); - - _session = connection.createSession(false, Session.CLIENT_ACKNOWLEDGE); - - connection.start(); - - } - catch (Exception e) - { - fail("Creating new connection when:" + e.getMessage()); - } - - return connection; - } - - private void declareExchange(int channelId, String _type, String _name, boolean nowait) - throws AMQException, FailoverException - { - ExchangeDeclareBody body = - ((AMQConnection) _connection).getProtocolHandler() - .getMethodRegistry() - .createExchangeDeclareBody(0, - new AMQShortString(_name), - new AMQShortString(_type), - true, - false, - false, - false, - nowait, - null); - AMQFrame exchangeDeclare = body.generateFrame(channelId); - AMQProtocolHandler protocolHandler = ((AMQConnection) _connection).getProtocolHandler(); - - - if (nowait) - { - protocolHandler.writeFrame(exchangeDeclare); - } - else - { - protocolHandler.syncWrite(exchangeDeclare, ExchangeDeclareOkBody.class, SYNC_TIMEOUT); - } - -// return null; -// } -// }, (AMQConnection)_connection).execute(); - - } - - private void createChannel(int channelId) throws AMQException, FailoverException - { - ChannelOpenBody body = - ((AMQConnection) _connection).getProtocolHandler().getMethodRegistry().createChannelOpenBody(null); - - ((AMQConnection) _connection).getProtocolHandler().syncWrite(body.generateFrame(channelId), // outOfBand - ChannelOpenOkBody.class); - - } - - public void onException(JMSException jmsException) - { - // _logger.info("CCT" + jmsException); - fail(jmsException.getMessage()); - } - - public void bytesSent(long count) - { } - - public void bytesReceived(long count) - { } - - public boolean preFailover(boolean redirect) - { - return false; - } - - public boolean preResubscribe() - { - return false; - } - - public void failoverComplete() - { } - -} diff --git a/java/systests/src/main/java/org/apache/qpid/test/unit/close/JavaServerCloseRaceConditionTest.java b/java/systests/src/main/java/org/apache/qpid/test/unit/close/JavaServerCloseRaceConditionTest.java index f2387fa99b..b43fe35a09 100644 --- a/java/systests/src/main/java/org/apache/qpid/test/unit/close/JavaServerCloseRaceConditionTest.java +++ b/java/systests/src/main/java/org/apache/qpid/test/unit/close/JavaServerCloseRaceConditionTest.java @@ -21,7 +21,7 @@ package org.apache.qpid.test.unit.close; import org.apache.qpid.client.AMQConnection; -import org.apache.qpid.client.AMQSession; +import org.apache.qpid.client.AMQSession_0_8; import org.apache.qpid.framing.AMQFrame; import org.apache.qpid.framing.AMQShortString; import org.apache.qpid.framing.ExchangeDeclareBody; @@ -81,7 +81,7 @@ public class JavaServerCloseRaceConditionTest extends QpidBrokerTestCase AMQConnection connection = (AMQConnection) getConnection(); - AMQSession session = (AMQSession) connection.createSession(false, Session.AUTO_ACKNOWLEDGE); + AMQSession_0_8 session = (AMQSession_0_8) connection.createSession(false, Session.AUTO_ACKNOWLEDGE); // Set no wait true so that we block the connection // Also set a different exchange class string so the attempt to declare diff --git a/java/systests/src/main/java/org/apache/qpid/test/unit/topic/DurableSubscriptionTest.java b/java/systests/src/main/java/org/apache/qpid/test/unit/topic/DurableSubscriptionTest.java index a07e531b98..a9ac028af6 100644 --- a/java/systests/src/main/java/org/apache/qpid/test/unit/topic/DurableSubscriptionTest.java +++ b/java/systests/src/main/java/org/apache/qpid/test/unit/topic/DurableSubscriptionTest.java @@ -73,7 +73,7 @@ public class DurableSubscriptionTest extends QpidBrokerTestCase public void setUp() throws Exception { - setConfigurationProperty("management.enabled", "true"); + getBrokerConfiguration().addJmxManagementConfiguration(); _jmxConnected=false; super.setUp(); } diff --git a/java/systests/src/main/java/org/apache/qpid/test/unit/transacted/TransactionTimeoutDisabledTest.java b/java/systests/src/main/java/org/apache/qpid/test/unit/transacted/TransactionTimeoutDisabledTest.java index fd8beffbe6..d93c7a2e71 100644 --- a/java/systests/src/main/java/org/apache/qpid/test/unit/transacted/TransactionTimeoutDisabledTest.java +++ b/java/systests/src/main/java/org/apache/qpid/test/unit/transacted/TransactionTimeoutDisabledTest.java @@ -29,7 +29,7 @@ public class TransactionTimeoutDisabledTest extends TransactionTimeoutTestCase protected void configure() throws Exception { // Setup housekeeping every second - setConfigurationProperty("virtualhosts.virtualhost." + VIRTUALHOST + ".housekeeping.checkPeriod", "100"); + setVirtualHostConfigurationProperty("virtualhosts.virtualhost." + VIRTUALHOST + ".housekeeping.checkPeriod", "100"); // No transaction timeout configuration. } diff --git a/java/systests/src/main/java/org/apache/qpid/test/unit/transacted/TransactionTimeoutTest.java b/java/systests/src/main/java/org/apache/qpid/test/unit/transacted/TransactionTimeoutTest.java index b11df5a2a0..4dc26847da 100644 --- a/java/systests/src/main/java/org/apache/qpid/test/unit/transacted/TransactionTimeoutTest.java +++ b/java/systests/src/main/java/org/apache/qpid/test/unit/transacted/TransactionTimeoutTest.java @@ -39,29 +39,29 @@ public class TransactionTimeoutTest extends TransactionTimeoutTestCase protected void configure() throws Exception { - // Setup housekeeping every second - setConfigurationProperty("virtualhosts.virtualhost." + VIRTUALHOST + ".housekeeping.checkPeriod", "100"); + // Setup housekeeping every 100ms + setVirtualHostConfigurationProperty("virtualhosts.virtualhost." + VIRTUALHOST + ".housekeeping.checkPeriod", "100"); if (getName().contains("ProducerIdle")) { - setConfigurationProperty("virtualhosts.virtualhost." + VIRTUALHOST + ".transactionTimeout.openWarn", "0"); - setConfigurationProperty("virtualhosts.virtualhost." + VIRTUALHOST + ".transactionTimeout.openClose", "0"); - setConfigurationProperty("virtualhosts.virtualhost." + VIRTUALHOST + ".transactionTimeout.idleWarn", "500"); - setConfigurationProperty("virtualhosts.virtualhost." + VIRTUALHOST + ".transactionTimeout.idleClose", "1500"); + setVirtualHostConfigurationProperty("virtualhosts.virtualhost." + VIRTUALHOST + ".transactionTimeout.openWarn", "0"); + setVirtualHostConfigurationProperty("virtualhosts.virtualhost." + VIRTUALHOST + ".transactionTimeout.openClose", "0"); + setVirtualHostConfigurationProperty("virtualhosts.virtualhost." + VIRTUALHOST + ".transactionTimeout.idleWarn", "500"); + setVirtualHostConfigurationProperty("virtualhosts.virtualhost." + VIRTUALHOST + ".transactionTimeout.idleClose", "1500"); } else if (getName().contains("ProducerOpen")) { - setConfigurationProperty("virtualhosts.virtualhost." + VIRTUALHOST + ".transactionTimeout.openWarn", "1000"); - setConfigurationProperty("virtualhosts.virtualhost." + VIRTUALHOST + ".transactionTimeout.openClose", "2000"); - setConfigurationProperty("virtualhosts.virtualhost." + VIRTUALHOST + ".transactionTimeout.idleWarn", "0"); - setConfigurationProperty("virtualhosts.virtualhost." + VIRTUALHOST + ".transactionTimeout.idleClose", "0"); + setVirtualHostConfigurationProperty("virtualhosts.virtualhost." + VIRTUALHOST + ".transactionTimeout.openWarn", "1000"); + setVirtualHostConfigurationProperty("virtualhosts.virtualhost." + VIRTUALHOST + ".transactionTimeout.openClose", "2000"); + setVirtualHostConfigurationProperty("virtualhosts.virtualhost." + VIRTUALHOST + ".transactionTimeout.idleWarn", "0"); + setVirtualHostConfigurationProperty("virtualhosts.virtualhost." + VIRTUALHOST + ".transactionTimeout.idleClose", "0"); } else { - setConfigurationProperty("virtualhosts.virtualhost." + VIRTUALHOST + ".transactionTimeout.openWarn", "1000"); - setConfigurationProperty("virtualhosts.virtualhost." + VIRTUALHOST + ".transactionTimeout.openClose", "2000"); - setConfigurationProperty("virtualhosts.virtualhost." + VIRTUALHOST + ".transactionTimeout.idleWarn", "500"); - setConfigurationProperty("virtualhosts.virtualhost." + VIRTUALHOST + ".transactionTimeout.idleClose", "1000"); + setVirtualHostConfigurationProperty("virtualhosts.virtualhost." + VIRTUALHOST + ".transactionTimeout.openWarn", "1000"); + setVirtualHostConfigurationProperty("virtualhosts.virtualhost." + VIRTUALHOST + ".transactionTimeout.openClose", "2000"); + setVirtualHostConfigurationProperty("virtualhosts.virtualhost." + VIRTUALHOST + ".transactionTimeout.idleWarn", "500"); + setVirtualHostConfigurationProperty("virtualhosts.virtualhost." + VIRTUALHOST + ".transactionTimeout.idleClose", "1000"); } } diff --git a/java/systests/src/main/java/org/apache/qpid/test/unit/transacted/TransactionTimeoutTestCase.java b/java/systests/src/main/java/org/apache/qpid/test/unit/transacted/TransactionTimeoutTestCase.java index e2b0f00ee4..721dc027c6 100644 --- a/java/systests/src/main/java/org/apache/qpid/test/unit/transacted/TransactionTimeoutTestCase.java +++ b/java/systests/src/main/java/org/apache/qpid/test/unit/transacted/TransactionTimeoutTestCase.java @@ -23,17 +23,13 @@ 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.AMQConnectionURL; -import org.apache.qpid.client.AMQQueue; import org.apache.qpid.client.AMQSession; -import org.apache.qpid.framing.AMQShortString; -import org.apache.qpid.jms.ConnectionURL; -import org.apache.qpid.jms.Session; +import org.apache.qpid.configuration.ClientProperties; import org.apache.qpid.protocol.AMQConstant; import org.apache.qpid.test.utils.QpidBrokerTestCase; import org.apache.qpid.util.LogMonitor; +import javax.jms.Connection; import javax.jms.DeliveryMode; import javax.jms.ExceptionListener; import javax.jms.JMSException; @@ -41,6 +37,7 @@ import javax.jms.Message; import javax.jms.MessageConsumer; import javax.jms.MessageProducer; import javax.jms.Queue; +import javax.jms.Session; import javax.jms.TextMessage; import java.util.List; import java.util.concurrent.CountDownLatch; @@ -61,7 +58,7 @@ public abstract class TransactionTimeoutTestCase extends QpidBrokerTestCase impl public static final String OPEN = "Open"; protected LogMonitor _monitor; - protected AMQConnection _con; + protected Connection _con; protected Session _psession, _csession; protected Queue _queue; protected MessageConsumer _consumer; @@ -89,16 +86,14 @@ public abstract class TransactionTimeoutTestCase extends QpidBrokerTestCase impl super.setUp(); // Connect to broker - String broker = ("tcp://localhost:" + DEFAULT_PORT); - ConnectionURL url = new AMQConnectionURL("amqp://guest:guest@clientid/test?brokerlist='" + broker + "'&maxprefetch='1'"); - _con = (AMQConnection) getConnection(url); + setTestClientSystemProperty(ClientProperties.MAX_PREFETCH_PROP_NAME, String.valueOf(1)); + _con = getConnection(); _con.setExceptionListener(this); _con.start(); // Create queue Session qsession = _con.createSession(true, Session.SESSION_TRANSACTED); - AMQShortString queueName = new AMQShortString("test"); - _queue = new AMQQueue(qsession.getDefaultQueueExchangeName(), queueName, queueName, false, true); + _queue = qsession.createQueue(getTestQueueName()); qsession.close(); // Create producer and consumer diff --git a/java/systests/src/main/java/org/apache/qpid/test/utils/BrokerCommandHelper.java b/java/systests/src/main/java/org/apache/qpid/test/utils/BrokerCommandHelper.java new file mode 100644 index 0000000000..12d286f822 --- /dev/null +++ b/java/systests/src/main/java/org/apache/qpid/test/utils/BrokerCommandHelper.java @@ -0,0 +1,79 @@ +/* Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT 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.utils; + +import java.io.File; +import java.util.Arrays; +import java.util.LinkedList; +import java.util.List; + +/** + * Generates the command to start a broker by substituting the tokens + * in the provided broker command. + * + * The command is returned as a list so that it can be easily used by a + * {@link java.lang.ProcessBuilder}. + */ +public class BrokerCommandHelper +{ + private final List _brokerCommandTemplateAsList; + + public BrokerCommandHelper(String brokerCommandTemplate) + { + _brokerCommandTemplateAsList = new LinkedList(Arrays.asList(brokerCommandTemplate.split("\\s+"))); + } + + public String[] getBrokerCommand( int port, String storePath, String storeType, File logConfigFile) + { + String[] command = new String[_brokerCommandTemplateAsList.size()]; + int i=0; + for (String commandPart : _brokerCommandTemplateAsList) + { + command[i] = commandPart + .replace("@PORT", "" + port) + .replace("@STORE_PATH", storePath) + .replace("@STORE_TYPE", storeType) + .replace("@LOG_CONFIG_FILE", '"' + logConfigFile.getAbsolutePath() + '"'); + i++; + } + return command; + } + + private int getBrokerCommandLogOptionIndex(String logOption) + { + int logOptionIndex = _brokerCommandTemplateAsList.indexOf(logOption); + if(logOptionIndex == -1) + { + throw new RuntimeException("Could not find option " + logOption + " in " + _brokerCommandTemplateAsList); + } + return logOptionIndex; + } + + + public void removeBrokerCommandLog4JFile() + { + String logOption = "-l"; + int logOptionIndex = getBrokerCommandLogOptionIndex(logOption); + if (logOptionIndex + 1 >= _brokerCommandTemplateAsList.size()) + { + throw new RuntimeException("Could not find log config location"); + } + _brokerCommandTemplateAsList.remove(logOptionIndex); + _brokerCommandTemplateAsList.remove(logOptionIndex); + } +} diff --git a/java/systests/src/main/java/org/apache/qpid/test/utils/BrokerCommandHelperTest.java b/java/systests/src/main/java/org/apache/qpid/test/utils/BrokerCommandHelperTest.java new file mode 100644 index 0000000000..f0bcea8e6e --- /dev/null +++ b/java/systests/src/main/java/org/apache/qpid/test/utils/BrokerCommandHelperTest.java @@ -0,0 +1,61 @@ +/* Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.qpid.test.utils; + +import static org.mockito.Mockito.*; + +import java.io.File; + +public class BrokerCommandHelperTest extends QpidTestCase +{ + private BrokerCommandHelper _brokerCommandHelper = new BrokerCommandHelper("qpid -p @PORT -sp @STORE_PATH -st @STORE_TYPE -l @LOG_CONFIG_FILE"); + + private File logConfigFile = mock(File.class); + + @Override + public void setUp() + { + when(logConfigFile.getAbsolutePath()).thenReturn("log Config File"); + } + + public void testGetBrokerCommand() + { + String[] brokerCommand = _brokerCommandHelper.getBrokerCommand(1, "configFile", "json", logConfigFile); + + String[] expected = { "qpid", "-p", "1", "-sp", "configFile", "-st", "json", "-l", "\"log Config File\"" }; + assertEquals("Unexpected broker command", 9, brokerCommand.length); + for (int i = 0; i < expected.length; i++) + { + assertEquals("Unexpected command part value at " + i,expected[i], brokerCommand[i] ); + } + } + + public void testRemoveBrokerCommandLog4JFile() + { + _brokerCommandHelper.removeBrokerCommandLog4JFile(); + String[] brokerCommand = _brokerCommandHelper.getBrokerCommand(1, "configFile", "json", logConfigFile); + + String[] expected = { "qpid", "-p", "1", "-sp", "configFile", "-st", "json" }; + assertEquals("Unexpected broker command", 7, brokerCommand.length); + for (int i = 0; i < expected.length; i++) + { + assertEquals("Unexpected command part value at " + i,expected[i], brokerCommand[i] ); + } + } + +} diff --git a/java/systests/src/main/java/org/apache/qpid/test/utils/InternalBrokerHolder.java b/java/systests/src/main/java/org/apache/qpid/test/utils/InternalBrokerHolder.java index a71a4ef517..8bad73d0ea 100644 --- a/java/systests/src/main/java/org/apache/qpid/test/utils/InternalBrokerHolder.java +++ b/java/systests/src/main/java/org/apache/qpid/test/utils/InternalBrokerHolder.java @@ -20,9 +20,6 @@ */ package org.apache.qpid.test.utils; -import java.lang.management.ManagementFactory; -import java.lang.management.ThreadInfo; -import java.lang.management.ThreadMXBean; import java.util.Set; import org.apache.log4j.Logger; @@ -82,28 +79,7 @@ public class InternalBrokerHolder implements BrokerHolder @Override public String dumpThreads() { - ThreadMXBean threadMXBean = ManagementFactory.getThreadMXBean(); - ThreadInfo[] threadInfos = threadMXBean.dumpAllThreads(true, true); - StringBuilder dump = new StringBuilder(); - dump.append(String.format("%n")); - for (ThreadInfo threadInfo : threadInfos) - { - dump.append(threadInfo); - } - - long[] deadLocks = threadMXBean.findDeadlockedThreads(); - if (deadLocks != null && deadLocks.length > 0) - { - ThreadInfo[] deadlockedThreads = threadMXBean.getThreadInfo(deadLocks); - dump.append(String.format("%n")); - dump.append("Deadlock is detected!"); - dump.append(String.format("%n")); - for (ThreadInfo threadInfo : deadlockedThreads) - { - dump.append(threadInfo); - } - } - return dump.toString(); + return TestUtils.dumpThreads(); } @Override diff --git a/java/systests/src/main/java/org/apache/qpid/test/utils/JMXTestUtils.java b/java/systests/src/main/java/org/apache/qpid/test/utils/JMXTestUtils.java index 43b80b45fb..6e6e3271f0 100644 --- a/java/systests/src/main/java/org/apache/qpid/test/utils/JMXTestUtils.java +++ b/java/systests/src/main/java/org/apache/qpid/test/utils/JMXTestUtils.java @@ -24,7 +24,6 @@ import junit.framework.TestCase; import org.apache.commons.configuration.ConfigurationException; import org.apache.qpid.management.common.JMXConnnectionFactory; -import org.apache.qpid.management.common.mbeans.ConfigurationManagement; import org.apache.qpid.management.common.mbeans.LoggingManagement; import org.apache.qpid.management.common.mbeans.ManagedBroker; import org.apache.qpid.management.common.mbeans.ManagedConnection; @@ -32,6 +31,8 @@ import org.apache.qpid.management.common.mbeans.ManagedExchange; import org.apache.qpid.management.common.mbeans.ManagedQueue; import org.apache.qpid.management.common.mbeans.ServerInformation; import org.apache.qpid.management.common.mbeans.UserManagement; +import org.apache.qpid.server.model.Plugin; +import org.apache.qpid.server.plugin.PluginFactory; import javax.management.InstanceNotFoundException; import javax.management.JMException; @@ -46,7 +47,9 @@ import javax.management.ObjectName; import javax.management.remote.JMXConnector; import java.io.IOException; import java.util.ArrayList; +import java.util.HashMap; import java.util.List; +import java.util.Map; import java.util.Set; /** @@ -78,7 +81,7 @@ public class JMXTestUtils public void setUp() throws IOException, ConfigurationException, Exception { - _test.setConfigurationProperty("management.enabled", "true"); + _test.getBrokerConfiguration().addJmxManagementConfiguration(); } public void open() throws Exception @@ -287,9 +290,7 @@ public class JMXTestUtils public ObjectName getQueueObjectName(String virtualHostName, String queue) { // Get the name of the test manager - String query = "org.apache.qpid:type=VirtualHost.Queue,VirtualHost=" - + ObjectName.quote(virtualHostName) + ",name=" - + ObjectName.quote(queue) + ",*"; + String query = getQueueObjectNameString(virtualHostName, queue); Set objectNames = queryObjects(query); @@ -302,32 +303,20 @@ public class JMXTestUtils return objectName; } + public String getQueueObjectNameString(String virtualHostName, String queue) { + return "org.apache.qpid:type=VirtualHost.Queue,VirtualHost=" + + ObjectName.quote(virtualHostName) + ",name=" + + ObjectName.quote(queue) + ",*"; + } + /** - * Retrive the ObjectName for the given Exchange on a VirtualHost. - * - * This is then used to create a proxy to the ManagedExchange MBean. - * - * @param virtualHostName the VirtualHost the Exchange is on - * @param exchange the Exchange to retireve e.g. 'direct' - * @return the ObjectName for the given Exchange on the VirtualHost + * Generate the ObjectName for the given Exchange on a VirtualHost. */ - @SuppressWarnings("static-access") - public ObjectName getExchangeObjectName(String virtualHostName, String exchange) + public String getExchangeObjectName(String virtualHostName, String exchange) { - // Get the name of the test manager - String query = "org.apache.qpid:type=VirtualHost.Exchange,VirtualHost=" + return "org.apache.qpid:type=VirtualHost.Exchange,VirtualHost=" + ObjectName.quote(virtualHostName) + ",name=" + ObjectName.quote(exchange) + ",*"; - - Set objectNames = queryObjects(query); - - _test.assertNotNull("Null ObjectName Set returned", objectNames); - _test.assertEquals("Incorrect number of exchange with name '" + exchange + "' returned", 1, objectNames.size()); - - // We have verified we have only one value in objectNames so return it - ObjectName objectName = objectNames.iterator().next(); - _test.getLogger().info("Loading: " + objectName); - return objectName; } @SuppressWarnings("static-access") @@ -343,7 +332,7 @@ public class JMXTestUtils return getManagedObject(managedClass, objectName); } - public boolean isManagedObjectExist(String query) + public boolean doesManagedObjectExist(String query) { return !queryObjects(query).isEmpty(); } @@ -373,9 +362,20 @@ public class JMXTestUtils return getManagedObject(ManagedBroker.class, getVirtualHostManagerObjectName(virtualHost)); } + @SuppressWarnings("static-access") public ManagedExchange getManagedExchange(String exchangeName) { - ObjectName objectName = getExchangeObjectName("test", exchangeName); + String query = getExchangeObjectName("test", exchangeName); + + Set objectNames = queryObjects(query); + + _test.assertNotNull("Null ObjectName Set returned", objectNames); + _test.assertEquals("Incorrect number of exchange with name '" + exchangeName + "' returned", 1, objectNames.size()); + + // We have verified we have only one value in objectNames so return an mbean proxy for it + ObjectName objectName = objectNames.iterator().next(); + _test.getLogger().info("Loading: " + objectName); + return MBeanServerInvocationHandler.newProxyInstance(_mbsc, objectName, ManagedExchange.class, false); } @@ -391,12 +391,6 @@ public class JMXTestUtils return getManagedObject(LoggingManagement.class, objectName); } - public ConfigurationManagement getConfigurationManagement() throws MalformedObjectNameException - { - ObjectName objectName = new ObjectName("org.apache.qpid:type=ConfigurationManagement,name=ConfigurationManagement"); - return getManagedObject(ConfigurationManagement.class, objectName); - } - public UserManagement getUserManagement() throws MalformedObjectNameException { ObjectName objectName = new ObjectName("org.apache.qpid:type=UserManagement,name=UserManagement"); diff --git a/java/systests/src/main/java/org/apache/qpid/test/utils/QpidBrokerTestCase.java b/java/systests/src/main/java/org/apache/qpid/test/utils/QpidBrokerTestCase.java old mode 100644 new mode 100755 index aa909a6674..d36f57171f --- a/java/systests/src/main/java/org/apache/qpid/test/utils/QpidBrokerTestCase.java +++ b/java/systests/src/main/java/org/apache/qpid/test/utils/QpidBrokerTestCase.java @@ -19,18 +19,17 @@ package org.apache.qpid.test.utils; import java.io.File; import java.io.FileOutputStream; -import java.io.IOException; import java.io.PrintStream; -import java.net.MalformedURLException; -import java.net.URL; +import java.net.URI; +import java.net.URISyntaxException; import java.util.ArrayList; +import java.util.Collection; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; import java.util.concurrent.TimeUnit; - import javax.jms.BytesMessage; import javax.jms.Connection; import javax.jms.Destination; @@ -45,32 +44,34 @@ import javax.jms.Session; import javax.jms.StreamMessage; import javax.jms.TextMessage; import javax.jms.Topic; +import javax.naming.Context; import javax.naming.InitialContext; import javax.naming.NamingException; - import org.apache.commons.configuration.ConfigurationException; import org.apache.commons.configuration.XMLConfiguration; import org.apache.commons.lang.StringUtils; import org.apache.log4j.Logger; import org.apache.qpid.AMQException; import org.apache.qpid.client.AMQConnectionFactory; +import org.apache.qpid.client.AMQConnectionURL; import org.apache.qpid.client.AMQQueue; import org.apache.qpid.client.AMQTopic; import org.apache.qpid.exchange.ExchangeDefaults; import org.apache.qpid.jms.BrokerDetails; import org.apache.qpid.jms.ConnectionURL; -import org.apache.qpid.management.common.mbeans.ConfigurationManagement; import org.apache.qpid.server.Broker; import org.apache.qpid.server.BrokerOptions; -import org.apache.qpid.server.ProtocolExclusion; -import org.apache.qpid.server.ProtocolInclusion; -import org.apache.qpid.server.configuration.ServerConfiguration; +import org.apache.qpid.server.configuration.BrokerProperties; +import org.apache.qpid.server.model.Port; +import org.apache.qpid.server.model.VirtualHost; import org.apache.qpid.server.protocol.AmqpProtocolVersion; +import org.apache.qpid.server.store.MemoryMessageStore; import org.apache.qpid.server.store.MessageStoreConstants; +import org.apache.qpid.server.store.MessageStoreCreator; +import org.apache.qpid.server.store.MessageStoreFactory; import org.apache.qpid.server.store.derby.DerbyMessageStore; import org.apache.qpid.url.URLSyntaxException; import org.apache.qpid.util.FileUtils; -import org.apache.qpid.util.LogMonitor; /** * Qpid base class for system testing test cases. @@ -80,7 +81,7 @@ public class QpidBrokerTestCase extends QpidTestCase public enum BrokerType { EXTERNAL /** Test case relies on a Broker started independently of the test-suite */, - INTERNAL /** Test case starts an embedded broker within this JVM */, + INTERNAL /** Test case starts an embedded broker within this JVM */, SPAWNED /** Test case spawns a new broker as a separate process */ } @@ -88,9 +89,9 @@ public class QpidBrokerTestCase extends QpidTestCase public static final String GUEST_PASSWORD = "guest"; protected final static String QpidHome = System.getProperty("QPID_HOME"); - protected File _configFile = new File(System.getProperty("broker.config")); - protected File _logConfigFile = new File(System.getProperty("log4j.configuration")); - + private final File _configFile = new File(System.getProperty("broker.config")); + private File _logConfigFile; + protected final String _brokerStoreType = System.getProperty("broker.config-store-type", "json"); protected static final Logger _logger = Logger.getLogger(QpidBrokerTestCase.class); protected static final int LOGMONITOR_TIMEOUT = 5000; @@ -98,7 +99,7 @@ public class QpidBrokerTestCase extends QpidTestCase private Map _propertiesSetForBroker = new HashMap(); - private XMLConfiguration _testConfiguration = new XMLConfiguration(); + private Map _brokerConfigurations; private XMLConfiguration _testVirtualhosts = new XMLConfiguration(); protected static final String INDEX = "index"; @@ -106,24 +107,31 @@ public class QpidBrokerTestCase extends QpidTestCase private static final String DEFAULT_INITIAL_CONTEXT = "org.apache.qpid.jndi.PropertiesFileInitialContextFactory"; + private static Map supportedStoresClassToTypeMapping = new HashMap(); + static { - String initialContext = System.getProperty(InitialContext.INITIAL_CONTEXT_FACTORY); + String initialContext = System.getProperty(Context.INITIAL_CONTEXT_FACTORY); if (initialContext == null || initialContext.length() == 0) { - System.setProperty(InitialContext.INITIAL_CONTEXT_FACTORY, DEFAULT_INITIAL_CONTEXT); + System.setProperty(Context.INITIAL_CONTEXT_FACTORY, DEFAULT_INITIAL_CONTEXT); + } + + MessageStoreCreator messageStoreCreator = new MessageStoreCreator(); + Collection factories = messageStoreCreator.getFactories(); + for (MessageStoreFactory messageStoreFactory : factories) + { + supportedStoresClassToTypeMapping.put(messageStoreFactory.createMessageStore().getClass().getName(), messageStoreFactory.getType()); } } // system properties private static final String TEST_VIRTUALHOSTS = "test.virtualhosts"; - private static final String TEST_CONFIG = "test.config"; private static final String BROKER_LANGUAGE = "broker.language"; protected static final String BROKER_TYPE = "broker.type"; private static final String BROKER_COMMAND = "broker.command"; private static final String BROKER_CLEAN_BETWEEN_TESTS = "broker.clean.between.tests"; - private static final String BROKER_EXISTING_QPID_WORK = "broker.existing.qpid.work"; private static final String BROKER_VERSION = "broker.version"; protected static final String BROKER_READY = "broker.ready"; private static final String BROKER_STOPPED = "broker.stopped"; @@ -131,8 +139,14 @@ public class QpidBrokerTestCase extends QpidTestCase private static final String BROKER_LOG_INTERLEAVE = "broker.log.interleave"; private static final String BROKER_LOG_PREFIX = "broker.log.prefix"; private static final String BROKER_PERSITENT = "broker.persistent"; - public static final String BROKER_PROTOCOL_EXCLUDES = "broker.protocol.excludes"; - public static final String BROKER_PROTOCOL_INCLUDES = "broker.protocol.includes"; + public static final String PROFILE_USE_SSL = "profile.use_ssl"; + + public static final int DEFAULT_PORT_VALUE = 5672; + public static final int DEFAULT_SSL_PORT_VALUE = 5671; + public static final int DEFAULT_JMXPORT_REGISTRYSERVER = 8999; + public static final int JMXPORT_CONNECTORSERVER_OFFSET = 100; + public static final int DEFAULT_HTTP_MANAGEMENT_PORT = 8080; + public static final int DEFAULT_HTTPS_MANAGEMENT_PORT = 8443; // values protected static final String JAVA = "java"; @@ -140,15 +154,15 @@ public class QpidBrokerTestCase extends QpidTestCase protected static final String QPID_HOME = "QPID_HOME"; - public static final int DEFAULT_VM_PORT = 1; - public static final int DEFAULT_PORT = Integer.getInteger("test.port", ServerConfiguration.DEFAULT_PORT); + public static final int DEFAULT_PORT = Integer.getInteger("test.port", DEFAULT_PORT_VALUE); public static final int FAILING_PORT = Integer.parseInt(System.getProperty("test.port.alt")); - public static final int DEFAULT_MANAGEMENT_PORT = Integer.getInteger("test.mport", ServerConfiguration.DEFAULT_JMXPORT_REGISTRYSERVER); - public static final int DEFAULT_SSL_PORT = Integer.getInteger("test.port.ssl", ServerConfiguration.DEFAULT_SSL_PORT); + public static final int DEFAULT_MANAGEMENT_PORT = Integer.getInteger("test.mport", DEFAULT_JMXPORT_REGISTRYSERVER); + public static final int DEFAULT_SSL_PORT = Integer.getInteger("test.port.ssl", DEFAULT_SSL_PORT_VALUE); protected String _brokerLanguage = System.getProperty(BROKER_LANGUAGE, JAVA); protected BrokerType _brokerType = BrokerType.valueOf(System.getProperty(BROKER_TYPE, "").toUpperCase()); - protected String _brokerCommand = System.getProperty(BROKER_COMMAND); + + protected BrokerCommandHelper _brokerCommandHelper = new BrokerCommandHelper(System.getProperty(BROKER_COMMAND)); private Boolean _brokerCleanBetweenTests = Boolean.getBoolean(BROKER_CLEAN_BETWEEN_TESTS); private final AmqpProtocolVersion _brokerVersion = AmqpProtocolVersion.valueOf(System.getProperty(BROKER_VERSION, "")); protected String _output = System.getProperty(TEST_OUTPUT, System.getProperty("java.io.tmpdir")); @@ -190,14 +204,67 @@ public class QpidBrokerTestCase extends QpidTestCase } private MessageType _messageType = MessageType.TEXT; - public QpidBrokerTestCase(String name) - { - super(name); - } - public QpidBrokerTestCase() { super(); + _brokerConfigurations = new HashMap(); + initialiseLogConfigFile(); + } + + public TestBrokerConfiguration getBrokerConfiguration(int port) + { + int actualPort = getPort(port); + + synchronized (_brokerConfigurations) + { + TestBrokerConfiguration configuration = _brokerConfigurations.get(actualPort); + if (configuration == null) + { + configuration = createBrokerConfiguration(actualPort); + } + return configuration; + } + } + + public TestBrokerConfiguration getBrokerConfiguration() + { + return getBrokerConfiguration(DEFAULT_PORT); + } + + public TestBrokerConfiguration createBrokerConfiguration(int port) + { + int actualPort = getPort(port); + TestBrokerConfiguration configuration = new TestBrokerConfiguration(System.getProperty(_brokerStoreType), _configFile.getAbsolutePath()); + synchronized (_brokerConfigurations) + { + _brokerConfigurations.put(actualPort, configuration); + } + if (actualPort != DEFAULT_PORT) + { + configuration.setObjectAttribute(TestBrokerConfiguration.ENTRY_NAME_AMQP_PORT, Port.PORT, actualPort); + configuration.setObjectAttribute(TestBrokerConfiguration.ENTRY_NAME_RMI_PORT, Port.PORT, getManagementPort(actualPort)); + configuration.setObjectAttribute(TestBrokerConfiguration.ENTRY_NAME_JMX_PORT, Port.PORT, getManagementPort(actualPort) + JMXPORT_CONNECTORSERVER_OFFSET); + } + return configuration; + } + + private void initialiseLogConfigFile() + { + try + { + _logger.info("About to initialise log config file from system property: " + LOG4J_CONFIG_FILE_PATH); + + URI uri = new URI("file", LOG4J_CONFIG_FILE_PATH, null); + _logConfigFile = new File(uri); + if(!_logConfigFile.exists()) + { + throw new RuntimeException("Log config file " + _logConfigFile.getAbsolutePath() + " does not exist"); + } + } + catch (URISyntaxException e) + { + throw new RuntimeException("Couldn't create URI from log4.configuration: " + LOG4J_CONFIG_FILE_PATH, e); + } } public Logger getLogger() @@ -289,16 +356,6 @@ public class QpidBrokerTestCase extends QpidTestCase fail("Unable to test without config file:" + _configFile); } - String existingQpidWorkPath = System.getProperty(BROKER_EXISTING_QPID_WORK); - if(existingQpidWorkPath != null && !existingQpidWorkPath.equals("")) - { - - String qpidWork = getQpidWork(_brokerType, getPort()); - File existing = new File(existingQpidWorkPath); - cleanBrokerWork(qpidWork); - FileUtils.copyRecursive(existing, new File(qpidWork)); - } - startBroker(); } @@ -322,7 +379,7 @@ public class QpidBrokerTestCase extends QpidTestCase { Set ports = new HashSet(); int managementPort = getManagementPort(mainPort); - int connectorServerPort = managementPort + ServerConfiguration.JMXPORT_CONNECTORSERVER_OFFSET; + int connectorServerPort = managementPort + JMXPORT_CONNECTORSERVER_OFFSET; ports.add(mainPort); ports.add(managementPort); @@ -354,37 +411,33 @@ public class QpidBrokerTestCase extends QpidTestCase } } - protected String getBrokerCommand(int port) throws MalformedURLException + public void startBroker() throws Exception { - final int sslPort = port-1; - final String protocolExcludesList = getProtocolExcludesList(port, sslPort); - final String protocolIncludesList = getProtocolIncludesList(port, sslPort); + startBroker(0); + } - return _brokerCommand - .replace("@PORT", "" + port) - .replace("@SSL_PORT", "" + sslPort) - .replace("@MPORT", "" + getManagementPort(port)) - .replace("@CONFIG_FILE", _configFile.toString()) - .replace("@LOG_CONFIG_FILE", _logConfigFile.toString()) - .replace("@EXCLUDES", protocolExcludesList) - .replace("@INCLUDES", protocolIncludesList); + public void startBroker(int port) throws Exception + { + int actualPort = getPort(port); + TestBrokerConfiguration configuration = getBrokerConfiguration(actualPort); + startBroker(actualPort, configuration, _testVirtualhosts); } - public void startBroker() throws Exception + + protected File getBrokerCommandLog4JFile() { - startBroker(0); + return _logConfigFile; } - public void startBroker(int port) throws Exception + protected void setBrokerCommandLog4JFile(File file) { - startBroker(port, _testConfiguration, _testVirtualhosts); + _logConfigFile = file; + _logger.info("Modified log config file to: " + file); } - public void startBroker(int port, XMLConfiguration testConfiguration, XMLConfiguration virtualHosts) throws Exception + public void startBroker(int port, TestBrokerConfiguration testConfiguration, XMLConfiguration virtualHosts) throws Exception { port = getPort(port); - - // Save any configuration changes that have been made String testConfig = saveTestConfiguration(port, testConfiguration); String virtualHostsConfig = saveTestVirtualhosts(port, virtualHosts); @@ -397,28 +450,20 @@ public class QpidBrokerTestCase extends QpidTestCase if (_brokerType.equals(BrokerType.INTERNAL) && !existingInternalBroker()) { - setConfigurationProperty(ServerConfiguration.MGMT_CUSTOM_REGISTRY_SOCKET, String.valueOf(false)); - testConfig = saveTestConfiguration(port, testConfiguration); - _logger.info("Set test.config property to: " + testConfig); _logger.info("Set test.virtualhosts property to: " + virtualHostsConfig); - setSystemProperty(TEST_CONFIG, testConfig); setSystemProperty(TEST_VIRTUALHOSTS, virtualHostsConfig); - + setSystemProperty(BrokerProperties.PROPERTY_USE_CUSTOM_RMI_SOCKET_FACTORY, "false"); BrokerOptions options = new BrokerOptions(); - options.setConfigFile(_configFile.getAbsolutePath()); - options.addPort(port); - - addExcludedPorts(port, DEFAULT_SSL_PORT, options); - addIncludedPorts(port, DEFAULT_SSL_PORT, options); - options.setJmxPortRegistryServer(getManagementPort(port)); + options.setConfigurationStoreType(_brokerStoreType); + options.setConfigurationStoreLocation(testConfig); //Set the log config file, relying on the log4j.configuration system property //set on the JVM by the JUnit runner task in module.xml. options.setLogConfigFile(_logConfigFile.getAbsolutePath()); Broker broker = new Broker(); - _logger.info("starting internal broker (same JVM)"); + _logger.info("Starting internal broker (same JVM)"); broker.startup(options); _brokers.put(port, new InternalBrokerHolder(broker, System.getProperty("QPID_WORK"), portsUsedByBroker)); @@ -427,9 +472,10 @@ public class QpidBrokerTestCase extends QpidTestCase { // Add the port to QPID_WORK to ensure unique working dirs for multi broker tests final String qpidWork = getQpidWork(_brokerType, port); - String cmd = getBrokerCommand(port); - _logger.info("starting external broker: " + cmd); - ProcessBuilder pb = new ProcessBuilder(cmd.split("\\s+")); + + String[] cmd = _brokerCommandHelper.getBrokerCommand(port, testConfig, _brokerStoreType, _logConfigFile); + _logger.info("Starting spawn broker using command: " + StringUtils.join(cmd, ' ')); + ProcessBuilder pb = new ProcessBuilder(cmd); pb.redirectErrorStream(true); Map processEnv = pb.environment(); String qpidHome = System.getProperty(QPID_HOME); @@ -459,28 +505,28 @@ public class QpidBrokerTestCase extends QpidTestCase } } + String qpidOpts = ""; - // Add default test logging levels that are used by the log4j-test - // Use the convenience methods to push the current logging setting - // in to the external broker's QPID_OPTS string. - if (System.getProperty("amqj.protocol.logging.level") != null) + // a synchronized hack to avoid adding into QPID_OPTS the values + // of JVM properties "test.virtualhosts" and "test.config" set by a concurrent startup process + synchronized (_propertiesSetForBroker) { + // Add default test logging levels that are used by the log4j-test + // Use the convenience methods to push the current logging setting + // in to the external broker's QPID_OPTS string. setSystemProperty("amqj.protocol.logging.level"); - } - if (System.getProperty("root.logging.level") != null) - { setSystemProperty("root.logging.level"); - } - - // set test.config and test.virtualhosts - String qpidOpts = " -D" + TEST_CONFIG + "=" + testConfig + " -D" + TEST_VIRTUALHOSTS + "=" + virtualHostsConfig; + setSystemProperty(BrokerProperties.PROPERTY_BROKER_DEFAULT_AMQP_PROTOCOL_EXCLUDES); + setSystemProperty(BrokerProperties.PROPERTY_BROKER_DEFAULT_AMQP_PROTOCOL_INCLUDES); + setSystemProperty(TEST_VIRTUALHOSTS, virtualHostsConfig); - // Add all the specified system properties to QPID_OPTS - if (!_propertiesSetForBroker.isEmpty()) - { - for (String key : _propertiesSetForBroker.keySet()) + // Add all the specified system properties to QPID_OPTS + if (!_propertiesSetForBroker.isEmpty()) { - qpidOpts += " -D" + key + "=" + _propertiesSetForBroker.get(key); + for (String key : _propertiesSetForBroker.keySet()) + { + qpidOpts += " -D" + key + "=" + _propertiesSetForBroker.get(key); + } } } if (processEnv.containsKey("QPID_OPTS")) @@ -489,9 +535,6 @@ public class QpidBrokerTestCase extends QpidTestCase } processEnv.put("QPID_OPTS", qpidOpts); - _logger.info("Set test.config property to: " + testConfig); - _logger.info("Set test.virtualhosts property to: " + virtualHostsConfig); - // cpp broker requires that the work directory is created createBrokerWork(qpidWork); @@ -505,9 +548,15 @@ public class QpidBrokerTestCase extends QpidTestCase p.start(); + SpawnedBrokerHolder holder = new SpawnedBrokerHolder(process, qpidWork, portsUsedByBroker); if (!p.await(30, TimeUnit.SECONDS)) { _logger.info("broker failed to become ready (" + p.getReady() + "):" + p.getStopLine()); + String threadDump = holder.dumpThreads(); + if (!threadDump.isEmpty()) + { + _logger.info("the result of a try to capture thread dump:" + threadDump); + } //Ensure broker has stopped process.destroy(); cleanBrokerWork(qpidWork); @@ -528,65 +577,7 @@ public class QpidBrokerTestCase extends QpidTestCase // this is expect if the broker started successfully } - _brokers.put(port, new SpawnedBrokerHolder(process, qpidWork, portsUsedByBroker)); - } - } - - private void addExcludedPorts(int port, int sslPort, BrokerOptions options) - { - final String protocolExcludesList = getProtocolExcludesList(port, sslPort); - - if (protocolExcludesList.equals("")) - { - return; - } - final String[] toks = protocolExcludesList.split("\\s"); - - if(toks.length % 2 != 0) - { - throw new IllegalArgumentException("Must be an even number of tokens in '" + protocolExcludesList + "'"); - } - for (int i = 0; i < toks.length; i=i+2) - { - String excludeArg = toks[i]; - final int excludedPort = Integer.parseInt(toks[i+1]); - options.addExcludedPort(ProtocolExclusion.lookup(excludeArg), excludedPort); - - _logger.info("Adding protocol exclusion " + excludeArg + " " + excludedPort); - } - } - - protected String getProtocolExcludesList(int port, int sslPort) - { - return System.getProperty(BROKER_PROTOCOL_EXCLUDES,"").replace("@PORT", "" + port).replace("@SSL_PORT", "" + sslPort); - } - - private String getProtocolIncludesList(int port, int sslPort) - { - return System.getProperty(BROKER_PROTOCOL_INCLUDES, "").replace("@PORT", "" + port).replace("@SSL_PORT", "" + sslPort); - } - - private void addIncludedPorts(int port, int sslPort, BrokerOptions options) - { - final String protocolIncludesList = getProtocolIncludesList(port, sslPort); - - if (protocolIncludesList.equals("")) - { - return; - } - final String[] toks = protocolIncludesList.split("\\s"); - - if(toks.length % 2 != 0) - { - throw new IllegalArgumentException("Must be an even number of tokens in '" + protocolIncludesList + "'"); - } - for (int i = 0; i < toks.length; i=i+2) - { - String includeArg = toks[i]; - final int includedPort = Integer.parseInt(toks[i+1]); - options.addIncludedPort(ProtocolInclusion.lookup(includeArg), includedPort); - - _logger.info("Adding protocol inclusion " + includeArg + " " + includedPort); + _brokers.put(port, holder); } } @@ -620,7 +611,7 @@ public class QpidBrokerTestCase extends QpidTestCase public String getTestConfigFile(int port) { - return _output + "/" + getTestQueueName() + "-" + port + "-config.xml"; + return _output + "/" + getTestQueueName() + "-" + port + "-config"; } public String getTestVirtualhostsFile(int port) @@ -633,44 +624,33 @@ public class QpidBrokerTestCase extends QpidTestCase return file.replace(System.getProperty(QPID_HOME,"QPID_HOME") + "/",""); } - protected void saveTestConfiguration() throws ConfigurationException + protected String getPathRelativeToWorkingDirectory(String file) { - String relative = saveTestConfiguration(getPort(), _testConfiguration); - _logger.info("Set test.config property to: " + relative); - setSystemProperty(TEST_CONFIG, relative); + File configLocation = new File(file); + File workingDirectory = new File(System.getProperty("user.dir")); + return configLocation.getAbsolutePath().replace(workingDirectory.getAbsolutePath(), "").substring(1); } - protected String saveTestConfiguration(int port, XMLConfiguration testConfiguration) throws ConfigurationException + protected String saveTestConfiguration(int port, TestBrokerConfiguration testConfiguration) { - // Specify the test config file String testConfig = getTestConfigFile(port); - String relative = relativeToQpidHome(testConfig); - - _logger.info("Saving test virtualhosts file at: " + testConfig); - - // Create the file if configuration does not exist - if (testConfiguration.isEmpty()) + String relative = getPathRelativeToWorkingDirectory(testConfig); + if (!testConfiguration.isSaved()) { - testConfiguration.addProperty("__ignore", "true"); + _logger.info("Saving test broker configuration at: " + testConfig); + testConfiguration.save(new File(testConfig)); + testConfiguration.setSaved(true); } - testConfiguration.save(testConfig); return relative; } - protected void saveTestVirtualhosts() throws ConfigurationException - { - String relative = saveTestVirtualhosts(getPort(), _testVirtualhosts); - _logger.info("Set test.virtualhosts property to: " + relative); - setSystemProperty(TEST_VIRTUALHOSTS, relative); - } - protected String saveTestVirtualhosts(int port, XMLConfiguration virtualHostConfiguration) throws ConfigurationException { // Specify the test virtualhosts file String testVirtualhosts = getTestVirtualhostsFile(port); String relative = relativeToQpidHome(testVirtualhosts); - _logger.info("Set test.virtualhosts property to: " + testVirtualhosts); + _logger.info("Path to virtualhosts configuration: " + testVirtualhosts); // Create the file if configuration does not exist if (virtualHostConfiguration.isEmpty()) @@ -818,57 +798,41 @@ public class QpidBrokerTestCase extends QpidTestCase } /** - * Attempt to set the Java Broker to use the BDBMessageStore for persistence - * Falling back to the DerbyMessageStore if - * - * @param virtualhost - The virtualhost to modify + * Creates a new virtual host within the test virtualhost file. + * @param brokerPort broker port + * @param virtualHostName virtual host name * - * @throws ConfigurationException - when reading/writing existing configuration - * @throws IOException - When creating a temporary file. + * @throws ConfigurationException */ - protected void makeVirtualHostPersistent(String virtualhost) - throws ConfigurationException, IOException + protected void createTestVirtualHost(int brokerPort, String virtualHostName) throws ConfigurationException { - Class storeClass = null; - try + String storeClassName = getTestProfileMessageStoreClassName(); + + _testVirtualhosts.setProperty("virtualhost.name(-1)", virtualHostName); + _testVirtualhosts.setProperty("virtualhost." + virtualHostName + ".store.class", storeClassName); + + String storeDir = null; + + if (System.getProperty("profile", "").startsWith("java-dby-mem")) { - // Try and lookup the BDB class - storeClass = Class.forName("org.apache.qpid.server.store.berkeleydb.BDBMessageStore"); + storeDir = DerbyMessageStore.MEMORY_STORE_LOCATION; } - catch (ClassNotFoundException e) + else if (!MEMORY_STORE_CLASS_NAME.equals(storeClassName)) { - // No BDB store, we'll use Derby instead. - storeClass = DerbyMessageStore.class; + storeDir = "${QPID_WORK}" + File.separator + virtualHostName + "-store"; } + if (storeDir != null) + { + _testVirtualhosts.setProperty("virtualhost." + virtualHostName + ".store." + MessageStoreConstants.ENVIRONMENT_PATH_PROPERTY, storeDir); + } - setConfigurationProperty("virtualhosts.virtualhost." + virtualhost + ".store.class", - storeClass.getName()); - setConfigurationProperty("virtualhosts.virtualhost." + virtualhost + ".store." + MessageStoreConstants.ENVIRONMENT_PATH_PROPERTY, - "${QPID_WORK}/" + virtualhost); - } - - /** - * Get a property value from the current configuration file. - * - * @param property the property to lookup - * - * @return the requested String Value - * - * @throws org.apache.commons.configuration.ConfigurationException - * - */ - protected String getConfigurationStringProperty(String property) throws ConfigurationException - { - // Call save Configuration to be sure we have saved the test specific - // file. As the optional status - saveTestConfiguration(); - saveTestVirtualhosts(); - - ServerConfiguration configuration = new ServerConfiguration(_configFile); - // Don't need to configuration.configure() here as we are just pulling - // values directly by String. - return configuration.getConfig().getString(property); + // add new virtual host configuration to the broker store + Map attributes = new HashMap(); + attributes.put(VirtualHost.NAME, virtualHostName); + attributes.put(VirtualHost.CONFIG_PATH, System.getProperty("broker.virtualhosts-config")); + int port = getPort(brokerPort); + getBrokerConfiguration(port).addHostConfiguration(attributes); } /** @@ -884,10 +848,8 @@ public class QpidBrokerTestCase extends QpidTestCase * @param value the new value * * @throws ConfigurationException when loading the current config file - * @throws IOException when writing the new config file */ - public void setConfigurationProperty(String property, String value) - throws ConfigurationException, IOException + public void setVirtualHostConfigurationProperty(String property, String value) throws ConfigurationException { // Choose which file to write the property to based on prefix. if (property.startsWith("virtualhosts")) @@ -896,7 +858,7 @@ public class QpidBrokerTestCase extends QpidTestCase } else { - _testConfiguration.setProperty(property, value); + throw new ConfigurationException("Cannot set broker configuration as property"); } } @@ -914,11 +876,13 @@ public class QpidBrokerTestCase extends QpidTestCase */ protected void setBrokerOnlySystemProperty(String property, String value) { - if (!_propertiesSetForBroker.containsKey(property)) + synchronized (_propertiesSetForBroker) { - _propertiesSetForBroker.put(property, value); + if (!_propertiesSetForBroker.containsKey(property)) + { + _propertiesSetForBroker.put(property, value); + } } - } /** @@ -931,7 +895,11 @@ public class QpidBrokerTestCase extends QpidTestCase */ protected void setSystemProperty(String property) { - setSystemProperty(property, System.getProperty(property)); + String value = System.getProperty(property); + if (value != null) + { + setSystemProperty(property, value); + } } /** @@ -939,7 +907,7 @@ public class QpidBrokerTestCase extends QpidTestCase * * When the test run is complete the value will be reverted. * - * The values set using this method will also be propogated to the external + * The values set using this method will also be propagated to the external * Java Broker via a -D value defined in QPID_OPTS. * * If the value should not be set on the broker then use @@ -950,9 +918,18 @@ public class QpidBrokerTestCase extends QpidTestCase */ protected void setSystemProperty(String property, String value) { - // Record the value for the external broker - _propertiesSetForBroker.put(property, value); - + synchronized(_propertiesSetForBroker) + { + // Record the value for the external broker + if (value == null) + { + _propertiesSetForBroker.remove(property); + } + else + { + _propertiesSetForBroker.put(property, value); + } + } //Set the value for the test client vm aswell. setTestClientSystemProperty(property, value); } @@ -1073,7 +1050,7 @@ public class QpidBrokerTestCase extends QpidTestCase _logger.info("get ConnectionFactory"); if (_connectionFactory == null) { - if (Boolean.getBoolean("profile.use_ssl")) + if (Boolean.getBoolean(PROFILE_USE_SSL)) { _connectionFactory = getConnectionFactory("default.ssl"); } @@ -1092,7 +1069,7 @@ public class QpidBrokerTestCase extends QpidTestCase * * @return A connection factory * - * @throws Exception if there is an error getting the tactory + * @throws Exception if there is an error getting the factory */ public AMQConnectionFactory getConnectionFactory(String factoryName) throws NamingException { @@ -1104,6 +1081,22 @@ public class QpidBrokerTestCase extends QpidTestCase return getConnection(GUEST_USERNAME, GUEST_PASSWORD); } + public Connection getConnectionWithOptions(Map options) + throws URLSyntaxException, NamingException, JMSException + { + ConnectionURL curl = new AMQConnectionURL(getConnectionFactory().getConnectionURLString()); + for(Map.Entry entry : options.entrySet()) + { + curl.setOption(entry.getKey(), entry.getValue()); + } + curl = new AMQConnectionURL(curl.toString()); + + curl.setUsername(GUEST_USERNAME); + curl.setPassword(GUEST_PASSWORD); + return getConnection(curl); + } + + public Connection getConnection(ConnectionURL url) throws JMSException { _logger.info(url.getURL()); @@ -1363,11 +1356,6 @@ public class QpidBrokerTestCase extends QpidTestCase _messageSize = byteSize; } - public ConnectionURL getConnectionURL() throws NamingException - { - return getConnectionFactory().getConnectionURL(); - } - public BrokerDetails getBroker() { try @@ -1390,31 +1378,6 @@ public class QpidBrokerTestCase extends QpidTestCase return null; } - /** - * Reloads the broker security configuration using the ApplicationRegistry (InVM brokers) or the - * ConfigurationManagementMBean via the JMX interface (Standalone brokers, management must be - * enabled before calling the method). - */ - public void reloadBrokerSecurityConfig() throws Exception - { - JMXTestUtils jmxu = new JMXTestUtils(this); - jmxu.open(); - - try - { - ConfigurationManagement configMBean = jmxu.getConfigurationManagement(); - configMBean.reloadSecurityConfiguration(); - } - finally - { - jmxu.close(); - } - - LogMonitor _monitor = new LogMonitor(_outputFile); - assertTrue("The expected server security configuration reload did not occur", - _monitor.waitForMessage(ServerConfiguration.SECURITY_CONFIG_RELOADED, LOGMONITOR_TIMEOUT)); - } - protected int getFailingPort() { return FAILING_PORT; @@ -1430,13 +1393,14 @@ public class QpidBrokerTestCase extends QpidTestCase _testVirtualhosts = testVirtualhosts; } - public XMLConfiguration getTestConfiguration() + public String getTestProfileMessageStoreType() { - return _testConfiguration; + final String storeClass = getTestProfileMessageStoreClassName(); + if (storeClass == null) + { + return MemoryMessageStore.TYPE; + } + return supportedStoresClassToTypeMapping.get(storeClass); } - public void setTestConfiguration(XMLConfiguration testConfiguration) - { - _testConfiguration = testConfiguration; - } } diff --git a/java/systests/src/main/java/org/apache/qpid/test/utils/QpidClientConnectionHelper.java b/java/systests/src/main/java/org/apache/qpid/test/utils/QpidClientConnectionHelper.java deleted file mode 100644 index 72003ed7d7..0000000000 --- a/java/systests/src/main/java/org/apache/qpid/test/utils/QpidClientConnectionHelper.java +++ /dev/null @@ -1,295 +0,0 @@ -/* - * - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * - */ - -package org.apache.qpid.test.utils; - -import org.apache.log4j.Logger; - -import org.apache.qpid.client.AMQConnection; -import org.apache.qpid.client.AMQConnectionFactory; -import org.apache.qpid.client.AMQConnectionURL; -import org.apache.qpid.client.JMSAMQException; -import org.apache.qpid.url.URLSyntaxException; - -import javax.jms.Connection; -import javax.jms.ExceptionListener; -import javax.jms.JMSException; -import javax.jms.Message; -import javax.jms.MessageConsumer; -import javax.jms.MessageProducer; -import javax.jms.Queue; -import javax.jms.Session; -import javax.jms.TextMessage; - -/** - * @todo This was originally cut and paste from the client module leading to a duplicate class, then altered very - * slightly. To avoid the duplicate class the name was altered slightly to have 'Helper' on the end in order - * to distinguish it from the original. Delete this class and use the original instead, just upgrade it to - * provide the new features needed. - */ -public class QpidClientConnectionHelper implements ExceptionListener -{ - - private static final Logger _logger = Logger.getLogger(QpidClientConnectionHelper.class); - - private boolean transacted = true; - private int ackMode = Session.CLIENT_ACKNOWLEDGE; - private Connection connection; - - private String virtualHost; - private String brokerlist; - private int prefetch; - protected Session session; - protected boolean connected; - - public QpidClientConnectionHelper(String broker) - { - super(); - setVirtualHost("/test"); - setBrokerList(broker); - setPrefetch(5000); - } - - public void connect() throws JMSException - { - if (!connected) - { - /* - * amqp://[user:pass@][clientid]/virtualhost? - * brokerlist='[transport://]host[:port][?option='value'[&option='value']];' - * [&failover='method[?option='value'[&option='value']]'] - * [&option='value']" - */ - String brokerUrl = "amqp://guest:guest@" + virtualHost + "?brokerlist='" + brokerlist + "'"; - try - { - AMQConnectionFactory factory = new AMQConnectionFactory(new AMQConnectionURL(brokerUrl)); - _logger.info("connecting to Qpid :" + brokerUrl); - connection = factory.createConnection(); - - // register exception listener - connection.setExceptionListener(this); - - session = ((AMQConnection) connection).createSession(transacted, ackMode, prefetch); - - _logger.info("starting connection"); - connection.start(); - - connected = true; - } - catch (URLSyntaxException e) - { - throw new JMSAMQException("URL syntax error in [" + brokerUrl + "]: " + e.getMessage(), e); - } - } - } - - public void disconnect() throws JMSException - { - if (connected) - { - session.commit(); - session.close(); - connection.close(); - connected = false; - _logger.info("disconnected"); - } - } - - public void disconnectWithoutCommit() throws JMSException - { - if (connected) - { - session.close(); - connection.close(); - connected = false; - _logger.info("disconnected without commit"); - } - } - - public String getBrokerList() - { - return brokerlist; - } - - public void setBrokerList(String brokerlist) - { - this.brokerlist = brokerlist; - } - - public String getVirtualHost() - { - return virtualHost; - } - - public void setVirtualHost(String virtualHost) - { - this.virtualHost = virtualHost; - } - - public void setPrefetch(int prefetch) - { - this.prefetch = prefetch; - } - - /** override as necessary */ - public void onException(JMSException exception) - { - _logger.info("ExceptionListener event: error " + exception.getErrorCode() + ", message: " + exception.getMessage()); - } - - public boolean isConnected() - { - return connected; - } - - public Session getSession() - { - return session; - } - - /** - * Put a String as a text messages, repeat n times. A null payload will result in a null message. - * - * @param queueName The queue name to put to - * @param payload the content of the payload - * @param copies the number of messages to put - * - * @throws javax.jms.JMSException any exception that occurs - */ - public void put(String queueName, String payload, int copies, int deliveryMode) throws JMSException - { - if (!connected) - { - connect(); - } - - _logger.info("putting to queue " + queueName); - Queue queue = session.createQueue(queueName); - - final MessageProducer sender = session.createProducer(queue); - - sender.setDeliveryMode(deliveryMode); - - for (int i = 0; i < copies; i++) - { - Message m = session.createTextMessage(payload + i); - m.setIntProperty("index", i + 1); - sender.send(m); - } - - session.commit(); - sender.close(); - _logger.info("put " + copies + " copies"); - } - - /** - * GET the top message on a queue. Consumes the message. Accepts timeout value. - * - * @param queueName The quename to get from - * @param readTimeout The timeout to use - * - * @return the content of the text message if any - * - * @throws javax.jms.JMSException any exception that occured - */ - public Message getNextMessage(String queueName, long readTimeout) throws JMSException - { - if (!connected) - { - connect(); - } - - Queue queue = session.createQueue(queueName); - - final MessageConsumer consumer = session.createConsumer(queue); - - Message message = consumer.receive(readTimeout); - session.commit(); - consumer.close(); - - Message result; - - // all messages we consume should be TextMessages - if (message instanceof TextMessage) - { - result = ((TextMessage) message); - } - else if (null == message) - { - result = null; - } - else - { - _logger.info("warning: received non-text message"); - result = message; - } - - return result; - } - - /** - * GET the top message on a queue. Consumes the message. - * - * @param queueName The Queuename to get from - * - * @return The string content of the text message, if any received - * - * @throws javax.jms.JMSException any exception that occurs - */ - public Message getNextMessage(String queueName) throws JMSException - { - return getNextMessage(queueName, 0); - } - - /** - * Completely clears a queue. For readTimeout behaviour see Javadocs for javax.jms.MessageConsumer. - * - * @param queueName The Queue name to consume from - * @param readTimeout The timeout for each consume - * - * @throws javax.jms.JMSException Any exception that occurs during the consume - * @throws InterruptedException If the consume thread was interrupted during a consume. - */ - public void consume(String queueName, int readTimeout) throws JMSException, InterruptedException - { - if (!connected) - { - connect(); - } - - _logger.info("consuming queue " + queueName); - Queue queue = session.createQueue(queueName); - - final MessageConsumer consumer = session.createConsumer(queue); - int messagesReceived = 0; - - _logger.info("consuming..."); - while ((consumer.receive(readTimeout)) != null) - { - messagesReceived++; - } - - session.commit(); - consumer.close(); - _logger.info("consumed: " + messagesReceived); - } -} diff --git a/java/systests/src/main/java/org/apache/qpid/test/utils/TestBrokerConfiguration.java b/java/systests/src/main/java/org/apache/qpid/test/utils/TestBrokerConfiguration.java new file mode 100644 index 0000000000..80f8010678 --- /dev/null +++ b/java/systests/src/main/java/org/apache/qpid/test/utils/TestBrokerConfiguration.java @@ -0,0 +1,219 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.test.utils; + +import java.io.File; +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; +import java.util.UUID; + +import org.apache.qpid.server.configuration.ConfigurationEntry; +import org.apache.qpid.server.configuration.store.JsonConfigurationEntryStore; +import org.apache.qpid.server.model.AuthenticationProvider; +import org.apache.qpid.server.model.Plugin; +import org.apache.qpid.server.model.Port; +import org.apache.qpid.server.model.UUIDGenerator; +import org.apache.qpid.server.model.VirtualHost; +import org.apache.qpid.server.plugin.PluginFactory; + +public class TestBrokerConfiguration +{ + public static final String ENTRY_NAME_HTTP_PORT = "http"; + public static final String ENTRY_NAME_AMQP_PORT = "amqp"; + public static final String ENTRY_NAME_RMI_PORT = "rmi"; + public static final String ENTRY_NAME_JMX_PORT = "jmx"; + public static final String ENTRY_NAME_VIRTUAL_HOST = "test"; + public static final String ENTRY_NAME_AUTHENTICATION_PROVIDER = "plain"; + public static final String ENTRY_NAME_EXTERNAL_PROVIDER = "external"; + public static final String ENTRY_NAME_SSL_PORT = "sslPort"; + public static final String ENTRY_NAME_HTTP_MANAGEMENT = "MANAGEMENT-HTTP"; + public static final String MANAGEMENT_HTTP_PLUGIN_TYPE = "MANAGEMENT-HTTP"; + public static final String ENTRY_NAME_JMX_MANAGEMENT = "MANAGEMENT-JMX"; + public static final String MANAGEMENT_JMX_PLUGIN_TYPE = "MANAGEMENT-JMX"; + public static final String ENTRY_NAME_ANONYMOUS_PROVIDER = "anonymous"; + + private JsonConfigurationEntryStore _store; + private boolean _saved; + + public TestBrokerConfiguration(String storeType, String intialStoreLocation) + { + // TODO: add support for DERBY store + _store = new JsonConfigurationEntryStore(); + _store.open(JsonConfigurationEntryStore.IN_MEMORY, intialStoreLocation); + } + + public boolean setBrokerAttribute(String name, Object value) + { + return setObjectAttribute(_store.getRootEntry(), name, value); + } + + public boolean setObjectAttribute(String objectName, String attributeName, Object value) + { + ConfigurationEntry entry = findObjectByName(objectName); + if (entry == null) + { + return false; + } + return setObjectAttribute(entry, attributeName, value); + } + + public boolean setObjectAttributes(String objectName, Map attributes) + { + ConfigurationEntry entry = findObjectByName(objectName); + if (entry == null) + { + return false; + } + return setObjectAttributes(entry, attributes); + } + + public boolean save(File configFile) + { + _store.copyTo(configFile.getAbsolutePath()); + return true; + } + + public UUID[] removeObjectConfiguration(String name) + { + ConfigurationEntry entry = findObjectByName(name); + if (entry != null) + { + return _store.remove(entry.getId()); + } + return null; + } + + public UUID addObjectConfiguration(String name, String type, Map attributes) + { + UUID id = UUIDGenerator.generateBrokerChildUUID(type, name); + addObjectConfiguration(id, type, attributes); + return id; + } + + public UUID addJmxManagementConfiguration() + { + Map attributes = new HashMap(); + attributes.put(PluginFactory.PLUGIN_TYPE, MANAGEMENT_JMX_PLUGIN_TYPE); + attributes.put(Plugin.NAME, ENTRY_NAME_JMX_MANAGEMENT); + return addObjectConfiguration(ENTRY_NAME_JMX_MANAGEMENT, Plugin.class.getSimpleName(), attributes); + } + + public UUID addHttpManagementConfiguration() + { + Map attributes = new HashMap(); + attributes.put(PluginFactory.PLUGIN_TYPE, MANAGEMENT_HTTP_PLUGIN_TYPE); + attributes.put(Plugin.NAME, ENTRY_NAME_HTTP_MANAGEMENT); + return addObjectConfiguration(ENTRY_NAME_HTTP_MANAGEMENT, Plugin.class.getSimpleName(), attributes); + } + + public UUID addPortConfiguration(Map attributes) + { + String name = (String) attributes.get(Port.NAME); + return addObjectConfiguration(name, Port.class.getSimpleName(), attributes); + } + + public UUID addHostConfiguration(Map attributes) + { + String name = (String) attributes.get(VirtualHost.NAME); + return addObjectConfiguration(name, VirtualHost.class.getSimpleName(), attributes); + } + + public UUID addAuthenticationProviderConfiguration(Map attributes) + { + String name = (String) attributes.get(AuthenticationProvider.NAME); + return addObjectConfiguration(name, AuthenticationProvider.class.getSimpleName(), attributes); + } + + private boolean setObjectAttributes(ConfigurationEntry entry, Map attributes) + { + Map newAttributes = new HashMap(entry.getAttributes()); + newAttributes.putAll(attributes); + ConfigurationEntry newEntry = new ConfigurationEntry(entry.getId(), entry.getType(), newAttributes, + entry.getChildrenIds(), _store); + _store.save(newEntry); + return true; + } + + private ConfigurationEntry findObjectByName(String objectName) + { + ConfigurationEntry root = _store.getRootEntry(); + return findObjectByName(root, objectName); + } + + private ConfigurationEntry findObjectByName(ConfigurationEntry entry, String objectName) + { + Map attributes = entry.getAttributes(); + if (attributes != null) + { + String name = (String) attributes.get("name"); + if (objectName.equals(name)) + { + return entry; + } + } + Set childrenIds = entry.getChildrenIds(); + for (UUID uuid : childrenIds) + { + ConfigurationEntry child = _store.getEntry(uuid); + ConfigurationEntry result = findObjectByName(child, objectName); + if (result != null) + { + return result; + } + } + return null; + } + + private void addObjectConfiguration(UUID id, String type, Map attributes) + { + ConfigurationEntry entry = new ConfigurationEntry(id, type, attributes, Collections. emptySet(), _store); + ConfigurationEntry root = _store.getRootEntry(); + Set childrenIds = new HashSet(root.getChildrenIds()); + childrenIds.add(id); + ConfigurationEntry newRoot = new ConfigurationEntry(root.getId(), root.getType(), root.getAttributes(), childrenIds, + _store); + _store.save(newRoot, entry); + } + + private boolean setObjectAttribute(ConfigurationEntry entry, String attributeName, Object value) + { + Map attributes = new HashMap(entry.getAttributes()); + attributes.put(attributeName, value); + ConfigurationEntry newEntry = new ConfigurationEntry(entry.getId(), entry.getType(), attributes, entry.getChildrenIds(), + _store); + _store.save(newEntry); + return true; + } + + public boolean isSaved() + { + return _saved; + } + + public void setSaved(boolean saved) + { + _saved = saved; + } + +} diff --git a/java/systests/src/main/java/org/apache/qpid/test/utils/TestSSLConstants.java b/java/systests/src/main/java/org/apache/qpid/test/utils/TestSSLConstants.java new file mode 100644 index 0000000000..9d5be775dc --- /dev/null +++ b/java/systests/src/main/java/org/apache/qpid/test/utils/TestSSLConstants.java @@ -0,0 +1,30 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT 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.utils; + +public interface TestSSLConstants +{ + String KEYSTORE = "test-profiles/test_resources/ssl/java_client_keystore.jks"; + String KEYSTORE_PASSWORD = "password"; + String TRUSTSTORE = "test-profiles/test_resources/ssl/java_client_truststore.jks"; + String TRUSTSTORE_PASSWORD = "password"; + + String BROKER_KEYSTORE = "test-profiles/test_resources/ssl/java_broker_keystore.jks"; + String BROKER_KEYSTORE_PASSWORD = "password"; +} diff --git a/java/systests/src/main/java/org/apache/qpid/test/utils/TestUtils.java b/java/systests/src/main/java/org/apache/qpid/test/utils/TestUtils.java new file mode 100644 index 0000000000..c651d3ec7f --- /dev/null +++ b/java/systests/src/main/java/org/apache/qpid/test/utils/TestUtils.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.test.utils; + +import java.lang.management.ManagementFactory; +import java.lang.management.ThreadInfo; +import java.lang.management.ThreadMXBean; + +public class TestUtils +{ + public static String dumpThreads() + { + ThreadMXBean threadMXBean = ManagementFactory.getThreadMXBean(); + ThreadInfo[] threadInfos = threadMXBean.dumpAllThreads(true, true); + StringBuilder dump = new StringBuilder(); + dump.append(String.format("%n")); + for (ThreadInfo threadInfo : threadInfos) + { + dump.append(threadInfo); + } + + long[] deadLocks = threadMXBean.findDeadlockedThreads(); + if (deadLocks != null && deadLocks.length > 0) + { + ThreadInfo[] deadlockedThreads = threadMXBean.getThreadInfo(deadLocks); + dump.append(String.format("%n")); + dump.append("Deadlock is detected!"); + dump.append(String.format("%n")); + for (ThreadInfo threadInfo : deadlockedThreads) + { + dump.append(threadInfo); + } + } + return dump.toString(); + } +} diff --git a/java/systests/src/main/java/org/apache/qpid/util/LogMonitor.java b/java/systests/src/main/java/org/apache/qpid/util/LogMonitor.java index 2b99289cd1..d77731d09f 100644 --- a/java/systests/src/main/java/org/apache/qpid/util/LogMonitor.java +++ b/java/systests/src/main/java/org/apache/qpid/util/LogMonitor.java @@ -30,8 +30,10 @@ import java.io.FileNotFoundException; import java.io.FileReader; import java.io.IOException; import java.io.LineNumberReader; +import java.util.HashMap; import java.util.LinkedList; import java.util.List; +import java.util.Map; /** * Utility to simplify the monitoring of Log4j file output @@ -42,6 +44,8 @@ import java.util.List; */ public class LogMonitor { + private static final Logger _logger = Logger.getLogger(LogMonitor.class); + // The file that the log statements will be written to. private final File _logfile; @@ -90,6 +94,8 @@ public class LogMonitor _appender.setImmediateFlush(true); Logger.getRootLogger().addAppender(_appender); } + + _logger.info("Created LogMonitor. Monitoring file: " + _logfile.getAbsolutePath()); } /** @@ -156,6 +162,39 @@ public class LogMonitor return results; } + public Map> findMatches(String... pattern) throws IOException + { + + Map> results= new HashMap>(); + for (String p : pattern) + { + results.put(p, new LinkedList()); + } + LineNumberReader reader = new LineNumberReader(new FileReader(_logfile)); + try + { + while (reader.ready()) + { + String line = reader.readLine(); + if (reader.getLineNumber() > _linesToSkip) + { + for (String p : pattern) + { + if (line.contains(p)) + { + results.get(p).add(line); + } + } + } + } + } + finally + { + reader.close(); + } + + return results; + } /** * Checks the log file for a given message to appear. If the caller * has previously called {@link #markDiscardPoint()}, lines up until the discard -- cgit v1.2.1