From 34ee1fa2a9793f1cf68f688d85da78e957a7d9e7 Mon Sep 17 00:00:00 2001 From: Keith Wall Date: Mon, 21 Apr 2014 14:28:29 +0000 Subject: QPID-5715: [Java Broker] Add virtual host node to the model and refactor existing broker functionality to conform the new model. Save configuration model version as VHN attribute and refactor the upgraders and configuration recovery. git-svn-id: https://svn.apache.org/repos/asf/qpid/trunk/qpid@1588886 13f79535-47bb-0310-9956-ffa450edef68 --- .../jmx/BDBHAMessageStoreManagerMBean.java | 5 +- .../jmx/BDBHAMessageStoreManagerMBeanProvider.java | 13 +- .../jmx/BDBHAMessageStoreManagerMBeanTest.java | 6 +- .../server/store/berkeleydb/BDBHAVirtualHost.java | 163 +---- .../store/berkeleydb/BDBHAVirtualHostFactory.java | 13 +- .../server/store/berkeleydb/BDBMessageStore.java | 61 +- .../store/berkeleydb/BDBMessageStoreFactory.java | 10 +- .../store/berkeleydb/EnvironmentFacadeFactory.java | 2 +- .../berkeleydb/StandardEnvironmentFacade.java | 1 - .../replication/ReplicatedEnvironmentFacade.java | 1 + .../ReplicatedEnvironmentFacadeFactory.java | 70 +- .../store/berkeleydb/upgrade/UpgradeFrom7To8.java | 2 +- .../berkeleydb/BDBHAVirtualHostNode.java | 65 ++ .../berkeleydb/BDBHAVirtualHostNodeFactory.java | 44 ++ .../berkeleydb/BDBHAVirtualHostNodeImpl.java | 537 ++++++++++++++++ .../berkeleydb/BDBVirtualHostNode.java | 34 + .../berkeleydb/BDBVirtualHostNodeFactory.java | 44 ++ .../berkeleydb/BDBVirtualHostNodeImpl.java | 71 ++ ....qpid.server.plugin.ConfiguredObjectTypeFactory | 2 + .../store/berkeleydb/BDBHAVirtualHostNodeTest.java | 193 ++++++ .../server/store/berkeleydb/VirtualHostTest.java | 159 ----- .../berkeleydb/upgrade/UpgradeFrom7To8Test.java | 1 + .../server/store/berkeleydb/BDBBackupTest.java | 11 +- .../server/store/berkeleydb/BDBUpgradeTest.java | 15 +- .../store/berkeleydb/HAClusterBlackboxTest.java | 1 - .../store/berkeleydb/HAClusterTwoNodeTest.java | 2 +- .../store/berkeleydb/HATestClusterCreator.java | 47 +- .../configuration/startup/BrokerStoreUpgrader.java | 212 ++---- .../configuration/startup/StoreUpgraderPhase.java | 49 ++ .../startup/UpgraderPhaseFactory.java | 45 ++ .../store/StoreConfigurationChangeListener.java | 5 +- .../model/AbstractConfiguredObjectTypeFactory.java | 2 +- .../java/org/apache/qpid/server/model/Broker.java | 2 +- .../org/apache/qpid/server/model/BrokerModel.java | 9 +- .../org/apache/qpid/server/model/VirtualHost.java | 7 +- .../apache/qpid/server/model/VirtualHostNode.java | 36 ++ .../qpid/server/model/adapter/BrokerAdapter.java | 121 ++-- .../model/adapter/StandardVirtualHostFactory.java | 6 +- .../qpid/server/model/port/AbstractPort.java | 13 +- .../qpid/server/model/port/AmqpPortImpl.java | 3 +- .../plugin/DurableConfigurationStoreFactory.java | 5 +- .../AbstractDurableConfiguredObjectRecoverer.java | 118 ---- .../server/store/AbstractJDBCMessageStore.java | 7 + .../server/store/AbstractMemoryMessageStore.java | 1 - ...ConfiguredObjectRecordRecoveverAndUpgrader.java | 60 -- .../store/DurableConfigurationRecoverer.java | 312 --------- .../server/store/DurableConfigurationStore.java | 2 - .../store/DurableConfiguredObjectRecoverer.java | 32 - .../qpid/server/store/JsonFileConfigStore.java | 110 ++-- .../server/store/JsonFileConfigStoreFactory.java | 8 +- .../org/apache/qpid/server/store/MessageStore.java | 1 + .../org/apache/qpid/server/store/NullUpgrader.java | 7 - .../apache/qpid/server/store/UpgraderProvider.java | 26 - .../VirtualHostStoreUpgraderAndRecoverer.java | 713 +++++++++++++++++++++ .../server/virtualhost/AbstractVirtualHost.java | 216 ++++--- .../qpid/server/virtualhost/BindingRecoverer.java | 195 ------ .../virtualhost/DefaultUpgraderProvider.java | 413 ------------ .../qpid/server/virtualhost/ExchangeRecoverer.java | 114 ---- .../qpid/server/virtualhost/QueueRecoverer.java | 161 ----- .../server/virtualhost/StandardVirtualHost.java | 182 ++---- .../AbstractStandardVirtualHostNode.java | 354 ++++++++++ .../virtualhostnode/FileBasedVirtualHostNode.java | 33 + .../JsonVirtualHostNodeFactory.java | 43 ++ .../virtualhostnode/JsonVirtualHostNodeImpl.java | 61 ++ ....qpid.server.plugin.ConfiguredObjectTypeFactory | 3 +- .../src/main/resources/initial-config.json | 11 +- .../configuration/startup/BrokerRecovererTest.java | 40 -- .../startup/VirtualHostCreationTest.java | 58 +- .../store/ConfigurationEntryStoreTestCase.java | 21 +- .../StoreConfigurationChangeListenerTest.java | 10 +- .../server/logging/actors/BaseActorTestCase.java | 9 +- .../actors/BaseConnectionActorTestCase.java | 2 +- .../apache/qpid/server/model/VirtualHostTest.java | 43 +- .../AbstractDurableConfigurationStoreTestCase.java | 39 +- .../qpid/server/store/JsonFileConfigStoreTest.java | 155 +++-- .../store/TestMemoryMessageStoreFactory.java | 14 +- .../apache/qpid/server/util/BrokerTestHelper.java | 76 +-- .../DurableConfigurationRecovererTest.java | 545 ---------------- .../qpid/server/virtualhost/MockVirtualHost.java | 13 +- .../virtualhost/VirtualHostQueueCreationTest.java | 69 +- .../AbstractStandardVirtualHostNodeTest.java | 170 +++++ .../virtualhostnode/TestVirtualHostNode.java | 85 +++ .../TestVirtualHostNodeFactory.java | 43 ++ ....qpid.server.plugin.ConfiguredObjectTypeFactory | 20 + ....server.plugin.DurableConfigurationStoreFactory | 19 + .../store/derby/DerbyMessageStoreFactory.java | 7 +- .../derby/DerbyVirtualHostNode.java | 63 ++ .../derby/DerbyVirtualHostNodeFactory.java | 45 ++ ....qpid.server.plugin.ConfiguredObjectTypeFactory | 19 + .../qpid/server/store/jdbc/JDBCMessageStore.java | 12 +- .../server/store/jdbc/JDBCMessageStoreFactory.java | 6 +- .../virtualhostnode/jdbc/JDBCVirtualHostNode.java | 48 ++ .../jdbc/JDBCVirtualHostNodeFactory.java | 44 ++ .../jdbc/JDBCVirtualHostNodeImpl.java | 103 +++ ....qpid.server.plugin.ConfiguredObjectTypeFactory | 19 + .../server/management/plugin/HttpManagement.java | 14 +- .../plugin/servlet/rest/MessageContentServlet.java | 12 +- .../plugin/servlet/rest/MessageServlet.java | 12 +- .../qpid/server/jmx/JMXManagementPluginImpl.java | 67 +- .../org/apache/qpid/server/jmx/MBeanProvider.java | 4 +- .../server/store/MemoryMessageStoreFactory.java | 14 +- .../memory/MemoryVirtualHostNode.java | 47 ++ .../memory/MemoryVirtualHostNodeFactory.java | 44 ++ ....qpid.server.plugin.ConfiguredObjectTypeFactory | 19 + .../main/java/org/apache/qpid/util/Strings.java | 4 + .../org/apache/qpid/test/utils/QpidTestCase.java | 4 + java/systests/etc/config-systests.json | 12 +- .../failover/MultipleBrokersFailoverTest.java | 2 +- .../apache/qpid/server/logging/AlertingTest.java | 2 +- .../server/security/acl/ExternalACLJMXTest.java | 6 +- .../qpid/server/stats/StatisticsReportingTest.java | 9 +- .../apache/qpid/server/store/SplitStoreTest.java | 45 +- .../qpid/server/store/StoreOverfullTest.java | 23 +- .../server/store/VirtualHostMessageStoreTest.java | 229 +++---- .../systest/management/jmx/StatisticsTest.java | 4 +- .../java/org/apache/qpid/systest/rest/Asserts.java | 2 +- .../apache/qpid/systest/rest/BindingRestTest.java | 59 +- .../apache/qpid/systest/rest/BrokerRestTest.java | 17 +- .../qpid/systest/rest/ConnectionRestTest.java | 12 +- .../apache/qpid/systest/rest/ExchangeRestTest.java | 12 +- .../apache/qpid/systest/rest/QpidRestTestCase.java | 5 +- .../apache/qpid/systest/rest/QueueRestTest.java | 16 +- .../apache/qpid/systest/rest/RestTestHelper.java | 6 +- .../qpid/systest/rest/StructureRestTest.java | 18 +- .../qpid/systest/rest/VirtualHostRestTest.java | 88 ++- .../qpid/systest/rest/acl/BrokerACLTest.java | 72 +-- .../qpid/systest/rest/acl/ExchangeRestACLTest.java | 81 ++- .../qpid/systest/rest/acl/QueueRestACLTest.java | 86 +-- .../destination/AddressBasedDestinationTest.java | 7 - .../test/client/timeouts/SyncWaitDelayTest.java | 11 +- .../apache/qpid/test/utils/QpidBrokerTestCase.java | 35 +- .../qpid/test/utils/TestBrokerConfiguration.java | 29 + .../java/org/apache/qpid/test/utils/TestUtils.java | 62 ++ 133 files changed, 4551 insertions(+), 3708 deletions(-) create mode 100644 java/bdbstore/src/main/java/org/apache/qpid/server/virtualhostnode/berkeleydb/BDBHAVirtualHostNode.java create mode 100644 java/bdbstore/src/main/java/org/apache/qpid/server/virtualhostnode/berkeleydb/BDBHAVirtualHostNodeFactory.java create mode 100644 java/bdbstore/src/main/java/org/apache/qpid/server/virtualhostnode/berkeleydb/BDBHAVirtualHostNodeImpl.java create mode 100644 java/bdbstore/src/main/java/org/apache/qpid/server/virtualhostnode/berkeleydb/BDBVirtualHostNode.java create mode 100644 java/bdbstore/src/main/java/org/apache/qpid/server/virtualhostnode/berkeleydb/BDBVirtualHostNodeFactory.java create mode 100644 java/bdbstore/src/main/java/org/apache/qpid/server/virtualhostnode/berkeleydb/BDBVirtualHostNodeImpl.java create mode 100644 java/bdbstore/src/test/java/org/apache/qpid/server/store/berkeleydb/BDBHAVirtualHostNodeTest.java delete mode 100644 java/bdbstore/src/test/java/org/apache/qpid/server/store/berkeleydb/VirtualHostTest.java create mode 100644 java/broker-core/src/main/java/org/apache/qpid/server/configuration/startup/StoreUpgraderPhase.java create mode 100644 java/broker-core/src/main/java/org/apache/qpid/server/configuration/startup/UpgraderPhaseFactory.java create mode 100644 java/broker-core/src/main/java/org/apache/qpid/server/model/VirtualHostNode.java delete mode 100644 java/broker-core/src/main/java/org/apache/qpid/server/store/AbstractDurableConfiguredObjectRecoverer.java delete mode 100644 java/broker-core/src/main/java/org/apache/qpid/server/store/ConfiguredObjectRecordRecoveverAndUpgrader.java delete mode 100644 java/broker-core/src/main/java/org/apache/qpid/server/store/DurableConfigurationRecoverer.java delete mode 100644 java/broker-core/src/main/java/org/apache/qpid/server/store/DurableConfiguredObjectRecoverer.java delete mode 100644 java/broker-core/src/main/java/org/apache/qpid/server/store/UpgraderProvider.java create mode 100644 java/broker-core/src/main/java/org/apache/qpid/server/store/VirtualHostStoreUpgraderAndRecoverer.java delete mode 100644 java/broker-core/src/main/java/org/apache/qpid/server/virtualhost/BindingRecoverer.java delete mode 100644 java/broker-core/src/main/java/org/apache/qpid/server/virtualhost/DefaultUpgraderProvider.java delete mode 100644 java/broker-core/src/main/java/org/apache/qpid/server/virtualhost/ExchangeRecoverer.java delete mode 100644 java/broker-core/src/main/java/org/apache/qpid/server/virtualhost/QueueRecoverer.java create mode 100644 java/broker-core/src/main/java/org/apache/qpid/server/virtualhostnode/AbstractStandardVirtualHostNode.java create mode 100644 java/broker-core/src/main/java/org/apache/qpid/server/virtualhostnode/FileBasedVirtualHostNode.java create mode 100644 java/broker-core/src/main/java/org/apache/qpid/server/virtualhostnode/JsonVirtualHostNodeFactory.java create mode 100644 java/broker-core/src/main/java/org/apache/qpid/server/virtualhostnode/JsonVirtualHostNodeImpl.java delete mode 100644 java/broker-core/src/test/java/org/apache/qpid/server/virtualhost/DurableConfigurationRecovererTest.java create mode 100644 java/broker-core/src/test/java/org/apache/qpid/server/virtualhostnode/AbstractStandardVirtualHostNodeTest.java create mode 100644 java/broker-core/src/test/java/org/apache/qpid/server/virtualhostnode/TestVirtualHostNode.java create mode 100644 java/broker-core/src/test/java/org/apache/qpid/server/virtualhostnode/TestVirtualHostNodeFactory.java create mode 100644 java/broker-core/src/test/resources/META-INF/services/org.apache.qpid.server.plugin.ConfiguredObjectTypeFactory create mode 100644 java/broker-core/src/test/resources/META-INF/services/org.apache.qpid.server.plugin.DurableConfigurationStoreFactory create mode 100644 java/broker-plugins/derby-store/src/main/java/org/apache/qpid/server/virtualhostnode/derby/DerbyVirtualHostNode.java create mode 100644 java/broker-plugins/derby-store/src/main/java/org/apache/qpid/server/virtualhostnode/derby/DerbyVirtualHostNodeFactory.java create mode 100644 java/broker-plugins/derby-store/src/main/resources/META-INF/services/org.apache.qpid.server.plugin.ConfiguredObjectTypeFactory create mode 100644 java/broker-plugins/jdbc-store/src/main/java/org/apache/qpid/server/virtualhostnode/jdbc/JDBCVirtualHostNode.java create mode 100644 java/broker-plugins/jdbc-store/src/main/java/org/apache/qpid/server/virtualhostnode/jdbc/JDBCVirtualHostNodeFactory.java create mode 100644 java/broker-plugins/jdbc-store/src/main/java/org/apache/qpid/server/virtualhostnode/jdbc/JDBCVirtualHostNodeImpl.java create mode 100644 java/broker-plugins/jdbc-store/src/main/resources/META-INF/services/org.apache.qpid.server.plugin.ConfiguredObjectTypeFactory create mode 100644 java/broker-plugins/memory-store/src/main/java/org/apache/qpid/server/virtualhostnode/memory/MemoryVirtualHostNode.java create mode 100644 java/broker-plugins/memory-store/src/main/java/org/apache/qpid/server/virtualhostnode/memory/MemoryVirtualHostNodeFactory.java create mode 100644 java/broker-plugins/memory-store/src/main/resources/META-INF/services/org.apache.qpid.server.plugin.ConfiguredObjectTypeFactory (limited to 'java') diff --git a/java/bdbstore/jmx/src/main/java/org/apache/qpid/server/store/berkeleydb/jmx/BDBHAMessageStoreManagerMBean.java b/java/bdbstore/jmx/src/main/java/org/apache/qpid/server/store/berkeleydb/jmx/BDBHAMessageStoreManagerMBean.java index f36c1ecc6f..3a21bc70d7 100644 --- a/java/bdbstore/jmx/src/main/java/org/apache/qpid/server/store/berkeleydb/jmx/BDBHAMessageStoreManagerMBean.java +++ b/java/bdbstore/jmx/src/main/java/org/apache/qpid/server/store/berkeleydb/jmx/BDBHAMessageStoreManagerMBean.java @@ -38,6 +38,7 @@ import javax.management.openmbean.TabularType; import org.apache.log4j.Logger; import org.apache.qpid.server.jmx.AMQManagedObject; import org.apache.qpid.server.jmx.ManagedObject; +import org.apache.qpid.server.jmx.ManagedObjectRegistry; import org.apache.qpid.server.store.berkeleydb.replication.ReplicatedEnvironmentFacade; /** @@ -75,9 +76,9 @@ public class BDBHAMessageStoreManagerMBean extends AMQManagedObject implements M private final ReplicatedEnvironmentFacade _replicatedEnvironmentFacade; private final String _objectName; - protected BDBHAMessageStoreManagerMBean(String virtualHostName, ReplicatedEnvironmentFacade replicatedEnvironmentFacade, ManagedObject parent) throws JMException + protected BDBHAMessageStoreManagerMBean(String virtualHostName, ReplicatedEnvironmentFacade replicatedEnvironmentFacade, ManagedObjectRegistry registry) throws JMException { - super(ManagedBDBHAMessageStore.class, ManagedBDBHAMessageStore.TYPE, ((AMQManagedObject)parent).getRegistry()); + super(ManagedBDBHAMessageStore.class, ManagedBDBHAMessageStore.TYPE, registry); LOGGER.debug("Creating BDBHAMessageStoreManagerMBean for " + virtualHostName); _replicatedEnvironmentFacade = replicatedEnvironmentFacade; _objectName = ObjectName.quote(virtualHostName); diff --git a/java/bdbstore/jmx/src/main/java/org/apache/qpid/server/store/berkeleydb/jmx/BDBHAMessageStoreManagerMBeanProvider.java b/java/bdbstore/jmx/src/main/java/org/apache/qpid/server/store/berkeleydb/jmx/BDBHAMessageStoreManagerMBeanProvider.java index 410ef941cd..558cc7e8a9 100644 --- a/java/bdbstore/jmx/src/main/java/org/apache/qpid/server/store/berkeleydb/jmx/BDBHAMessageStoreManagerMBeanProvider.java +++ b/java/bdbstore/jmx/src/main/java/org/apache/qpid/server/store/berkeleydb/jmx/BDBHAMessageStoreManagerMBeanProvider.java @@ -26,11 +26,14 @@ import javax.management.StandardMBean; import org.apache.log4j.Logger; import org.apache.qpid.server.jmx.MBeanProvider; import org.apache.qpid.server.jmx.ManagedObject; +import org.apache.qpid.server.jmx.ManagedObjectRegistry; import org.apache.qpid.server.model.ConfiguredObject; import org.apache.qpid.server.model.VirtualHost; +import org.apache.qpid.server.model.VirtualHostNode; import org.apache.qpid.server.store.berkeleydb.BDBHAVirtualHost; import org.apache.qpid.server.store.berkeleydb.BDBMessageStore; import org.apache.qpid.server.store.berkeleydb.replication.ReplicatedEnvironmentFacade; +import org.apache.qpid.server.virtualhostnode.berkeleydb.BDBHAVirtualHostNode; /** * This provide will create a {@link BDBHAMessageStoreManagerMBean} if the child is a virtual @@ -49,15 +52,15 @@ public class BDBHAMessageStoreManagerMBeanProvider implements MBeanProvider @Override public boolean isChildManageableByMBean(ConfiguredObject child) { - return (child instanceof VirtualHost && BDBHAVirtualHost.TYPE.equals(child.getType())); + return child instanceof BDBHAVirtualHostNode; } @Override - public StandardMBean createMBean(ConfiguredObject child, StandardMBean parent) throws JMException + public ManagedObject createMBean(ConfiguredObject child, ManagedObjectRegistry registry) throws JMException { - VirtualHost virtualHostChild = (VirtualHost) child; + BDBHAVirtualHostNode virtualHostNode = (BDBHAVirtualHostNode) child; - BDBMessageStore messageStore = (BDBMessageStore) virtualHostChild.getMessageStore(); + BDBMessageStore messageStore = (BDBMessageStore) virtualHostNode.getConfigurationStore(); if (LOGGER.isDebugEnabled()) { @@ -65,7 +68,7 @@ public class BDBHAMessageStoreManagerMBeanProvider implements MBeanProvider } ReplicatedEnvironmentFacade replicatedEnvironmentFacade = (ReplicatedEnvironmentFacade)messageStore.getEnvironmentFacade(); - return new BDBHAMessageStoreManagerMBean(virtualHostChild.getName(), replicatedEnvironmentFacade, (ManagedObject) parent); + return new BDBHAMessageStoreManagerMBean(virtualHostNode.getGroupName(), replicatedEnvironmentFacade, registry); } @Override diff --git a/java/bdbstore/jmx/src/test/java/org/apache/qpid/server/store/berkeleydb/jmx/BDBHAMessageStoreManagerMBeanTest.java b/java/bdbstore/jmx/src/test/java/org/apache/qpid/server/store/berkeleydb/jmx/BDBHAMessageStoreManagerMBeanTest.java index fa16d1061a..6aeadde0f8 100644 --- a/java/bdbstore/jmx/src/test/java/org/apache/qpid/server/store/berkeleydb/jmx/BDBHAMessageStoreManagerMBeanTest.java +++ b/java/bdbstore/jmx/src/test/java/org/apache/qpid/server/store/berkeleydb/jmx/BDBHAMessageStoreManagerMBeanTest.java @@ -54,7 +54,6 @@ public class BDBHAMessageStoreManagerMBeanTest extends TestCase private ReplicatedEnvironmentFacade _replicatedEnvironmentFacade; private BDBHAMessageStoreManagerMBean _mBean; - private AMQManagedObject _mBeanParent; @Override protected void setUp() throws Exception @@ -62,9 +61,8 @@ public class BDBHAMessageStoreManagerMBeanTest extends TestCase super.setUp(); _replicatedEnvironmentFacade = mock(ReplicatedEnvironmentFacade.class); - _mBeanParent = mock(AMQManagedObject.class); - when(_mBeanParent.getRegistry()).thenReturn(mock(ManagedObjectRegistry.class)); - _mBean = new BDBHAMessageStoreManagerMBean(TEST_STORE_NAME, _replicatedEnvironmentFacade, _mBeanParent); + ManagedObjectRegistry registry = mock(ManagedObjectRegistry.class); + _mBean = new BDBHAMessageStoreManagerMBean(TEST_STORE_NAME, _replicatedEnvironmentFacade, registry); } @Override diff --git a/java/bdbstore/src/main/java/org/apache/qpid/server/store/berkeleydb/BDBHAVirtualHost.java b/java/bdbstore/src/main/java/org/apache/qpid/server/store/berkeleydb/BDBHAVirtualHost.java index 97d6355fa4..40781a6349 100644 --- a/java/bdbstore/src/main/java/org/apache/qpid/server/store/berkeleydb/BDBHAVirtualHost.java +++ b/java/bdbstore/src/main/java/org/apache/qpid/server/store/berkeleydb/BDBHAVirtualHost.java @@ -20,93 +20,34 @@ */ package org.apache.qpid.server.store.berkeleydb; -import java.util.HashMap; import java.util.Map; -import com.sleepycat.je.rep.StateChangeEvent; -import com.sleepycat.je.rep.StateChangeListener; -import org.apache.log4j.Logger; - -import org.apache.qpid.server.connection.IConnectionRegistry; -import org.apache.qpid.server.logging.messages.MessageStoreMessages; import org.apache.qpid.server.logging.subjects.MessageStoreLogSubject; -import org.apache.qpid.server.model.Broker; import org.apache.qpid.server.model.ManagedObject; -import org.apache.qpid.server.model.VirtualHost; -import org.apache.qpid.server.store.ConfiguredObjectRecordRecoveverAndUpgrader; +import org.apache.qpid.server.model.VirtualHostNode; import org.apache.qpid.server.store.DurableConfigurationStore; import org.apache.qpid.server.store.MessageStore; -import org.apache.qpid.server.store.berkeleydb.replication.ReplicatedEnvironmentFacade; -import org.apache.qpid.server.store.berkeleydb.replication.ReplicatedEnvironmentFacadeFactory; -import org.apache.qpid.server.store.handler.ConfiguredObjectRecordHandler; import org.apache.qpid.server.virtualhost.AbstractVirtualHost; -import org.apache.qpid.server.virtualhost.MessageStoreRecoverer; -import org.apache.qpid.server.virtualhost.VirtualHostState; @ManagedObject( category = false, type = "BDB_HA" ) public class BDBHAVirtualHost extends AbstractVirtualHost { public static final String TYPE = "BDB_HA"; - private static final Logger LOGGER = Logger.getLogger(BDBHAVirtualHost.class); - private BDBMessageStore _messageStore; + private final BDBMessageStore _messageStore; private MessageStoreLogSubject _messageStoreLogSubject; - BDBHAVirtualHost(final Map attributes, Broker broker) + protected BDBHAVirtualHost(final Map attributes, VirtualHostNode virtualHostNode) { - super(attributes, broker); - } - + super(attributes, virtualHostNode); - @Override - public void validate() - { - super.validate(); - Map attributes = getActualAttributes(); - @SuppressWarnings("unchecked") - Map messageStoreSettings = (Map)attributes.get(org.apache.qpid.server.model.VirtualHost.MESSAGE_STORE_SETTINGS); - if (messageStoreSettings == null) - { - throw new IllegalArgumentException("Attribute '"+ org.apache.qpid.server.model.VirtualHost.MESSAGE_STORE_SETTINGS + "' is required."); - } - - validateAttribute(MessageStore.STORE_PATH, String.class, messageStoreSettings); - validateAttribute(ReplicatedEnvironmentFacadeFactory.GROUP_NAME, String.class, messageStoreSettings); - validateAttribute(ReplicatedEnvironmentFacadeFactory.NODE_NAME, String.class, messageStoreSettings); - validateAttribute(ReplicatedEnvironmentFacadeFactory.NODE_ADDRESS, String.class, messageStoreSettings); - validateAttribute(ReplicatedEnvironmentFacadeFactory.HELPER_ADDRESS, String.class, messageStoreSettings); - } - - private void validateAttribute(String attrName, Class clazz, Map attributes) - { - Object attr = attributes.get(attrName); - if(!clazz.isInstance(attr)) - { - throw new IllegalArgumentException("Attribute '"+ attrName - +"' is required and must be of type "+clazz.getSimpleName()+"."); - } + _messageStore = (BDBMessageStore) virtualHostNode.getConfigurationStore(); + _messageStoreLogSubject = new MessageStoreLogSubject(getName(), _messageStore.getClass().getSimpleName()); } - protected void initialiseStorage(VirtualHost virtualHost) + @Override + protected void initialiseStorage() { - setState(VirtualHostState.PASSIVE); - - _messageStoreLogSubject = new MessageStoreLogSubject(getName(), BDBMessageStore.class.getSimpleName()); - _messageStore = new BDBMessageStore(new ReplicatedEnvironmentFacadeFactory()); - getEventLogger().message(_messageStoreLogSubject, MessageStoreMessages.CREATED()); - - Map messageStoreSettings = new HashMap(virtualHost.getMessageStoreSettings()); - messageStoreSettings.put(DurableConfigurationStore.IS_MESSAGE_STORE_TOO, true); - - _messageStore.openConfigurationStore(virtualHost, messageStoreSettings); - _messageStore.openMessageStore(virtualHost, messageStoreSettings); - - getEventLogger().message(_messageStoreLogSubject, MessageStoreMessages.STORE_LOCATION(_messageStore.getStoreLocation())); - - // Make the virtualhost model object a replication group listener - ReplicatedEnvironmentFacade environmentFacade = (ReplicatedEnvironmentFacade) _messageStore.getEnvironmentFacade(); - environmentFacade.setStateChangeListener(new BDBHAMessageStoreStateChangeListener()); - } @Override @@ -121,98 +62,10 @@ public class BDBHAVirtualHost extends AbstractVirtualHost return _messageStore; } - private void onMaster() - { - try - { - _messageStore.getEnvironmentFacade().getEnvironment().flushLog(true); - - if(isStoreEmpty()) - { - createDefaultExchanges(); - } - else - { - ConfiguredObjectRecordHandler upgraderRecoverer = - new ConfiguredObjectRecordRecoveverAndUpgrader(this, getDurableConfigurationRecoverers()); - _messageStore.visitConfiguredObjectRecords(upgraderRecoverer); - } - - new MessageStoreRecoverer(this, getMessageStoreLogSubject()).recover(); - - attainActivation(); - } - catch (Exception e) - { - LOGGER.error("Failed to activate on hearing MASTER change event", e); - } - } - - private void passivate() - { - VirtualHostState finalState = VirtualHostState.ERRORED; - - try - { - /* the approach here is not ideal as there is a race condition where a - * queue etc could be created while the virtual host is on the way to - * the passivated state. However the store state change from MASTER to UNKNOWN - * is documented as exceptionally rare. - */ - - getConnectionRegistry().close(IConnectionRegistry.VHOST_PASSIVATE_REPLY_TEXT); - removeHouseKeepingTasks(); - - getDtxRegistry().close(); - - finalState = VirtualHostState.PASSIVE; - } - finally - { - setState(finalState); - reportIfError(getVirtualHostState()); - } - } - @Override protected MessageStoreLogSubject getMessageStoreLogSubject() { return _messageStoreLogSubject; } - private class BDBHAMessageStoreStateChangeListener implements StateChangeListener - { - - @Override - public void stateChange(StateChangeEvent stateChangeEvent) throws RuntimeException - { - com.sleepycat.je.rep.ReplicatedEnvironment.State state = stateChangeEvent.getState(); - - if (LOGGER.isInfoEnabled()) - { - LOGGER.info("Received BDB event indicating transition to state " + state); - } - - switch (state) - { - case MASTER: - onMaster(); - break; - case REPLICA: - passivate(); - break; - case DETACHED: - LOGGER.error("BDB replicated node in detached state, therefore passivating."); - passivate(); - break; - case UNKNOWN: - LOGGER.warn("BDB replicated node in unknown state (hopefully temporarily)"); - break; - default: - LOGGER.error("Unexpected state change: " + state); - throw new IllegalStateException("Unexpected state change: " + state); - } - } - } - } diff --git a/java/bdbstore/src/main/java/org/apache/qpid/server/store/berkeleydb/BDBHAVirtualHostFactory.java b/java/bdbstore/src/main/java/org/apache/qpid/server/store/berkeleydb/BDBHAVirtualHostFactory.java index 2a28a61eca..cf011d06c1 100644 --- a/java/bdbstore/src/main/java/org/apache/qpid/server/store/berkeleydb/BDBHAVirtualHostFactory.java +++ b/java/bdbstore/src/main/java/org/apache/qpid/server/store/berkeleydb/BDBHAVirtualHostFactory.java @@ -20,13 +20,11 @@ */ package org.apache.qpid.server.store.berkeleydb; +import java.util.Map; + import org.apache.qpid.server.model.AbstractConfiguredObjectTypeFactory; -import org.apache.qpid.server.model.Broker; import org.apache.qpid.server.model.ConfiguredObject; - -import java.util.HashMap; -import java.util.Map; -import java.util.UUID; +import org.apache.qpid.server.model.VirtualHostNode; public class BDBHAVirtualHostFactory extends AbstractConfiguredObjectTypeFactory { @@ -40,9 +38,8 @@ public class BDBHAVirtualHostFactory extends AbstractConfiguredObjectTypeFactory public BDBHAVirtualHost createInstance(final Map attributes, final ConfiguredObject... parents) { - final Broker broker = getParent(Broker.class, parents); - return new BDBHAVirtualHost(attributes, broker); + final VirtualHostNode virtualHostNode = getParent(VirtualHostNode.class, parents); + return new BDBHAVirtualHost(attributes, virtualHostNode); } - } diff --git a/java/bdbstore/src/main/java/org/apache/qpid/server/store/berkeleydb/BDBMessageStore.java b/java/bdbstore/src/main/java/org/apache/qpid/server/store/berkeleydb/BDBMessageStore.java index 722a3a090d..5d9c2012a9 100644 --- a/java/bdbstore/src/main/java/org/apache/qpid/server/store/berkeleydb/BDBMessageStore.java +++ b/java/bdbstore/src/main/java/org/apache/qpid/server/store/berkeleydb/BDBMessageStore.java @@ -27,6 +27,7 @@ import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.HashMap; +import java.util.List; import java.util.Map; import java.util.Random; import java.util.UUID; @@ -36,6 +37,7 @@ import java.util.concurrent.atomic.AtomicLong; import org.apache.log4j.Logger; import org.apache.qpid.server.message.EnqueueableMessage; import org.apache.qpid.server.model.ConfiguredObject; +import org.apache.qpid.server.model.VirtualHostNode; import org.apache.qpid.server.store.ConfiguredObjectRecord; import org.apache.qpid.server.store.DurableConfigurationStore; import org.apache.qpid.server.store.Event; @@ -128,6 +130,9 @@ public class BDBMessageStore implements MessageStore, DurableConfigurationStore private volatile Committer _committer; + private boolean _isMessageStoreProvider; + + private String _storeLocation; public BDBMessageStore() { @@ -153,7 +158,8 @@ public class BDBMessageStore implements MessageStore, DurableConfigurationStore if (_environmentFacade == null) { EnvironmentFacadeTask[] initialisationTasks = null; - if (MapValueConverter.getBooleanAttribute(IS_MESSAGE_STORE_TOO, storeSettings, false)) + _isMessageStoreProvider = MapValueConverter.getBooleanAttribute(VirtualHostNode.IS_MESSAGE_STORE_PROVIDER, storeSettings, false); + if (_isMessageStoreProvider) { String[] databaseNames = new String[CONFIGURATION_STORE_DATABASE_NAMES.length + MESSAGE_STORE_DATABASE_NAMES.length]; System.arraycopy(CONFIGURATION_STORE_DATABASE_NAMES, 0, databaseNames, 0, CONFIGURATION_STORE_DATABASE_NAMES.length); @@ -165,6 +171,7 @@ public class BDBMessageStore implements MessageStore, DurableConfigurationStore initialisationTasks = new EnvironmentFacadeTask[]{new UpgradeTask(parent), new OpenDatabasesTask(CONFIGURATION_STORE_DATABASE_NAMES)}; } _environmentFacade = _environmentFacadeFactory.createEnvironmentFacade(storeSettings, initialisationTasks); + _storeLocation = _environmentFacade.getStoreLocation(); } else { @@ -274,6 +281,7 @@ public class BDBMessageStore implements MessageStore, DurableConfigurationStore { _environmentFacade = _environmentFacadeFactory.createEnvironmentFacade(messageStoreSettings, new UpgradeTask(parent), new OpenDatabasesTask(MESSAGE_STORE_DATABASE_NAMES), new DiskSpaceTask(), new MaxMessageIdTask()); + _storeLocation = _environmentFacade.getStoreLocation(); } _committer = _environmentFacade.createCommitter(parent.getName()); @@ -292,11 +300,7 @@ public class BDBMessageStore implements MessageStore, DurableConfigurationStore @Override public String getStoreLocation() { - if (_environmentFacade == null) - { - return null; - } - return _environmentFacade.getStoreLocation(); + return _storeLocation; } public EnvironmentFacade getEnvironmentFacade() @@ -355,6 +359,7 @@ public class BDBMessageStore implements MessageStore, DurableConfigurationStore try { _environmentFacade.close(); + _environmentFacade = null; } catch(DatabaseException e) { @@ -1514,21 +1519,22 @@ public class BDBMessageStore implements MessageStore, DurableConfigurationStore @Override public void onDelete() { - String storeLocation = getStoreLocation(); - - if (storeLocation != null) + if (!_configurationStoreOpen.get() && !_messageStoreOpen.get()) { - if (LOGGER.isDebugEnabled()) + if (_storeLocation != null) { - LOGGER.debug("Deleting store " + storeLocation); - } + if (LOGGER.isDebugEnabled()) + { + LOGGER.debug("Deleting store " + _storeLocation); + } - File location = new File(storeLocation); - if (location.exists()) - { - if (!FileUtils.delete(location, true)) + File location = new File(_storeLocation); + if (location.exists()) { - LOGGER.error("Cannot delete " + storeLocation); + if (!FileUtils.delete(location, true)) + { + LOGGER.error("Cannot delete " + _storeLocation); + } } } } @@ -1711,6 +1717,7 @@ public class BDBMessageStore implements MessageStore, DurableConfigurationStore checkMessageStoreOpen(); Cursor cursor = null; + List entries = new ArrayList(); try { cursor = getDeliveryDb().openCursor(null, null); @@ -1718,15 +1725,10 @@ public class BDBMessageStore implements MessageStore, DurableConfigurationStore QueueEntryBinding keyBinding = QueueEntryBinding.getInstance(); DatabaseEntry value = new DatabaseEntry(); - while (cursor.getNext(key, value, LockMode.RMW) == OperationStatus.SUCCESS) + while (cursor.getNext(key, value, LockMode.DEFAULT) == OperationStatus.SUCCESS) { QueueEntryKey entry = keyBinding.entryToObject(key); - UUID queueId = entry.getQueueId(); - long messageId = entry.getMessageId(); - if (!handler.handle(queueId, messageId)) - { - break; - } + entries.add(entry); } } catch (DatabaseException e) @@ -1737,6 +1739,17 @@ public class BDBMessageStore implements MessageStore, DurableConfigurationStore { closeCursorSafely(cursor); } + + for(QueueEntryKey entry : entries) + { + UUID queueId = entry.getQueueId(); + long messageId = entry.getMessageId(); + if (!handler.handle(queueId, messageId)) + { + break; + } + } + } @Override diff --git a/java/bdbstore/src/main/java/org/apache/qpid/server/store/berkeleydb/BDBMessageStoreFactory.java b/java/bdbstore/src/main/java/org/apache/qpid/server/store/berkeleydb/BDBMessageStoreFactory.java index ef749f2472..5c4633fe04 100644 --- a/java/bdbstore/src/main/java/org/apache/qpid/server/store/berkeleydb/BDBMessageStoreFactory.java +++ b/java/bdbstore/src/main/java/org/apache/qpid/server/store/berkeleydb/BDBMessageStoreFactory.java @@ -64,16 +64,18 @@ public class BDBMessageStoreFactory implements MessageStoreFactory, DurableConfi } } + } - @SuppressWarnings("unchecked") - Map configurationStoreSettings = (Map) attributes.get(VirtualHost.CONFIGURATION_STORE_SETTINGS); + @Override + public void validateConfigurationStoreSettings(Map configurationStoreSettings) + { if(configurationStoreSettings != null && getType().equals(configurationStoreSettings.get(DurableConfigurationStore.STORE_TYPE))) { Object storePath = configurationStoreSettings.get(DurableConfigurationStore.STORE_PATH); if(!(storePath instanceof String)) { - throw new IllegalArgumentException("Setting '"+ DurableConfigurationStore.STORE_PATH - +"' is required and must be of type String."); + throw new IllegalArgumentException("Durable configuration store setting '" + DurableConfigurationStore.STORE_PATH + + "' is required and must be of type String."); } } diff --git a/java/bdbstore/src/main/java/org/apache/qpid/server/store/berkeleydb/EnvironmentFacadeFactory.java b/java/bdbstore/src/main/java/org/apache/qpid/server/store/berkeleydb/EnvironmentFacadeFactory.java index 2e02a6cfed..83584e306f 100644 --- a/java/bdbstore/src/main/java/org/apache/qpid/server/store/berkeleydb/EnvironmentFacadeFactory.java +++ b/java/bdbstore/src/main/java/org/apache/qpid/server/store/berkeleydb/EnvironmentFacadeFactory.java @@ -24,7 +24,7 @@ import java.util.Map; public interface EnvironmentFacadeFactory { - public static final String ENVIRONMENT_CONFIGURATION = "bdbEnvironmentConfig"; + public static final String ENVIRONMENT_CONFIGURATION = "environmentConfiguration"; EnvironmentFacade createEnvironmentFacade(Map storeSettings, EnvironmentFacadeTask... initialisationTasks); diff --git a/java/bdbstore/src/main/java/org/apache/qpid/server/store/berkeleydb/StandardEnvironmentFacade.java b/java/bdbstore/src/main/java/org/apache/qpid/server/store/berkeleydb/StandardEnvironmentFacade.java index 6065be5fa9..b11fb6e873 100644 --- a/java/bdbstore/src/main/java/org/apache/qpid/server/store/berkeleydb/StandardEnvironmentFacade.java +++ b/java/bdbstore/src/main/java/org/apache/qpid/server/store/berkeleydb/StandardEnvironmentFacade.java @@ -232,5 +232,4 @@ public class StandardEnvironmentFacade implements EnvironmentFacade { return _storePath; } - } diff --git a/java/bdbstore/src/main/java/org/apache/qpid/server/store/berkeleydb/replication/ReplicatedEnvironmentFacade.java b/java/bdbstore/src/main/java/org/apache/qpid/server/store/berkeleydb/replication/ReplicatedEnvironmentFacade.java index b8192ea741..0b00800b04 100644 --- a/java/bdbstore/src/main/java/org/apache/qpid/server/store/berkeleydb/replication/ReplicatedEnvironmentFacade.java +++ b/java/bdbstore/src/main/java/org/apache/qpid/server/store/berkeleydb/replication/ReplicatedEnvironmentFacade.java @@ -1103,4 +1103,5 @@ public class ReplicatedEnvironmentFacade implements EnvironmentFacade, StateChan } } + } diff --git a/java/bdbstore/src/main/java/org/apache/qpid/server/store/berkeleydb/replication/ReplicatedEnvironmentFacadeFactory.java b/java/bdbstore/src/main/java/org/apache/qpid/server/store/berkeleydb/replication/ReplicatedEnvironmentFacadeFactory.java index 05944632b0..62035bb65f 100644 --- a/java/bdbstore/src/main/java/org/apache/qpid/server/store/berkeleydb/replication/ReplicatedEnvironmentFacadeFactory.java +++ b/java/bdbstore/src/main/java/org/apache/qpid/server/store/berkeleydb/replication/ReplicatedEnvironmentFacadeFactory.java @@ -20,31 +20,14 @@ */ package org.apache.qpid.server.store.berkeleydb.replication; -import com.sleepycat.je.Durability; -import com.sleepycat.je.Durability.ReplicaAckPolicy; -import com.sleepycat.je.Durability.SyncPolicy; -import org.apache.qpid.server.store.MessageStore; +import java.util.Map; + import org.apache.qpid.server.store.berkeleydb.EnvironmentFacade; import org.apache.qpid.server.store.berkeleydb.EnvironmentFacadeFactory; - -import java.util.Map; +import org.apache.qpid.server.virtualhostnode.berkeleydb.BDBHAVirtualHostNodeImpl; public class ReplicatedEnvironmentFacadeFactory implements EnvironmentFacadeFactory { - public static final String DURABILITY = "haDurability"; - public static final String GROUP_NAME = "haGroupName"; - public static final String HELPER_ADDRESS = "haHelperAddress"; - public static final String NODE_ADDRESS = "haNodeAddress"; - public static final String NODE_NAME = "haNodeName"; - public static final String REPLICATION_CONFIG = "haReplicationConfig"; - public static final String COALESCING_SYNC = "haCoalescingSync"; - public static final String DESIGNATED_PRIMARY = "haDesignatedPrimary"; - - private static final int DEFAULT_NODE_PRIORITY = 1; - private static final Durability DEFAULT_DURABILITY = new Durability(SyncPolicy.NO_SYNC, SyncPolicy.NO_SYNC, - ReplicaAckPolicy.SIMPLE_MAJORITY); - private static final boolean DEFAULT_COALESCING_SYNC = true; - @Override public EnvironmentFacade createEnvironmentFacade(final Map messageStoreSettings, EnvironmentFacadeTask... initialisationTasks) { @@ -53,77 +36,76 @@ public class ReplicatedEnvironmentFacadeFactory implements EnvironmentFacadeFact @Override public boolean isDesignatedPrimary() { - return convertBoolean(messageStoreSettings.get(DESIGNATED_PRIMARY), false); + return (Boolean)messageStoreSettings.get(BDBHAVirtualHostNodeImpl.DESIGNATED_PRIMARY); } @Override public boolean isCoalescingSync() { - return convertBoolean(messageStoreSettings.get(COALESCING_SYNC), DEFAULT_COALESCING_SYNC); + return (Boolean)messageStoreSettings.get(BDBHAVirtualHostNodeImpl.COALESCING_SYNC); } @Override public String getStorePath() { - return (String) messageStoreSettings.get(MessageStore.STORE_PATH); + return (String) messageStoreSettings.get(BDBHAVirtualHostNodeImpl.STORE_PATH); } @SuppressWarnings("unchecked") @Override public Map getParameters() { - return (Map) messageStoreSettings.get(EnvironmentFacadeFactory.ENVIRONMENT_CONFIGURATION); + return (Map) messageStoreSettings.get(BDBHAVirtualHostNodeImpl.ENVIRONMENT_CONFIGURATION); } @SuppressWarnings("unchecked") @Override public Map getReplicationParameters() { - return (Map) messageStoreSettings.get(REPLICATION_CONFIG); + return (Map) messageStoreSettings.get(BDBHAVirtualHostNodeImpl.REPLICATED_ENVIRONMENT_CONFIGURATION); } @Override public int getQuorumOverride() { - return 0; + return (Integer)messageStoreSettings.get(BDBHAVirtualHostNodeImpl.QUORUM_OVERRIDE); } @Override public int getPriority() { - return DEFAULT_NODE_PRIORITY; + return (Integer)messageStoreSettings.get(BDBHAVirtualHostNodeImpl.PRIORITY); } @Override public String getName() { - return (String)messageStoreSettings.get(NODE_NAME); + return (String)messageStoreSettings.get(BDBHAVirtualHostNodeImpl.NAME); } @Override public String getHostPort() { - return (String)messageStoreSettings.get(NODE_ADDRESS); + return (String)messageStoreSettings.get(BDBHAVirtualHostNodeImpl.ADDRESS); } @Override public String getHelperHostPort() { - return (String)messageStoreSettings.get(HELPER_ADDRESS); + return (String)messageStoreSettings.get(BDBHAVirtualHostNodeImpl.HELPER_ADDRESS); } @Override public String getGroupName() { - return (String)messageStoreSettings.get(GROUP_NAME); + return (String)messageStoreSettings.get(BDBHAVirtualHostNodeImpl.GROUP_NAME); } @Override public String getDurability() { - String durability = (String)messageStoreSettings.get(DURABILITY); - return durability == null ? DEFAULT_DURABILITY.toString() : durability; - } + return (String)messageStoreSettings.get(BDBHAVirtualHostNodeImpl.DURABILITY); + } }; return new ReplicatedEnvironmentFacade(configuration, initialisationTasks); @@ -135,24 +117,4 @@ public class ReplicatedEnvironmentFacadeFactory implements EnvironmentFacadeFact return ReplicatedEnvironmentFacade.TYPE; } - private boolean convertBoolean(final Object value, boolean defaultValue) - { - if(value instanceof Boolean) - { - return (Boolean) value; - } - else if(value instanceof String) - { - return Boolean.valueOf((String) value); - } - else if(value == null) - { - return defaultValue; - } - else - { - throw new IllegalArgumentException("Cannot convert type " + value.getClass() + " to a Boolean"); - } - } - } diff --git a/java/bdbstore/src/main/java/org/apache/qpid/server/store/berkeleydb/upgrade/UpgradeFrom7To8.java b/java/bdbstore/src/main/java/org/apache/qpid/server/store/berkeleydb/upgrade/UpgradeFrom7To8.java index 0d4e40fdcb..faccd2fdf4 100644 --- a/java/bdbstore/src/main/java/org/apache/qpid/server/store/berkeleydb/upgrade/UpgradeFrom7To8.java +++ b/java/bdbstore/src/main/java/org/apache/qpid/server/store/berkeleydb/upgrade/UpgradeFrom7To8.java @@ -78,7 +78,7 @@ public class UpgradeFrom7To8 extends AbstractStoreUpgrade Map virtualHostAttributes = new HashMap(); virtualHostAttributes.put("modelVersion", stringifiedConfigVersion); - + virtualHostAttributes.put("name", parent.getName()); String virtualHostName = parent.getName(); UUID virtualHostId = UUIDGenerator.generateVhostUUID(virtualHostName); ConfiguredObjectRecord virtualHostRecord = new org.apache.qpid.server.store.ConfiguredObjectRecordImpl(virtualHostId, "VirtualHost", virtualHostAttributes); diff --git a/java/bdbstore/src/main/java/org/apache/qpid/server/virtualhostnode/berkeleydb/BDBHAVirtualHostNode.java b/java/bdbstore/src/main/java/org/apache/qpid/server/virtualhostnode/berkeleydb/BDBHAVirtualHostNode.java new file mode 100644 index 0000000000..f0325b24f8 --- /dev/null +++ b/java/bdbstore/src/main/java/org/apache/qpid/server/virtualhostnode/berkeleydb/BDBHAVirtualHostNode.java @@ -0,0 +1,65 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT 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.virtualhostnode.berkeleydb; + +import java.util.Map; + +import org.apache.qpid.server.model.ManagedAttribute; + +public interface BDBHAVirtualHostNode> extends BDBVirtualHostNode +{ + public static final String GROUP_NAME = "groupName"; + public static final String ADDRESS = "address"; + public static final String HELPER_ADDRESS = "helperAddress"; + public static final String DURABILITY = "durability"; + public static final String COALESCING_SYNC = "coalescingSync"; + public static final String DESIGNATED_PRIMARY = "designatedPrimary"; + public static final String PRIORITY = "priority"; + public static final String QUORUM_OVERRIDE = "quorumOverride"; + public static final String REPLICATED_ENVIRONMENT_CONFIGURATION = "replicatedEnvironmentConfiguration"; + + @ManagedAttribute(automate = true, mandatory=true) + String getGroupName(); + + @ManagedAttribute(automate = true, mandatory=true) + String getAddress(); + + @ManagedAttribute(automate = true, mandatory=true) + String getHelperAddress(); + + @ManagedAttribute(automate = true, defaultValue = "NO_SYNC,NO_SYNC,SIMPLE_MAJORITY") + String getDurability(); + + @ManagedAttribute(automate = true, defaultValue = "true") + boolean isCoalescingSync(); + + @ManagedAttribute(automate = true, defaultValue = "false") + boolean isDesignatedPrimary(); + + @ManagedAttribute(automate = true, defaultValue = "1") + int getPriority(); + + @ManagedAttribute(automate = true, defaultValue = "0") + int getQuorumOverride(); + + @ManagedAttribute(automate = true) + Map getReplicatedEnvironmentConfiguration(); +} diff --git a/java/bdbstore/src/main/java/org/apache/qpid/server/virtualhostnode/berkeleydb/BDBHAVirtualHostNodeFactory.java b/java/bdbstore/src/main/java/org/apache/qpid/server/virtualhostnode/berkeleydb/BDBHAVirtualHostNodeFactory.java new file mode 100644 index 0000000000..5f988559e8 --- /dev/null +++ b/java/bdbstore/src/main/java/org/apache/qpid/server/virtualhostnode/berkeleydb/BDBHAVirtualHostNodeFactory.java @@ -0,0 +1,44 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ + +package org.apache.qpid.server.virtualhostnode.berkeleydb; + +import java.util.Map; + +import org.apache.qpid.server.model.AbstractConfiguredObjectTypeFactory; +import org.apache.qpid.server.model.Broker; +import org.apache.qpid.server.model.ConfiguredObject; + +public class BDBHAVirtualHostNodeFactory extends AbstractConfiguredObjectTypeFactory +{ + public BDBHAVirtualHostNodeFactory() + { + super(BDBHAVirtualHostNodeImpl.class); + } + + @Override + public BDBHAVirtualHostNodeImpl createInstance(Map attributes, ConfiguredObject... parents) + { + Broker broker = getParent(Broker.class, parents); + return new BDBHAVirtualHostNodeImpl(broker, attributes, broker.getTaskExecutor()); + } + +} diff --git a/java/bdbstore/src/main/java/org/apache/qpid/server/virtualhostnode/berkeleydb/BDBHAVirtualHostNodeImpl.java b/java/bdbstore/src/main/java/org/apache/qpid/server/virtualhostnode/berkeleydb/BDBHAVirtualHostNodeImpl.java new file mode 100644 index 0000000000..fff5c63337 --- /dev/null +++ b/java/bdbstore/src/main/java/org/apache/qpid/server/virtualhostnode/berkeleydb/BDBHAVirtualHostNodeImpl.java @@ -0,0 +1,537 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT 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.virtualhostnode.berkeleydb; + +import java.security.PrivilegedAction; +import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; +import java.util.concurrent.atomic.AtomicReference; + +import javax.security.auth.Subject; + +import org.apache.log4j.Logger; +import org.apache.qpid.server.configuration.updater.TaskExecutor; +import org.apache.qpid.server.logging.EventLogger; +import org.apache.qpid.server.logging.messages.ConfigStoreMessages; +import org.apache.qpid.server.logging.subjects.MessageStoreLogSubject; +import org.apache.qpid.server.model.AbstractConfiguredObject; +import org.apache.qpid.server.model.Broker; +import org.apache.qpid.server.model.BrokerModel; +import org.apache.qpid.server.model.ConfiguredObject; +import org.apache.qpid.server.model.ConfiguredObjectFactory; +import org.apache.qpid.server.model.LifetimePolicy; +import org.apache.qpid.server.model.ManagedAttributeField; +import org.apache.qpid.server.model.ManagedObject; +import org.apache.qpid.server.model.State; +import org.apache.qpid.server.model.SystemContext; +import org.apache.qpid.server.model.VirtualHost; +import org.apache.qpid.server.model.VirtualHostNode; +import org.apache.qpid.server.security.SecurityManager; +import org.apache.qpid.server.store.DurableConfigurationStore; +import org.apache.qpid.server.store.VirtualHostStoreUpgraderAndRecoverer; +import org.apache.qpid.server.store.berkeleydb.BDBHAVirtualHost; +import org.apache.qpid.server.store.berkeleydb.BDBHAVirtualHostFactory; +import org.apache.qpid.server.store.berkeleydb.BDBMessageStore; +import org.apache.qpid.server.store.berkeleydb.replication.ReplicatedEnvironmentFacade; +import org.apache.qpid.server.store.berkeleydb.replication.ReplicatedEnvironmentFacadeFactory; +import org.apache.qpid.server.virtualhost.VirtualHostState; + +import com.sleepycat.je.rep.StateChangeEvent; +import com.sleepycat.je.rep.StateChangeListener; + +@ManagedObject( category = false, type = "BDB_HA" ) +public class BDBHAVirtualHostNodeImpl extends AbstractConfiguredObject implements BDBHAVirtualHostNode +{ + private static final Logger LOGGER = Logger.getLogger(BDBHAVirtualHostNodeImpl.class); + + @ManagedAttributeField + private Map _environmentConfiguration; + + @ManagedAttributeField + private String _storePath; + + @ManagedAttributeField + private String _groupName; + + @ManagedAttributeField + private String _helperAddress; + + @ManagedAttributeField + private String _address; + + @ManagedAttributeField + private String _durability; + + @ManagedAttributeField + private boolean _coalescingSync; + + @ManagedAttributeField + private boolean _designatedPrimary; + + @ManagedAttributeField + private int _priority; + + @ManagedAttributeField + private int _quorumOverride; + + @ManagedAttributeField + private Map _replicatedEnvironmentConfiguration; + + //TODO: remove this field + @ManagedAttributeField + private boolean _messageStoreProvider; + + private final AtomicReference _state = new AtomicReference(State.INITIALISING); + private final Broker _broker; + private final ConfiguredObjectFactory _objectFactory; + private final EventLogger _eventLogger; + + private MessageStoreLogSubject _configurationStoreLogSubject; + private BDBMessageStore _durableConfigurationStore; + + @SuppressWarnings("rawtypes") + protected BDBHAVirtualHostNodeImpl(Broker broker, Map attributes, TaskExecutor taskExecutor) + { + super(Collections.,ConfiguredObject>singletonMap(Broker.class, broker), attributes, taskExecutor); + _broker = broker; + _objectFactory = _broker.getParent(SystemContext.class).getObjectFactory(); + SystemContext systemContext = _broker.getParent(SystemContext.class); + _eventLogger = systemContext.getEventLogger(); + + } + + @Override + public Map getEnvironmentConfiguration() + { + return _environmentConfiguration; + } + + @Override + public String getStorePath() + { + return _storePath; + } + + @Override + public boolean isMessageStoreProvider() + { + return true; + } + + @Override + public VirtualHost getVirtualHost() + { + @SuppressWarnings("rawtypes") + Collection children = getChildren(VirtualHost.class); + if (children.size() == 0) + { + return null; + } + else if (children.size() == 1) + { + return children.iterator().next(); + } + else + { + throw new IllegalStateException(this + " has an unexpected number of virtualhost children, size " + children.size()); + } + } + + + @Override + public DurableConfigurationStore getConfigurationStore() + { + return _durableConfigurationStore; + } + + @Override + public State getState() + { + return _state.get(); + } + + @Override + public LifetimePolicy getLifetimePolicy() + { + return LifetimePolicy.PERMANENT; + } + + @Override + public String getGroupName() + { + return _groupName; + } + + @Override + public String getHelperAddress() + { + return _helperAddress; + } + + @Override + public String getAddress() + { + return _address; + } + + @Override + public String getDurability() + { + return _durability; + } + + @Override + public boolean isCoalescingSync() + { + return _coalescingSync; + } + + @Override + public boolean isDesignatedPrimary() + { + return _designatedPrimary; + } + + @Override + public int getPriority() + { + return _priority; + } + + @Override + public int getQuorumOverride() + { + return _quorumOverride; + } + + @Override + public Map getReplicatedEnvironmentConfiguration() + { + return _replicatedEnvironmentConfiguration; + } + + @Override + protected boolean setState(State currentState, State desiredState) + { + State state = getState(); + + if (desiredState == State.DELETED) + { + if (state == State.ACTIVE) + { + setDesiredState(state, State.STOPPED); + } + if (state == State.INITIALISING || state == State.STOPPED || state == State.ERRORED) + { + if( _state.compareAndSet(state, State.DELETED)) + { + delete(); + return true; + } + } + else + { + throw new IllegalStateException("Cannot delete virtual host node in " + state + " state"); + } + } + else if (desiredState == State.ACTIVE) + { + if ((state == State.INITIALISING || state == State.STOPPED) && _state.compareAndSet(state, State.ACTIVE)) + { + try + { + activate(); + } + catch(RuntimeException e) + { + _state.compareAndSet(State.ACTIVE, State.ERRORED); + if (_broker.isManagementMode()) + { + LOGGER.warn("Failed to make " + this + " active.", e); + } + else + { + throw e; + } + } + return true; + } + else + { + throw new IllegalStateException("Cannot activate virtual host node in " + state + " state"); + } + } + else if (desiredState == State.STOPPED) + { + if (_state.compareAndSet(state, State.STOPPED)) + { + stop(); + return true; + } + else + { + throw new IllegalStateException("Cannot stop virtual host node in " + state + " state"); + } + } + return false; + } + + @Override + public String toString() + { + return "BDBHAVirtualHostNodeImpl [name=" + getName() + ", storePath=" + _storePath + ", groupName=" + _groupName + ", address=" + _address + + ", state=" + _state.get() + "]"; + } + + @SuppressWarnings({ "rawtypes", "unchecked" }) + @Override + protected C addChild(Class childClass, Map attributes, + ConfiguredObject... otherParents) + { + if(childClass == VirtualHost.class) + { + if ("MASTER".equals(((ReplicatedEnvironmentFacade)_durableConfigurationStore.getEnvironmentFacade()).getNodeState())) + { + BDBHAVirtualHostFactory virtualHostFactory = new BDBHAVirtualHostFactory(); + return (C) virtualHostFactory.create(getObjectFactory(), attributes,this); + } + else + { + ReplicaVirtualHost host = new ReplicaVirtualHost(attributes, this); + host.create(); + return (C) host; + } + } + return super.addChild(childClass, attributes, otherParents); + } + + private void activate() + { + if (LOGGER.isDebugEnabled()) + { + LOGGER.debug("Activating virtualhost node " + this); + } + + _durableConfigurationStore = new BDBMessageStore(new ReplicatedEnvironmentFacadeFactory()); + _configurationStoreLogSubject = new MessageStoreLogSubject(getName(), BDBMessageStore.class.getSimpleName()); + + Map attributes = buildAttributesForStore(); + + _durableConfigurationStore.openConfigurationStore(this, attributes); + + _eventLogger.message(_configurationStoreLogSubject, ConfigStoreMessages.CREATED()); + _eventLogger.message(_configurationStoreLogSubject, ConfigStoreMessages.STORE_LOCATION(getStorePath())); + + + ReplicatedEnvironmentFacade environmentFacade = (ReplicatedEnvironmentFacade) _durableConfigurationStore.getEnvironmentFacade(); + environmentFacade.setStateChangeListener(new BDBHAMessageStoreStateChangeListener()); + } + + private void stop() + { + destroyVirtualHostIfExist(); + _durableConfigurationStore.closeConfigurationStore(); + _eventLogger.message(_configurationStoreLogSubject, ConfigStoreMessages.CLOSE()); + } + + private void delete() + { + VirtualHost virtualHost = getVirtualHost(); + if (virtualHost != null) + { + virtualHost.setDesiredState(virtualHost.getState(), State.DELETED); + } + + //TODO: this needs to be called from parent + deleted(); + + _durableConfigurationStore.onDelete(); + + } + + private Map buildAttributesForStore() + { + final Map attributes = new HashMap(); + Subject.doAs(SecurityManager.getSubjectWithAddedSystemRights(), new PrivilegedAction() + { + @Override + public Object run() + { + for (String attributeName : getAttributeNames()) + { + Object value = getAttribute(attributeName); + attributes.put(attributeName, value); + } + return null; + } + }); + + attributes.put(IS_MESSAGE_STORE_PROVIDER, true); + return attributes; + } + + private void onMaster() + { + try + { + destroyVirtualHostIfExist(); + _durableConfigurationStore.getEnvironmentFacade().getEnvironment().flushLog(true); + + _eventLogger.message(_configurationStoreLogSubject, ConfigStoreMessages.RECOVERY_START()); + VirtualHostStoreUpgraderAndRecoverer upgraderAndRecoverer = new VirtualHostStoreUpgraderAndRecoverer(this, _objectFactory); + upgraderAndRecoverer.perform(_durableConfigurationStore); + _eventLogger.message(_configurationStoreLogSubject, ConfigStoreMessages.RECOVERY_COMPLETE()); + + VirtualHost host = getVirtualHost(); + + if (host == null) + { + if (LOGGER.isDebugEnabled()) + { + LOGGER.debug("Creating new virtualhost with name : " + getGroupName()); + } + + Map hostAttributes = new HashMap(); + hostAttributes.put(VirtualHost.MODEL_VERSION, BrokerModel.MODEL_VERSION); + hostAttributes.put(VirtualHost.NAME, getGroupName()); + hostAttributes.put(VirtualHost.TYPE, "BDB_HA"); + host = createChild(VirtualHost.class, hostAttributes); + } + else + { + if (LOGGER.isDebugEnabled()) + { + LOGGER.debug("Recovered virtualhost with name : " + getGroupName()); + } + + final VirtualHost recoveredHost = host; + Subject.doAs(SecurityManager.getSubjectWithAddedSystemRights(), new PrivilegedAction() + { + @Override + public Object run() + { + recoveredHost.open(); + return null; + } + }); + } + host.setDesiredState(host.getState(), State.ACTIVE); + + } + catch (Exception e) + { + LOGGER.error("Failed to activate on hearing MASTER change event", e); + } + } + + private void onReplica() + { + try + { + destroyVirtualHostIfExist(); + + Map hostAttributes = new HashMap(); + hostAttributes.put(VirtualHost.MODEL_VERSION, BrokerModel.MODEL_VERSION); + hostAttributes.put(VirtualHost.NAME, getGroupName()); + hostAttributes.put(VirtualHost.TYPE, "BDB_HA"); + createChild(VirtualHost.class, hostAttributes); + } + catch (Exception e) + { + LOGGER.error("Failed to create a replica host", e); + } + } + + private void onDetached() + { + destroyVirtualHostIfExist(); + } + + protected void destroyVirtualHostIfExist() + { + VirtualHost virtualHost = getVirtualHost(); + if (virtualHost!= null) + { + virtualHost.setDesiredState(virtualHost.getState(), State.STOPPED); + } + } + + private class BDBHAMessageStoreStateChangeListener implements StateChangeListener + { + @Override + public void stateChange(StateChangeEvent stateChangeEvent) throws RuntimeException + { + com.sleepycat.je.rep.ReplicatedEnvironment.State state = stateChangeEvent.getState(); + + if (LOGGER.isInfoEnabled()) + { + LOGGER.info("Received BDB event indicating transition to state " + state); + } + + switch (state) + { + case MASTER: + onMaster(); + break; + case REPLICA: + onReplica(); + break; + case DETACHED: + LOGGER.error("BDB replicated node in detached state, therefore passivating."); + onDetached(); + break; + case UNKNOWN: + LOGGER.warn("BDB replicated node in unknown state (hopefully temporarily)"); + break; + default: + LOGGER.error("Unexpected state change: " + state); + throw new IllegalStateException("Unexpected state change: " + state); + } + } + } + + private class ReplicaVirtualHost extends BDBHAVirtualHost + { + + ReplicaVirtualHost(Map attributes, VirtualHostNode virtualHostNode) + { + super(attributes, virtualHostNode); + setState(VirtualHostState.PASSIVE); + } + + @Override + public void onCreate() + { + } + + @Override + public boolean setState(State currentState, State desiredState) + { + if (desiredState != State.STOPPED) + { + throw new IllegalArgumentException("Unsupported state " + desiredState); + } + return super.setState(currentState, desiredState); + } + } +} diff --git a/java/bdbstore/src/main/java/org/apache/qpid/server/virtualhostnode/berkeleydb/BDBVirtualHostNode.java b/java/bdbstore/src/main/java/org/apache/qpid/server/virtualhostnode/berkeleydb/BDBVirtualHostNode.java new file mode 100644 index 0000000000..4785d47447 --- /dev/null +++ b/java/bdbstore/src/main/java/org/apache/qpid/server/virtualhostnode/berkeleydb/BDBVirtualHostNode.java @@ -0,0 +1,34 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT 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.virtualhostnode.berkeleydb; + +import java.util.Map; + +import org.apache.qpid.server.model.ManagedAttribute; +import org.apache.qpid.server.virtualhostnode.FileBasedVirtualHostNode; + +public interface BDBVirtualHostNode> extends FileBasedVirtualHostNode +{ + public static final String ENVIRONMENT_CONFIGURATION = "environmentConfiguration"; + + @ManagedAttribute(mandatory=false, automate=true) + Map getEnvironmentConfiguration(); +} \ No newline at end of file diff --git a/java/bdbstore/src/main/java/org/apache/qpid/server/virtualhostnode/berkeleydb/BDBVirtualHostNodeFactory.java b/java/bdbstore/src/main/java/org/apache/qpid/server/virtualhostnode/berkeleydb/BDBVirtualHostNodeFactory.java new file mode 100644 index 0000000000..80bf9d9520 --- /dev/null +++ b/java/bdbstore/src/main/java/org/apache/qpid/server/virtualhostnode/berkeleydb/BDBVirtualHostNodeFactory.java @@ -0,0 +1,44 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ + +package org.apache.qpid.server.virtualhostnode.berkeleydb; + +import java.util.Map; + +import org.apache.qpid.server.model.AbstractConfiguredObjectTypeFactory; +import org.apache.qpid.server.model.Broker; +import org.apache.qpid.server.model.ConfiguredObject; + +public class BDBVirtualHostNodeFactory extends AbstractConfiguredObjectTypeFactory +{ + public BDBVirtualHostNodeFactory() + { + super(BDBVirtualHostNodeImpl.class); + } + + @Override + public BDBVirtualHostNodeImpl createInstance(Map attributes, ConfiguredObject... parents) + { + Broker broker = getParent(Broker.class, parents); + return new BDBVirtualHostNodeImpl(broker, attributes, broker.getTaskExecutor()); + } + +} diff --git a/java/bdbstore/src/main/java/org/apache/qpid/server/virtualhostnode/berkeleydb/BDBVirtualHostNodeImpl.java b/java/bdbstore/src/main/java/org/apache/qpid/server/virtualhostnode/berkeleydb/BDBVirtualHostNodeImpl.java new file mode 100644 index 0000000000..806dd49256 --- /dev/null +++ b/java/bdbstore/src/main/java/org/apache/qpid/server/virtualhostnode/berkeleydb/BDBVirtualHostNodeImpl.java @@ -0,0 +1,71 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.server.virtualhostnode.berkeleydb; + +import java.util.Map; + +import org.apache.qpid.server.configuration.updater.TaskExecutor; +import org.apache.qpid.server.model.Broker; +import org.apache.qpid.server.model.ManagedAttributeField; +import org.apache.qpid.server.model.ManagedObject; +import org.apache.qpid.server.plugin.DurableConfigurationStoreFactory; +import org.apache.qpid.server.store.berkeleydb.BDBMessageStoreFactory; +import org.apache.qpid.server.virtualhostnode.AbstractStandardVirtualHostNode; + +@ManagedObject( category = false, type = "BDB" ) +public class BDBVirtualHostNodeImpl extends AbstractStandardVirtualHostNode implements BDBVirtualHostNode +{ + @ManagedAttributeField + private String _storePath; + + @ManagedAttributeField + private Map _environmentConfiguration; + + public BDBVirtualHostNodeImpl(Broker parent, Map attributes, TaskExecutor taskExecutor) + { + super(parent, attributes, taskExecutor); + } + + @Override + protected DurableConfigurationStoreFactory getDurableConfigurationStoreFactory() + { + return new BDBMessageStoreFactory(); + } + + @Override + public Map getEnvironmentConfiguration() + { + return _environmentConfiguration; + } + + @Override + public String getStorePath() + { + return _storePath; + } + + @Override + public String toString() + { + return getClass().getSimpleName() + " [id=" + getId() + ", name=" + getName() + ", storePath=" + getStorePath() + "]"; + } + +} diff --git a/java/bdbstore/src/main/resources/META-INF/services/org.apache.qpid.server.plugin.ConfiguredObjectTypeFactory b/java/bdbstore/src/main/resources/META-INF/services/org.apache.qpid.server.plugin.ConfiguredObjectTypeFactory index 0f8848cb74..a8855df6b7 100644 --- a/java/bdbstore/src/main/resources/META-INF/services/org.apache.qpid.server.plugin.ConfiguredObjectTypeFactory +++ b/java/bdbstore/src/main/resources/META-INF/services/org.apache.qpid.server.plugin.ConfiguredObjectTypeFactory @@ -17,3 +17,5 @@ # under the License. # org.apache.qpid.server.store.berkeleydb.BDBHAVirtualHostFactory +org.apache.qpid.server.virtualhostnode.berkeleydb.BDBVirtualHostNodeFactory +org.apache.qpid.server.virtualhostnode.berkeleydb.BDBHAVirtualHostNodeFactory diff --git a/java/bdbstore/src/test/java/org/apache/qpid/server/store/berkeleydb/BDBHAVirtualHostNodeTest.java b/java/bdbstore/src/test/java/org/apache/qpid/server/store/berkeleydb/BDBHAVirtualHostNodeTest.java new file mode 100644 index 0000000000..d54ed354f0 --- /dev/null +++ b/java/bdbstore/src/test/java/org/apache/qpid/server/store/berkeleydb/BDBHAVirtualHostNodeTest.java @@ -0,0 +1,193 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.server.store.berkeleydb; + +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +import java.io.File; +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; +import java.util.UUID; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.TimeUnit; + +import org.apache.qpid.server.configuration.updater.TaskExecutor; +import org.apache.qpid.server.model.Broker; +import org.apache.qpid.server.model.ConfigurationChangeListener; +import org.apache.qpid.server.model.ConfiguredObject; +import org.apache.qpid.server.model.State; +import org.apache.qpid.server.model.VirtualHost; +import org.apache.qpid.server.model.VirtualHostNode; +import org.apache.qpid.server.plugin.ConfiguredObjectTypeFactory; +import org.apache.qpid.server.store.DurableConfigurationStore; +import org.apache.qpid.server.util.BrokerTestHelper; +import org.apache.qpid.server.virtualhostnode.berkeleydb.BDBHAVirtualHostNode; +import org.apache.qpid.server.virtualhostnode.berkeleydb.BDBHAVirtualHostNodeFactory; +import org.apache.qpid.test.utils.QpidTestCase; +import org.apache.qpid.util.FileUtils; + +import com.sleepycat.je.rep.ReplicatedEnvironment; +import com.sleepycat.je.rep.ReplicationConfig; + +public class BDBHAVirtualHostNodeTest extends QpidTestCase +{ + + private Broker _broker; + private File _bdbStorePath; + private VirtualHostNode _virtualHostNode; + private TaskExecutor _taskExecutor; + + @Override + protected void setUp() throws Exception + { + super.setUp(); + + _broker = BrokerTestHelper.createBrokerMock(); + + _taskExecutor = new TaskExecutor(); + _taskExecutor.start(); + when(_broker.getTaskExecutor()).thenReturn(_taskExecutor); + + _bdbStorePath = new File(TMP_FOLDER, getTestName() + "." + System.currentTimeMillis()); + _bdbStorePath.deleteOnExit(); + } + + @Override + protected void tearDown() throws Exception + { + try + { + if (_virtualHostNode != null) + { + _virtualHostNode.setDesiredState(_virtualHostNode.getState(), State.STOPPED); + } + } + finally + { + if (_taskExecutor != null) + { + _taskExecutor.stopImmediately(); + } + if (_bdbStorePath != null) + { + FileUtils.delete(_bdbStorePath, true); + } + super.tearDown(); + } + } + + public void testCreateAndActivateVirtualHostNode() throws Exception + { + String repStreamTimeout = "2 h"; + String nodeName = "node"; + String groupName = "group"; + String nodeHostPort = "localhost:" + findFreePort(); + String helperHostPort = nodeHostPort; + String durability = "NO_SYNC,SYNC,NONE"; + UUID id = UUID.randomUUID(); + + Map attributes = new HashMap(); + attributes.put(BDBHAVirtualHostNode.TYPE, "BDB_HA"); + attributes.put(BDBHAVirtualHostNode.ID, id); + attributes.put(BDBHAVirtualHostNode.NAME, nodeName); + attributes.put(BDBHAVirtualHostNode.GROUP_NAME, groupName); + attributes.put(BDBHAVirtualHostNode.ADDRESS, nodeHostPort); + attributes.put(BDBHAVirtualHostNode.HELPER_ADDRESS, helperHostPort); + attributes.put(BDBHAVirtualHostNode.DURABILITY, durability); + attributes.put(BDBHAVirtualHostNode.STORE_PATH, _bdbStorePath); + attributes.put(BDBHAVirtualHostNode.REPLICATED_ENVIRONMENT_CONFIGURATION, + Collections.singletonMap(ReplicationConfig.REP_STREAM_TIMEOUT, repStreamTimeout)); + + ConfiguredObjectTypeFactory factory = new BDBHAVirtualHostNodeFactory(); + + BDBHAVirtualHostNode node = (BDBHAVirtualHostNode) factory.create(null, attributes, _broker); + + final CountDownLatch virtualHostAddedLatch = new CountDownLatch(1); + final CountDownLatch virtualHostStateChangeLatch = new CountDownLatch(1); + node.addChangeListener(new ConfigurationChangeListener() + { + @Override + public void stateChanged(ConfiguredObject object, State oldState, State newState) + { + if (object instanceof VirtualHost) + { + virtualHostStateChangeLatch.countDown(); + } + } + + @Override + public void childRemoved(ConfiguredObject object, ConfiguredObject child) + { + } + + @Override + public void childAdded(ConfiguredObject object, ConfiguredObject child) + { + child.addChangeListener(this); + virtualHostAddedLatch.countDown(); + } + + @Override + public void attributeSet(ConfiguredObject object, String attributeName, Object oldAttributeValue, Object newAttributeValue) + { + } + }); + assertEquals(State.ACTIVE, node.setDesiredState(node.getState(), State.ACTIVE)); + + DurableConfigurationStore store = node.getConfigurationStore(); + assertNotNull(store); + + BDBMessageStore bdbMessageStore = (BDBMessageStore) store; + ReplicatedEnvironment environment = (ReplicatedEnvironment) bdbMessageStore.getEnvironmentFacade().getEnvironment(); + ReplicationConfig replicationConfig = environment.getRepConfig(); + + assertEquals(nodeName, environment.getNodeName()); + assertEquals(groupName, environment.getGroup().getName()); + assertEquals(nodeHostPort, replicationConfig.getNodeHostPort()); + assertEquals(helperHostPort, replicationConfig.getHelperHosts()); + assertEquals(durability, environment.getConfig().getDurability().toString()); + assertEquals("Unexpected JE replication stream timeout", repStreamTimeout, replicationConfig.getConfigParam(ReplicationConfig.REP_STREAM_TIMEOUT)); + + assertTrue("Virtual host child has not been added", virtualHostAddedLatch.await(30, TimeUnit.SECONDS)); + assertTrue("Virtual host child has not had a state change", virtualHostStateChangeLatch.await(30, TimeUnit.SECONDS)); + VirtualHost virtualHost = node.getVirtualHost(); + assertNotNull("Virtual host child was not added", virtualHost); + assertEquals("Unexpected virtual host name", groupName, virtualHost.getName()); + assertEquals("Unexpected virtual host store", store, virtualHost.getMessageStore()); + assertEquals("Unexpected virtual host state", State.ACTIVE, virtualHost.getState()); + + State currentState = node.setDesiredState(State.ACTIVE, State.STOPPED); + assertEquals("Unexpected state returned after stop", State.STOPPED, currentState); + assertEquals("Unexpected state", State.STOPPED, node.getState()); + + assertNull("Virtual host is not destroyed", node.getVirtualHost()); + + currentState = node.setDesiredState(State.STOPPED, State.DELETED); + assertEquals("Unexpected state returned after delete", State.DELETED, currentState); + assertEquals("Unexpected state", State.DELETED, node.getState()); + assertFalse("Store still exists", _bdbStorePath.exists()); + } + +} + + diff --git a/java/bdbstore/src/test/java/org/apache/qpid/server/store/berkeleydb/VirtualHostTest.java b/java/bdbstore/src/test/java/org/apache/qpid/server/store/berkeleydb/VirtualHostTest.java deleted file mode 100644 index abaaaa6d72..0000000000 --- a/java/bdbstore/src/test/java/org/apache/qpid/server/store/berkeleydb/VirtualHostTest.java +++ /dev/null @@ -1,159 +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.store.berkeleydb; - -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; - -import java.io.File; -import java.util.Collections; -import java.util.HashMap; -import java.util.Map; -import java.util.UUID; - -import com.sleepycat.je.rep.ReplicatedEnvironment; -import com.sleepycat.je.rep.ReplicationConfig; - -import org.apache.qpid.server.configuration.ConfigurationEntryStore; -import org.apache.qpid.server.configuration.RecovererProvider; -import org.apache.qpid.server.configuration.updater.TaskExecutor; -import org.apache.qpid.server.model.Broker; -import org.apache.qpid.server.model.BrokerModel; -import org.apache.qpid.server.model.ConfiguredObject; -import org.apache.qpid.server.model.ConfiguredObjectFactory; -import org.apache.qpid.server.model.ConfiguredObjectFactoryImpl; -import org.apache.qpid.server.model.State; -import org.apache.qpid.server.model.VirtualHost; -import org.apache.qpid.server.stats.StatisticsGatherer; -import org.apache.qpid.server.store.MessageStore; -import org.apache.qpid.server.store.berkeleydb.replication.ReplicatedEnvironmentFacadeFactory; -import org.apache.qpid.server.util.BrokerTestHelper; -import org.apache.qpid.test.utils.QpidTestCase; -import org.apache.qpid.util.FileUtils; - -public class VirtualHostTest extends QpidTestCase -{ - - private Broker _broker; - private StatisticsGatherer _statisticsGatherer; - private RecovererProvider _recovererProvider; - private File _bdbStorePath; - private VirtualHost _host; - private ConfigurationEntryStore _store; - private TaskExecutor _taskExecutor; - - @Override - protected void setUp() throws Exception - { - super.setUp(); - - _store = mock(ConfigurationEntryStore.class); - _broker = BrokerTestHelper.createBrokerMock(); - _taskExecutor = new TaskExecutor(); - _taskExecutor.start(); - when(_broker.getTaskExecutor()).thenReturn(_taskExecutor); - - _statisticsGatherer = mock(StatisticsGatherer.class); - - _bdbStorePath = new File(TMP_FOLDER, getTestName() + "." + System.currentTimeMillis()); - _bdbStorePath.deleteOnExit(); - } - - @Override - protected void tearDown() throws Exception - { - try - { - if (_host != null) - { - _host.setDesiredState(_host.getState(), State.STOPPED); - } - } - finally - { - _taskExecutor.stopImmediately(); - - if (_bdbStorePath != null) - { - FileUtils.delete(_bdbStorePath, true); - } - super.tearDown(); - } - } - - public void testCreateBdbHaVirtualHostFromConfigurationEntry() - { - String repStreamTimeout = "2 h"; - String nodeName = "node"; - String groupName = "group"; - String nodeHostPort = "localhost:" + findFreePort(); - String helperHostPort = nodeHostPort; - String durability = "NO_SYNC,SYNC,NONE"; - String virtualHostName = getName(); - - Map messageStoreSettings = new HashMap(); - messageStoreSettings.put(ReplicatedEnvironmentFacadeFactory.NODE_NAME, nodeName); - messageStoreSettings.put(ReplicatedEnvironmentFacadeFactory.GROUP_NAME, groupName); - messageStoreSettings.put(ReplicatedEnvironmentFacadeFactory.NODE_ADDRESS, nodeHostPort); - messageStoreSettings.put(ReplicatedEnvironmentFacadeFactory.HELPER_ADDRESS, helperHostPort); - messageStoreSettings.put(ReplicatedEnvironmentFacadeFactory.DURABILITY, durability); - - messageStoreSettings.put(MessageStore.STORE_PATH, _bdbStorePath.getAbsolutePath()); - messageStoreSettings.put(ReplicatedEnvironmentFacadeFactory.REPLICATION_CONFIG, - Collections.singletonMap(ReplicationConfig.REP_STREAM_TIMEOUT, repStreamTimeout)); - - Map virtualHostAttributes = new HashMap(); - virtualHostAttributes.put(VirtualHost.NAME, virtualHostName); - virtualHostAttributes.put(VirtualHost.TYPE, BDBHAVirtualHost.TYPE); - virtualHostAttributes.put(VirtualHost.MESSAGE_STORE_SETTINGS, messageStoreSettings); - - _host = createHost(virtualHostAttributes); - _host.setDesiredState(State.INITIALISING, State.ACTIVE); - - assertEquals("Unexpected virtual host name", virtualHostName, _host.getName()); - assertEquals("Unexpected host type", BDBHAVirtualHost.TYPE, _host.getType()); - - assertEquals(messageStoreSettings, _host.getMessageStoreSettings()); - - BDBMessageStore messageStore = (BDBMessageStore) _host.getMessageStore(); - ReplicatedEnvironment environment = (ReplicatedEnvironment) messageStore.getEnvironmentFacade().getEnvironment(); - ReplicationConfig replicationConfig = environment.getRepConfig(); - - assertEquals(nodeName, environment.getNodeName()); - assertEquals(groupName, environment.getGroup().getName()); - assertEquals(nodeHostPort, replicationConfig.getNodeHostPort()); - assertEquals(helperHostPort, replicationConfig.getHelperHosts()); - assertEquals(durability, environment.getConfig().getDurability().toString()); - assertEquals("Unexpected JE replication stream timeout", repStreamTimeout, replicationConfig.getConfigParam(ReplicationConfig.REP_STREAM_TIMEOUT)); - } - - - private VirtualHost createHost(Map attributes) - { - ConfiguredObjectFactory factory = new ConfiguredObjectFactoryImpl(BrokerModel.getInstance()); - attributes = new HashMap(attributes); - attributes.put(ConfiguredObject.ID, UUID.randomUUID()); - return (VirtualHost) factory.create(VirtualHost.class, attributes,_broker); - } - -} - - diff --git a/java/bdbstore/src/test/java/org/apache/qpid/server/store/berkeleydb/upgrade/UpgradeFrom7To8Test.java b/java/bdbstore/src/test/java/org/apache/qpid/server/store/berkeleydb/upgrade/UpgradeFrom7To8Test.java index 57adc5afe4..9bd5c96fe6 100644 --- a/java/bdbstore/src/test/java/org/apache/qpid/server/store/berkeleydb/upgrade/UpgradeFrom7To8Test.java +++ b/java/bdbstore/src/test/java/org/apache/qpid/server/store/berkeleydb/upgrade/UpgradeFrom7To8Test.java @@ -160,6 +160,7 @@ public class UpgradeFrom7To8Test extends AbstractUpgradeTestCase { Map expectedVirtualHostEntry = new HashMap(); expectedVirtualHostEntry.put("modelVersion", modelVersion); + expectedVirtualHostEntry.put(VirtualHost.NAME, getVirtualHost().getName()); UUID expectedUUID = UUIDGenerator.generateVhostUUID(getVirtualHost().getName()); return Collections.singletonMap(expectedUUID, expectedVirtualHostEntry); diff --git a/java/bdbstore/systests/src/main/java/org/apache/qpid/server/store/berkeleydb/BDBBackupTest.java b/java/bdbstore/systests/src/main/java/org/apache/qpid/server/store/berkeleydb/BDBBackupTest.java index c682f44d60..fab889a49f 100644 --- a/java/bdbstore/systests/src/main/java/org/apache/qpid/server/store/berkeleydb/BDBBackupTest.java +++ b/java/bdbstore/systests/src/main/java/org/apache/qpid/server/store/berkeleydb/BDBBackupTest.java @@ -31,9 +31,8 @@ import javax.jms.MessageConsumer; import javax.jms.Session; import org.apache.log4j.Logger; - -import org.apache.qpid.server.model.VirtualHost; -import org.apache.qpid.server.store.MessageStore; +import org.apache.qpid.server.model.VirtualHostNode; +import org.apache.qpid.server.virtualhostnode.berkeleydb.BDBVirtualHostNode; import org.apache.qpid.test.utils.Piper; import org.apache.qpid.test.utils.QpidBrokerTestCase; import org.apache.qpid.util.FileUtils; @@ -63,9 +62,9 @@ public class BDBBackupTest extends QpidBrokerTestCase super.setUp(); _backupToDir = new File(SYSTEM_TMP_DIR + File.separator + getTestName()); _backupToDir.mkdirs(); - Map virtualHostAttributes = getBrokerConfiguration().getObjectAttributes(VirtualHost.class,TEST_VHOST); - Map messageStoreSettings = (Map) virtualHostAttributes.get(VirtualHost.MESSAGE_STORE_SETTINGS); - _backupFromDir = new File(Strings.expand((String) messageStoreSettings.get(MessageStore.STORE_PATH))); + + Map virtualHostNodeAttributes = getBrokerConfiguration().getObjectAttributes(VirtualHostNode.class, TEST_VHOST); + _backupFromDir = new File(Strings.expand((String) virtualHostNodeAttributes.get(BDBVirtualHostNode.STORE_PATH))); boolean fromDirExistsAndIsDir = _backupFromDir.isDirectory(); assertTrue("backupFromDir " + _backupFromDir + " should already exist", fromDirExistsAndIsDir); } diff --git a/java/bdbstore/systests/src/main/java/org/apache/qpid/server/store/berkeleydb/BDBUpgradeTest.java b/java/bdbstore/systests/src/main/java/org/apache/qpid/server/store/berkeleydb/BDBUpgradeTest.java index 55d4c78ccb..491856d953 100644 --- a/java/bdbstore/systests/src/main/java/org/apache/qpid/server/store/berkeleydb/BDBUpgradeTest.java +++ b/java/bdbstore/systests/src/main/java/org/apache/qpid/server/store/berkeleydb/BDBUpgradeTest.java @@ -42,18 +42,17 @@ import javax.jms.TopicSubscriber; import javax.management.openmbean.CompositeData; import javax.management.openmbean.TabularDataSupport; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - import org.apache.qpid.management.common.mbeans.ManagedExchange; import org.apache.qpid.management.common.mbeans.ManagedQueue; -import org.apache.qpid.server.model.VirtualHost; -import org.apache.qpid.server.store.MessageStore; +import org.apache.qpid.server.model.VirtualHostNode; +import org.apache.qpid.server.virtualhostnode.berkeleydb.BDBVirtualHostNode; 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.util.FileUtils; import org.apache.qpid.util.Strings; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * Tests upgrading a BDB store on broker startup. @@ -86,10 +85,8 @@ public class BDBUpgradeTest extends QpidBrokerTestCase public void setUp() throws Exception { assertNotNull("QPID_WORK must be set", QPID_WORK_ORIG); - Map virtualHostAttributes = getBrokerConfiguration().getObjectAttributes(VirtualHost.class,TestBrokerConfiguration.ENTRY_NAME_VIRTUAL_HOST); - @SuppressWarnings("unchecked") - Map messageStoreSettings = (Map) virtualHostAttributes.get(VirtualHost.MESSAGE_STORE_SETTINGS); - _storeLocation = Strings.expand((String)messageStoreSettings.get(MessageStore.STORE_PATH)); + Map virtualHostNodeAttributes = getBrokerConfiguration().getObjectAttributes(VirtualHostNode.class, TestBrokerConfiguration.ENTRY_NAME_VIRTUAL_HOST); + _storeLocation = Strings.expand((String)virtualHostNodeAttributes.get(BDBVirtualHostNode.STORE_PATH)); //Clear the two target directories if they exist. File directory = new File(_storeLocation); diff --git a/java/bdbstore/systests/src/main/java/org/apache/qpid/server/store/berkeleydb/HAClusterBlackboxTest.java b/java/bdbstore/systests/src/main/java/org/apache/qpid/server/store/berkeleydb/HAClusterBlackboxTest.java index 0464269efc..0de61d68cd 100644 --- a/java/bdbstore/systests/src/main/java/org/apache/qpid/server/store/berkeleydb/HAClusterBlackboxTest.java +++ b/java/bdbstore/systests/src/main/java/org/apache/qpid/server/store/berkeleydb/HAClusterBlackboxTest.java @@ -146,7 +146,6 @@ public class HAClusterBlackboxTest extends QpidBrokerTestCase assertEquals("Failover occurred unexpectedly", 1L, _failoverLatch.getCount()); } - @Override public void failoverComplete() { diff --git a/java/bdbstore/systests/src/main/java/org/apache/qpid/server/store/berkeleydb/HAClusterTwoNodeTest.java b/java/bdbstore/systests/src/main/java/org/apache/qpid/server/store/berkeleydb/HAClusterTwoNodeTest.java index 248cd7dc3d..b414905ddc 100644 --- a/java/bdbstore/systests/src/main/java/org/apache/qpid/server/store/berkeleydb/HAClusterTwoNodeTest.java +++ b/java/bdbstore/systests/src/main/java/org/apache/qpid/server/store/berkeleydb/HAClusterTwoNodeTest.java @@ -169,8 +169,8 @@ public class HAClusterTwoNodeTest extends QpidBrokerTestCase public void testSecondaryDesignatedAsPrimaryAfterOrginalPrimaryStopped() throws Exception { startCluster(true); - _clusterCreator.stopNode(_clusterCreator.getBrokerPortNumberOfPrimary()); final ManagedBDBHAMessageStore storeBean = getStoreBeanForNodeAtBrokerPort(_clusterCreator.getBrokerPortNumberOfSecondaryNode()); + _clusterCreator.stopNode(_clusterCreator.getBrokerPortNumberOfPrimary()); assertFalse("Expected node to NOT be set as designated primary", storeBean.getDesignatedPrimary()); storeBean.setDesignatedPrimary(true); diff --git a/java/bdbstore/systests/src/main/java/org/apache/qpid/server/store/berkeleydb/HATestClusterCreator.java b/java/bdbstore/systests/src/main/java/org/apache/qpid/server/store/berkeleydb/HATestClusterCreator.java index 78d58224f9..96a75db2cc 100644 --- a/java/bdbstore/systests/src/main/java/org/apache/qpid/server/store/berkeleydb/HATestClusterCreator.java +++ b/java/bdbstore/systests/src/main/java/org/apache/qpid/server/store/berkeleydb/HATestClusterCreator.java @@ -38,19 +38,18 @@ import java.util.concurrent.TimeUnit; import javax.jms.Connection; -import com.sleepycat.je.rep.ReplicationConfig; import org.apache.commons.lang.StringUtils; import org.apache.log4j.Logger; - import org.apache.qpid.client.AMQConnection; import org.apache.qpid.client.AMQConnectionURL; -import org.apache.qpid.server.model.VirtualHost; -import org.apache.qpid.server.store.MessageStore; -import org.apache.qpid.server.store.berkeleydb.replication.ReplicatedEnvironmentFacadeFactory; +import org.apache.qpid.server.model.VirtualHostNode; +import org.apache.qpid.server.virtualhostnode.berkeleydb.BDBHAVirtualHostNode; import org.apache.qpid.test.utils.QpidBrokerTestCase; import org.apache.qpid.test.utils.TestBrokerConfiguration; import org.apache.qpid.url.URLSyntaxException; +import com.sleepycat.je.rep.ReplicationConfig; + public class HATestClusterCreator { protected static final Logger LOGGER = Logger.getLogger(HATestClusterCreator.class); @@ -82,7 +81,7 @@ public class HATestClusterCreator { _testcase = testcase; _virtualHostName = virtualHostName; - _groupName = "group" + _testcase.getName(); + _groupName = virtualHostName; _ipAddressOfBroker = getIpAddressOfBrokerHost(); _numberOfNodes = numberOfNodes; _bdbHelperPort = 0; @@ -104,21 +103,23 @@ public class HATestClusterCreator } String nodeName = getNodeNameForNodeAt(bdbPort); - Map messageStoreSettings = new HashMap(); - messageStoreSettings.put(MessageStore.STORE_PATH, System.getProperty("QPID_WORK") + File.separator + brokerPort); - messageStoreSettings.put(ReplicatedEnvironmentFacadeFactory.GROUP_NAME, _groupName); - messageStoreSettings.put(ReplicatedEnvironmentFacadeFactory.NODE_NAME, nodeName); - messageStoreSettings.put(ReplicatedEnvironmentFacadeFactory.NODE_ADDRESS, getNodeHostPortForNodeAt(bdbPort)); - messageStoreSettings.put(ReplicatedEnvironmentFacadeFactory.HELPER_ADDRESS, getHelperHostPort()); + + Map virtualHostNodeAttributes = new HashMap(); + virtualHostNodeAttributes.put(BDBHAVirtualHostNode.STORE_PATH, System.getProperty("QPID_WORK") + File.separator + brokerPort); + virtualHostNodeAttributes.put(BDBHAVirtualHostNode.GROUP_NAME, _groupName); + virtualHostNodeAttributes.put(BDBHAVirtualHostNode.NAME, nodeName); + virtualHostNodeAttributes.put(BDBHAVirtualHostNode.ADDRESS, getNodeHostPortForNodeAt(bdbPort)); + virtualHostNodeAttributes.put(BDBHAVirtualHostNode.HELPER_ADDRESS, getHelperHostPort()); + virtualHostNodeAttributes.put(BDBHAVirtualHostNode.TYPE, "BDB_HA"); + Map repSettings = new HashMap(); repSettings.put(ReplicationConfig.INSUFFICIENT_REPLICAS_TIMEOUT, "2 s"); repSettings.put(ReplicationConfig.ELECTIONS_PRIMARY_RETRIES, "0"); - messageStoreSettings.put(ReplicatedEnvironmentFacadeFactory.REPLICATION_CONFIG, repSettings ); + virtualHostNodeAttributes.put(BDBHAVirtualHostNode.REPLICATED_ENVIRONMENT_CONFIGURATION, repSettings); TestBrokerConfiguration brokerConfiguration = _testcase.getBrokerConfiguration(brokerPort); brokerConfiguration.addJmxManagementConfiguration(); - brokerConfiguration.setObjectAttribute(VirtualHost.class, _virtualHostName, VirtualHost.TYPE, BDBHAVirtualHost.TYPE); - brokerConfiguration.setObjectAttribute(VirtualHost.class, _virtualHostName, VirtualHost.MESSAGE_STORE_SETTINGS, messageStoreSettings); + brokerConfiguration.setObjectAttributes(VirtualHostNode.class, _virtualHostName, virtualHostNodeAttributes); brokerPort = _testcase.getNextAvailable(bdbPort + 1); } @@ -132,10 +133,8 @@ public class HATestClusterCreator throw new IllegalArgumentException("Only two nodes groups have the concept of primary"); } TestBrokerConfiguration config = _testcase.getBrokerConfiguration(_primaryBrokerPort); - @SuppressWarnings("unchecked") - Map storeSetting = (Map) config.getObjectAttributes(VirtualHost.class, _virtualHostName).get(VirtualHost.MESSAGE_STORE_SETTINGS); - storeSetting.put(ReplicatedEnvironmentFacadeFactory.DESIGNATED_PRIMARY, designatedPrimary); - config.setObjectAttribute(VirtualHost.class, _virtualHostName, VirtualHost.MESSAGE_STORE_SETTINGS, storeSetting); + String nodeName = getNodeNameForNodeAt(_brokerPortToBdbPortMap.get(_primaryBrokerPort)); + config.setObjectAttribute(VirtualHostNode.class, nodeName, BDBHAVirtualHostNode.DESIGNATED_PRIMARY, designatedPrimary); config.setSaved(false); } @@ -369,15 +368,15 @@ public class HATestClusterCreator public void modifyClusterNodeBdbAddress(int brokerPortNumberToBeMoved, int newBdbPort) { TestBrokerConfiguration config = _testcase.getBrokerConfiguration(brokerPortNumberToBeMoved); + String nodeName = getNodeNameForNodeAt(_brokerPortToBdbPortMap.get(brokerPortNumberToBeMoved)); + + Map objectAttributes = config.getObjectAttributes(VirtualHostNode.class, nodeName); - @SuppressWarnings("unchecked") - Map storeSetting = (Map) config.getObjectAttributes(VirtualHost.class, _virtualHostName).get(VirtualHost.MESSAGE_STORE_SETTINGS); - String oldBdbHostPort = (String) storeSetting.get(ReplicatedEnvironmentFacadeFactory.NODE_ADDRESS); + String oldBdbHostPort = (String)objectAttributes.get(BDBHAVirtualHostNode.ADDRESS); String[] oldHostAndPort = StringUtils.split(oldBdbHostPort, ":"); String oldHost = oldHostAndPort[0]; String newBdbHostPort = oldHost + ":" + newBdbPort; - storeSetting.put(ReplicatedEnvironmentFacadeFactory.NODE_ADDRESS, newBdbHostPort); - config.setObjectAttribute(VirtualHost.class, _virtualHostName, VirtualHost.MESSAGE_STORE_SETTINGS, storeSetting); + config.setObjectAttribute(VirtualHostNode.class, nodeName, BDBHAVirtualHostNode.ADDRESS, newBdbHostPort); config.setSaved(false); } diff --git a/java/broker-core/src/main/java/org/apache/qpid/server/configuration/startup/BrokerStoreUpgrader.java b/java/broker-core/src/main/java/org/apache/qpid/server/configuration/startup/BrokerStoreUpgrader.java index 79d1595b27..1a942a2e4a 100644 --- a/java/broker-core/src/main/java/org/apache/qpid/server/configuration/startup/BrokerStoreUpgrader.java +++ b/java/broker-core/src/main/java/org/apache/qpid/server/configuration/startup/BrokerStoreUpgrader.java @@ -1,4 +1,4 @@ -package org.apache.qpid.server.configuration.startup;/* +/* * * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file @@ -18,7 +18,7 @@ package org.apache.qpid.server.configuration.startup;/* * under the License. * */ - +package org.apache.qpid.server.configuration.startup; import java.util.Arrays; import java.util.Collection; import java.util.Collections; @@ -30,7 +30,6 @@ import java.util.Set; import java.util.UUID; import org.apache.log4j.Logger; - import org.apache.qpid.server.configuration.IllegalConfigurationException; import org.apache.qpid.server.configuration.store.StoreConfigurationChangeListener; import org.apache.qpid.server.model.Broker; @@ -41,82 +40,58 @@ import org.apache.qpid.server.store.ConfiguredObjectRecord; import org.apache.qpid.server.store.ConfiguredObjectRecordImpl; import org.apache.qpid.server.store.DurableConfigurationStore; import org.apache.qpid.server.store.DurableConfigurationStoreUpgrader; -import org.apache.qpid.server.store.NonNullUpgrader; +import org.apache.qpid.server.store.NullUpgrader; import org.apache.qpid.server.store.handler.ConfiguredObjectRecordHandler; import org.apache.qpid.server.util.Action; public class BrokerStoreUpgrader { - private static Logger LOGGER = Logger.getLogger(BrokerStoreUpgrader.class); - - private static Map _upgraders = new HashMap(); private final SystemContext _systemContext; + private Map _upgraders = new HashMap(); + + + // Note: don't use externally defined constants in upgraders in case they change, the values here MUST stay the same + // no matter what changes are made to the code in the future public BrokerStoreUpgrader(SystemContext systemContext) { _systemContext = systemContext; + + register(new Upgrader_1_0_to_1_1()); + register(new Upgrader_1_1_to_1_2()); + register(new Upgrader_1_2_to_1_3()); + register(new Upgrader_1_3_to_1_4()); } - private static abstract class UpgraderPhaseFactory + private void register(UpgraderPhaseFactory factory) { - private final String _toVersion; - - protected UpgraderPhaseFactory(String fromVersion, String toVersion) - { - _upgraders.put(fromVersion, this); - _toVersion = toVersion; - } - - public String getToVersion() - { - return _toVersion; - } - - public abstract BrokerStoreUpgraderPhase newInstance(); + _upgraders.put(factory.getFromVersion(), factory); } - private static abstract class BrokerStoreUpgraderPhase extends NonNullUpgrader + private final class Upgrader_1_0_to_1_1 extends UpgraderPhaseFactory { - private final String _toVersion; - - protected BrokerStoreUpgraderPhase(String toVersion) + private Upgrader_1_0_to_1_1() { - _toVersion = toVersion; + super("1.0", "1.1"); } - - protected ConfiguredObjectRecord upgradeBrokerRecord(ConfiguredObjectRecord record) - { - Map updatedAttributes = new HashMap(record.getAttributes()); - updatedAttributes.put(Broker.MODEL_VERSION, _toVersion); - record = createModifiedRecord(record, updatedAttributes); - getUpdateMap().put(record.getId(), record); - return record; - } - } - - // Note: don't use externally defined constants in upgraders in case they change, the values here MUST stay the same - // no matter what changes are made to the code in the future - - private final static UpgraderPhaseFactory UPGRADE_1_0 = new UpgraderPhaseFactory("1.0", "1.1") - { @Override - public BrokerStoreUpgraderPhase newInstance() + public StoreUpgraderPhase newInstance() { - return new BrokerStoreUpgraderPhase(getToVersion()) + return new StoreUpgraderPhase(Broker.MODEL_VERSION, getToVersion()) { @Override public void configuredObject(ConfiguredObjectRecord record) { if (record.getType().equals("Broker")) { - record = upgradeBrokerRecord(record); + record = upgradeRootRecord(record); } else if (record.getType().equals("VirtualHost") && record.getAttributes().containsKey("storeType")) { Map updatedAttributes = new HashMap(record.getAttributes()); updatedAttributes.put("type", "STANDARD"); - record = createModifiedRecord(record, updatedAttributes); + record = new ConfiguredObjectRecordImpl(record.getId(), record.getType(), updatedAttributes, record.getParents()); getUpdateMap().put(record.getId(), record); } @@ -131,24 +106,19 @@ public class BrokerStoreUpgrader } }; } - - - }; - - - protected static ConfiguredObjectRecordImpl createModifiedRecord(final ConfiguredObjectRecord record, - final Map updatedAttributes) - { - - return new ConfiguredObjectRecordImpl(record.getId(), record.getType(), updatedAttributes, record.getParents()); } - private final static UpgraderPhaseFactory UPGRADE_1_1 = new UpgraderPhaseFactory("1.1", "1.2") + private static final class Upgrader_1_1_to_1_2 extends UpgraderPhaseFactory { + private Upgrader_1_1_to_1_2() + { + super("1.1", "1.2"); + } + @Override - public BrokerStoreUpgraderPhase newInstance() + public StoreUpgraderPhase newInstance() { - return new BrokerStoreUpgraderPhase(getToVersion()) + return new StoreUpgraderPhase(Broker.MODEL_VERSION, getToVersion()) { @Override @@ -156,7 +126,7 @@ public class BrokerStoreUpgrader { if (record.getType().equals("Broker")) { - record = upgradeBrokerRecord(record); + record = upgradeRootRecord(record); } getNextUpgrader().configuredObject(record); @@ -170,15 +140,19 @@ public class BrokerStoreUpgrader } }; } - }; - + } - private final static UpgraderPhaseFactory UPGRADE_1_2 = new UpgraderPhaseFactory("1.2", "1.3") + private static final class Upgrader_1_2_to_1_3 extends UpgraderPhaseFactory { + private Upgrader_1_2_to_1_3() + { + super("1.2", "1.3"); + } + @Override - public BrokerStoreUpgraderPhase newInstance() + public StoreUpgraderPhase newInstance() { - return new BrokerStoreUpgraderPhase(getToVersion()) + return new StoreUpgraderPhase(Broker.MODEL_VERSION, getToVersion()) { @Override @@ -188,7 +162,7 @@ public class BrokerStoreUpgrader { Map updatedAttributes = new HashMap(record.getAttributes()); updatedAttributes.put("trustStoreType", updatedAttributes.remove("type")); - record = createModifiedRecord(record, updatedAttributes); + record = new ConfiguredObjectRecordImpl(record.getId(), record.getType(), updatedAttributes, record.getParents()); getUpdateMap().put(record.getId(), record); } @@ -196,13 +170,13 @@ public class BrokerStoreUpgrader { Map updatedAttributes = new HashMap(record.getAttributes()); updatedAttributes.put("keyStoreType", updatedAttributes.remove("type")); - record = createModifiedRecord(record, updatedAttributes); + record = new ConfiguredObjectRecordImpl(record.getId(), record.getType(), updatedAttributes, record.getParents()); getUpdateMap().put(record.getId(), record); } else if (record.getType().equals("Broker")) { - record = upgradeBrokerRecord(record); + record = upgradeRootRecord(record); } getNextUpgrader().configuredObject(record); @@ -216,17 +190,22 @@ public class BrokerStoreUpgrader } }; } - }; - + } - private final static UpgraderPhaseFactory UPGRADE_1_3 = new UpgraderPhaseFactory("1.3", "1.4") + private static final class Upgrader_1_3_to_1_4 extends UpgraderPhaseFactory { + private Upgrader_1_3_to_1_4() + { + super("1.3", "1.4"); + } + @Override - public BrokerStoreUpgraderPhase newInstance() + public StoreUpgraderPhase newInstance() { - return new BrokerStoreUpgraderPhase(getToVersion()) + return new StoreUpgraderPhase(Broker.MODEL_VERSION, getToVersion()) { + @SuppressWarnings("serial") private Map _vhostUpgraderMap = new HashMap() {{ put("BDB_HA", new BdbHaVirtualHostUpgrader()); @@ -257,13 +236,13 @@ public class BrokerStoreUpgrader { Map updatedAttributes = new HashMap(record.getAttributes()); updatedAttributes.put("type", updatedAttributes.remove("pluginType")); - record = createModifiedRecord(record, updatedAttributes); + record = new ConfiguredObjectRecordImpl(record.getId(), record.getType(), updatedAttributes, record.getParents()); getUpdateMap().put(record.getId(), record); } else if (record.getType().equals("Broker")) { - record = upgradeBrokerRecord(record); + record = upgradeRootRecord(record); } getNextUpgrader().configuredObject(record); @@ -277,9 +256,7 @@ public class BrokerStoreUpgrader } }; } - - - }; + } private static interface VirtualHostEntryUpgrader { @@ -288,6 +265,7 @@ public class BrokerStoreUpgrader private static class StandardVirtualHostUpgrader implements VirtualHostEntryUpgrader { + @SuppressWarnings("serial") Map _messageStoreAttributeTransformers = new HashMap() {{ put("DERBY", new AttributesTransformer(). @@ -317,6 +295,7 @@ public class BrokerStoreUpgrader addAttributeTransformer("storeType", mutateAttributeValue("JDBC"))); }}; + @SuppressWarnings("serial") Map _configurationStoreAttributeTransformers = new HashMap() {{ put("DERBY", new AttributesTransformer(). @@ -581,12 +560,9 @@ public class BrokerStoreUpgrader } } - - - - public Broker upgrade(DurableConfigurationStore store) + public Broker upgrade(DurableConfigurationStore store) { - final BrokerStoreRecoveryHandler recoveryHandler = new BrokerStoreRecoveryHandler(_systemContext, store); + final BrokerStoreRecoveryHandler recoveryHandler = new BrokerStoreRecoveryHandler(_systemContext, store, _upgraders); store.openConfigurationStore(_systemContext, Collections.emptyMap()); store.visitConfiguredObjectRecords(recoveryHandler); @@ -602,11 +578,13 @@ public class BrokerStoreUpgrader private DurableConfigurationStore _store; private final Map _records = new HashMap(); private final SystemContext _systemContext; + private Map _upgraders; - private BrokerStoreRecoveryHandler(final SystemContext systemContext, DurableConfigurationStore store) + private BrokerStoreRecoveryHandler(final SystemContext systemContext, DurableConfigurationStore store, Map upgraders) { _systemContext = systemContext; _store = store; + _upgraders = upgraders; } @@ -631,7 +609,7 @@ public class BrokerStoreUpgrader { LOGGER.debug("Adding broker store upgrader from model version: " + version); final UpgraderPhaseFactory upgraderPhaseFactory = _upgraders.get(version); - BrokerStoreUpgraderPhase upgrader = upgraderPhaseFactory.newInstance(); + StoreUpgraderPhase upgrader = upgraderPhaseFactory.newInstance(); if(_upgrader == null) { _upgrader = upgrader; @@ -645,69 +623,11 @@ public class BrokerStoreUpgrader if(_upgrader == null) { - _upgrader = new DurableConfigurationStoreUpgrader() - { - - @Override - public void configuredObject(final ConfiguredObjectRecord record) - { - } - - @Override - public void complete() - { - } - - @Override - public void setNextUpgrader(final DurableConfigurationStoreUpgrader upgrader) - { - } - - @Override - public Map getUpdatedRecords() - { - return Collections.emptyMap(); - } - - @Override - public Map getDeletedRecords() - { - return Collections.emptyMap(); - } - }; + _upgrader = new NullUpgrader(); } else { - _upgrader.setNextUpgrader(new DurableConfigurationStoreUpgrader() - { - @Override - public void configuredObject(final ConfiguredObjectRecord record) - { - } - - @Override - public void complete() - { - - } - - @Override - public void setNextUpgrader(final DurableConfigurationStoreUpgrader upgrader) - { - } - - @Override - public Map getUpdatedRecords() - { - return Collections.emptyMap(); - } - - @Override - public Map getDeletedRecords() - { - return Collections.emptyMap(); - } - }); + _upgrader.setNextUpgrader(new NullUpgrader()); } for(ConfiguredObjectRecord record : _records.values()) diff --git a/java/broker-core/src/main/java/org/apache/qpid/server/configuration/startup/StoreUpgraderPhase.java b/java/broker-core/src/main/java/org/apache/qpid/server/configuration/startup/StoreUpgraderPhase.java new file mode 100644 index 0000000000..5762a8f8e6 --- /dev/null +++ b/java/broker-core/src/main/java/org/apache/qpid/server/configuration/startup/StoreUpgraderPhase.java @@ -0,0 +1,49 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.server.configuration.startup; + +import java.util.HashMap; +import java.util.Map; + +import org.apache.qpid.server.store.ConfiguredObjectRecord; +import org.apache.qpid.server.store.ConfiguredObjectRecordImpl; +import org.apache.qpid.server.store.NonNullUpgrader; + +public abstract class StoreUpgraderPhase extends NonNullUpgrader +{ + private final String _toVersion; + private final String _versionAttributeName; + + protected StoreUpgraderPhase(String versionAttributeName, String toVersion) + { + _toVersion = toVersion; + _versionAttributeName = versionAttributeName; + } + + protected ConfiguredObjectRecord upgradeRootRecord(ConfiguredObjectRecord record) + { + Map updatedAttributes = new HashMap(record.getAttributes()); + updatedAttributes.put(_versionAttributeName, _toVersion); + record = new ConfiguredObjectRecordImpl(record.getId(), record.getType(), updatedAttributes, record.getParents()); + getUpdateMap().put(record.getId(), record); + return record; + } +} \ No newline at end of file diff --git a/java/broker-core/src/main/java/org/apache/qpid/server/configuration/startup/UpgraderPhaseFactory.java b/java/broker-core/src/main/java/org/apache/qpid/server/configuration/startup/UpgraderPhaseFactory.java new file mode 100644 index 0000000000..26686c67cd --- /dev/null +++ b/java/broker-core/src/main/java/org/apache/qpid/server/configuration/startup/UpgraderPhaseFactory.java @@ -0,0 +1,45 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT 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.startup; + +public abstract class UpgraderPhaseFactory +{ + private final String _toVersion; + private final String _fromVersion; + + protected UpgraderPhaseFactory(String fromVersion, String toVersion) + { + _toVersion = toVersion; + _fromVersion = fromVersion; + } + + public String getToVersion() + { + return _toVersion; + } + + public String getFromVersion() + { + return _fromVersion; + } + + public abstract StoreUpgraderPhase newInstance(); +} \ No newline at end of file diff --git a/java/broker-core/src/main/java/org/apache/qpid/server/configuration/store/StoreConfigurationChangeListener.java b/java/broker-core/src/main/java/org/apache/qpid/server/configuration/store/StoreConfigurationChangeListener.java index b76041dcce..94f496d89e 100644 --- a/java/broker-core/src/main/java/org/apache/qpid/server/configuration/store/StoreConfigurationChangeListener.java +++ b/java/broker-core/src/main/java/org/apache/qpid/server/configuration/store/StoreConfigurationChangeListener.java @@ -34,6 +34,7 @@ import org.apache.qpid.server.model.ConfiguredObject; import org.apache.qpid.server.model.Model; import org.apache.qpid.server.model.State; import org.apache.qpid.server.model.VirtualHost; +import org.apache.qpid.server.model.VirtualHostNode; import org.apache.qpid.server.store.DurableConfigurationStore; public class StoreConfigurationChangeListener implements ConfigurationChangeListener @@ -59,8 +60,8 @@ public class StoreConfigurationChangeListener implements ConfigurationChangeList @Override public void childAdded(ConfiguredObject object, ConfiguredObject child) { - // exclude VirtualHost children from storing in broker store - if (!(object instanceof VirtualHost)) + // exclude VirtualHostNode children from storing in broker store + if (!(object instanceof VirtualHostNode)) { child.addChangeListener(this); _store.update(true,child.asObjectRecord()); diff --git a/java/broker-core/src/main/java/org/apache/qpid/server/model/AbstractConfiguredObjectTypeFactory.java b/java/broker-core/src/main/java/org/apache/qpid/server/model/AbstractConfiguredObjectTypeFactory.java index d69d6e3076..f159f70d20 100644 --- a/java/broker-core/src/main/java/org/apache/qpid/server/model/AbstractConfiguredObjectTypeFactory.java +++ b/java/broker-core/src/main/java/org/apache/qpid/server/model/AbstractConfiguredObjectTypeFactory.java @@ -61,7 +61,7 @@ abstract public class AbstractConfiguredObjectTypeFactory attributes, ConfiguredObject... parents); - public final > C getParent(Class parentClass, ConfiguredObject... parents) + public final > C getParent(Class parentClass, ConfiguredObject... parents) { if(!parents[0].getModel().getParentTypes((Class) getCategoryClass()).contains( diff --git a/java/broker-core/src/main/java/org/apache/qpid/server/model/Broker.java b/java/broker-core/src/main/java/org/apache/qpid/server/model/Broker.java index 16aa3e8916..024a7b0bfb 100644 --- a/java/broker-core/src/main/java/org/apache/qpid/server/model/Broker.java +++ b/java/broker-core/src/main/java/org/apache/qpid/server/model/Broker.java @@ -136,7 +136,7 @@ public interface Broker> extends ConfiguredObject, EventL //children - Collection < VirtualHost > getVirtualHosts(); + Collection> getVirtualHostNodes(); Collection> getPorts(); diff --git a/java/broker-core/src/main/java/org/apache/qpid/server/model/BrokerModel.java b/java/broker-core/src/main/java/org/apache/qpid/server/model/BrokerModel.java index 7a6fd2a501..bcfb413451 100644 --- a/java/broker-core/src/main/java/org/apache/qpid/server/model/BrokerModel.java +++ b/java/broker-core/src/main/java/org/apache/qpid/server/model/BrokerModel.java @@ -38,9 +38,10 @@ public final class BrokerModel extends Model * 1.1 Addition of mandatory virtual host type / different types of virtual host * 1.3 Truststore/Keystore type => trustStoreType / type => keyStoreType * 1.4 Separate messageStoreSettings from virtualhost + * 2.0 Introduce VirtualHostNode as a child of a Broker instead of VirtualHost */ - public static final int MODEL_MAJOR_VERSION = 1; - public static final int MODEL_MINOR_VERSION = 4; + public static final int MODEL_MAJOR_VERSION = 2; + public static final int MODEL_MINOR_VERSION = 0; public static final String MODEL_VERSION = MODEL_MAJOR_VERSION + "." + MODEL_MINOR_VERSION; private static final Model MODEL_INSTANCE = new BrokerModel(); private final Map, Collection>> _parents = @@ -60,7 +61,7 @@ public final class BrokerModel extends Model addRelationship(SystemContext.class, Broker.class); - addRelationship(Broker.class, VirtualHost.class); + addRelationship(Broker.class, VirtualHostNode.class); addRelationship(Broker.class, Port.class); addRelationship(Broker.class, AccessControlProvider.class); addRelationship(Broker.class, AuthenticationProvider.class); @@ -69,6 +70,8 @@ public final class BrokerModel extends Model addRelationship(Broker.class, KeyStore.class); addRelationship(Broker.class, Plugin.class); + addRelationship(VirtualHostNode.class, VirtualHost.class); + addRelationship(VirtualHost.class, Exchange.class); addRelationship(VirtualHost.class, Queue.class); addRelationship(VirtualHost.class, Connection.class); diff --git a/java/broker-core/src/main/java/org/apache/qpid/server/model/VirtualHost.java b/java/broker-core/src/main/java/org/apache/qpid/server/model/VirtualHost.java index d5ccd6a69f..48206ccdf4 100644 --- a/java/broker-core/src/main/java/org/apache/qpid/server/model/VirtualHost.java +++ b/java/broker-core/src/main/java/org/apache/qpid/server/model/VirtualHost.java @@ -44,8 +44,8 @@ public interface VirtualHost, Q extends Queue, String SUPPORTED_QUEUE_TYPES = "supportedQueueTypes"; String SECURITY_ACL = "securityAcl"; String HOUSE_KEEPING_THREAD_COUNT = "houseKeepingThreadCount"; - String CONFIGURATION_STORE_SETTINGS = "configurationStoreSettings"; String MESSAGE_STORE_SETTINGS = "messageStoreSettings"; + String MODEL_VERSION = "modelVersion"; // TODO - this isn't really an attribute @ManagedAttribute( derived = true ) @@ -111,8 +111,8 @@ public interface VirtualHost, Q extends Queue, @ManagedAttribute( automate = true ) Map getMessageStoreSettings(); - @ManagedAttribute( automate = true ) - Map getConfigurationStoreSettings(); + @ManagedAttribute( derived = true ) + String getModelVersion(); @ManagedStatistic long getQueueCount(); @@ -135,7 +135,6 @@ public interface VirtualHost, Q extends Queue, @ManagedStatistic long getMessagesOut(); - //children Collection getAliases(); Collection getConnections(); diff --git a/java/broker-core/src/main/java/org/apache/qpid/server/model/VirtualHostNode.java b/java/broker-core/src/main/java/org/apache/qpid/server/model/VirtualHostNode.java new file mode 100644 index 0000000000..8d80ad19d7 --- /dev/null +++ b/java/broker-core/src/main/java/org/apache/qpid/server/model/VirtualHostNode.java @@ -0,0 +1,36 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.server.model; + +import org.apache.qpid.server.store.DurableConfigurationStore; + +@ManagedObject(category=true, managesChildren=false) +public interface VirtualHostNode> extends ConfiguredObject +{ + public static final String IS_MESSAGE_STORE_PROVIDER = "messageStoreProvider"; + + @ManagedAttribute (automate = true, defaultValue = "false") + boolean isMessageStoreProvider(); + + VirtualHost getVirtualHost(); + + DurableConfigurationStore getConfigurationStore(); +} diff --git a/java/broker-core/src/main/java/org/apache/qpid/server/model/adapter/BrokerAdapter.java b/java/broker-core/src/main/java/org/apache/qpid/server/model/adapter/BrokerAdapter.java index 3dd261e9a9..0a3ffe4595 100644 --- a/java/broker-core/src/main/java/org/apache/qpid/server/model/adapter/BrokerAdapter.java +++ b/java/broker-core/src/main/java/org/apache/qpid/server/model/adapter/BrokerAdapter.java @@ -36,7 +36,6 @@ import java.util.regex.Pattern; import javax.security.auth.Subject; import org.apache.log4j.Logger; - import org.apache.qpid.common.QpidProperties; import org.apache.qpid.server.BrokerOptions; import org.apache.qpid.server.configuration.IllegalConfigurationException; @@ -108,8 +107,6 @@ public class BrokerAdapter extends AbstractConfiguredObject imple attributes, parent.getTaskExecutor()); - //_virtualHostRegistry = new VirtualHostRegistry(parent.getEventLogger()); - _logRecorder = parent.getLogRecorder(); _eventLogger = parent.getEventLogger(); _brokerOptions = parent.getBrokerOptions(); @@ -235,9 +232,9 @@ public class BrokerAdapter extends AbstractConfiguredObject imple { addAccessControlProvider(accessControlProvider); } - for(VirtualHost virtualHost : getChildren(VirtualHost.class)) + for(VirtualHostNode virtualHostNode : getChildren(VirtualHostNode.class)) { - addVirtualHost(virtualHost); + addVirtualHostNode(virtualHostNode); } @@ -358,9 +355,10 @@ public class BrokerAdapter extends AbstractConfiguredObject imple return BrokerModel.MODEL_VERSION; } - public Collection> getVirtualHosts() + @Override + public Collection> getVirtualHostNodes() { - Collection children = getChildren(VirtualHost.class); + Collection children = getChildren(VirtualHostNode.class); return children; } @@ -402,11 +400,11 @@ public class BrokerAdapter extends AbstractConfiguredObject imple return children; } - private VirtualHost createVirtualHost(final Map attributes) + private VirtualHostNode createVirtualHostNode(Map attributes) throws AccessControlException, IllegalArgumentException { - final VirtualHost virtualHost = getObjectFactory().create(VirtualHost.class,attributes,this); + final VirtualHostNode virtualHostNode = getObjectFactory().create(VirtualHostNode.class,attributes, this); // permission has already been granted to create the virtual host // disable further access check on other operations, e.g. create exchange @@ -415,20 +413,13 @@ public class BrokerAdapter extends AbstractConfiguredObject imple @Override public Object run() { - virtualHost.setDesiredState(State.INITIALISING, State.ACTIVE); + virtualHostNode.setDesiredState(State.INITIALISING, State.ACTIVE); return null; } }); - return virtualHost; + return virtualHostNode; } - private boolean deleteVirtualHost(final VirtualHost vhost) throws AccessControlException, IllegalStateException - { - vhost.removeChangeListener(this); - return true; - } - - public State getState() { return null; //TODO @@ -467,9 +458,9 @@ public class BrokerAdapter extends AbstractConfiguredObject imple @Override public C execute() { - if (childClass == VirtualHost.class) + if (childClass == VirtualHostNode.class) { - return (C) createVirtualHost(attributes); + return (C) createVirtualHostNode(attributes); } else if (childClass == Port.class) { @@ -720,10 +711,16 @@ public class BrokerAdapter extends AbstractConfiguredObject imple return true; } - private void addVirtualHost(VirtualHost virtualHost) + private void addVirtualHostNode(VirtualHostNode virtualHostNode) { + virtualHostNode.addChangeListener(this); + } - virtualHost.addChangeListener(this); + + private boolean deleteVirtualHostNode(final VirtualHostNode virtualHostNode) throws AccessControlException, IllegalStateException + { + virtualHostNode.removeChangeListener(this); + return true; } @Override @@ -815,9 +812,9 @@ public class BrokerAdapter extends AbstractConfiguredObject imple { childDeleted = deletePort(oldState, (Port)object); } - else if(object instanceof VirtualHost) + else if(object instanceof VirtualHostNode) { - childDeleted = deleteVirtualHost((VirtualHost)object); + childDeleted = deleteVirtualHostNode((VirtualHostNode)object); } else if(object instanceof GroupProvider) { @@ -890,9 +887,17 @@ public class BrokerAdapter extends AbstractConfiguredObject imple } @Override - public VirtualHost findVirtualHostByName(String name) + public VirtualHost findVirtualHostByName(String name) { - return getChildByName(VirtualHost.class, name); + for (VirtualHostNode virtualHostNode : getChildren(VirtualHostNode.class)) + { + VirtualHost virtualHost = virtualHostNode.getVirtualHost(); + if (virtualHost != null && virtualHost.getName().equals(name)) + { + return virtualHost; + } + } + return null; } @Override @@ -1042,11 +1047,12 @@ public class BrokerAdapter extends AbstractConfiguredObject imple _messagesReceived.reset(); _dataReceived.reset(); - for (VirtualHost vhost : getVirtualHosts()) + for (VirtualHostNode virtualHostNode : getChildren(VirtualHostNode.class)) { - if(vhost instanceof VirtualHostImpl) + VirtualHost virtualHost = virtualHostNode.getVirtualHost(); + if (virtualHost instanceof VirtualHostImpl) { - ((VirtualHostImpl) vhost).resetStatistics(); + ((VirtualHostImpl) virtualHost).resetStatistics(); } } } @@ -1098,37 +1104,38 @@ public class BrokerAdapter extends AbstractConfiguredObject imple _eventLogger.message(BrokerMessages.STATS_MSGS(RECEIVED, _messagesReceived.getPeak(), _messagesReceived.getTotal())); - Collection> hosts = getVirtualHosts(); - for (VirtualHost vhost : hosts) + for (VirtualHostNode virtualHostNode : getChildren(VirtualHostNode.class)) + { + VirtualHost virtualHost = virtualHostNode.getVirtualHost(); + if (virtualHost instanceof VirtualHostImpl) { - if(vhost instanceof VirtualHostImpl) - { - VirtualHostImpl vhostImpl = (VirtualHostImpl) vhost; - String name = vhost.getName(); - StatisticsCounter dataDelivered = vhostImpl.getDataDeliveryStatistics(); - StatisticsCounter messagesDelivered = vhostImpl.getMessageDeliveryStatistics(); - StatisticsCounter dataReceived = vhostImpl.getDataReceiptStatistics(); - StatisticsCounter messagesReceived = vhostImpl.getMessageReceiptStatistics(); - EventLogger logger = vhostImpl.getEventLogger(); - logger.message(VirtualHostMessages.STATS_DATA(name, - DELIVERED, - dataDelivered.getPeak() / 1024.0, - dataDelivered.getTotal())); - logger.message(VirtualHostMessages.STATS_MSGS(name, - DELIVERED, - messagesDelivered.getPeak(), - messagesDelivered.getTotal())); - logger.message(VirtualHostMessages.STATS_DATA(name, - RECEIVED, - dataReceived.getPeak() / 1024.0, - dataReceived.getTotal())); - logger.message(VirtualHostMessages.STATS_MSGS(name, - RECEIVED, - messagesReceived.getPeak(), - messagesReceived.getTotal())); - } + VirtualHostImpl vhostImpl = (VirtualHostImpl) virtualHost; + String name = virtualHost.getName(); + StatisticsCounter dataDelivered = vhostImpl.getDataDeliveryStatistics(); + StatisticsCounter messagesDelivered = vhostImpl.getMessageDeliveryStatistics(); + StatisticsCounter dataReceived = vhostImpl.getDataReceiptStatistics(); + StatisticsCounter messagesReceived = vhostImpl.getMessageReceiptStatistics(); + EventLogger logger = vhostImpl.getEventLogger(); + logger.message(VirtualHostMessages.STATS_DATA(name, + DELIVERED, + dataDelivered.getPeak() / 1024.0, + dataDelivered.getTotal())); + logger.message(VirtualHostMessages.STATS_MSGS(name, + DELIVERED, + messagesDelivered.getPeak(), + messagesDelivered.getTotal())); + logger.message(VirtualHostMessages.STATS_DATA(name, + RECEIVED, + dataReceived.getPeak() / 1024.0, + dataReceived.getTotal())); + logger.message(VirtualHostMessages.STATS_MSGS(name, + RECEIVED, + messagesReceived.getPeak(), + messagesReceived.getTotal())); + } + } if (_reset) { diff --git a/java/broker-core/src/main/java/org/apache/qpid/server/model/adapter/StandardVirtualHostFactory.java b/java/broker-core/src/main/java/org/apache/qpid/server/model/adapter/StandardVirtualHostFactory.java index 64845e94f3..51f8897d67 100644 --- a/java/broker-core/src/main/java/org/apache/qpid/server/model/adapter/StandardVirtualHostFactory.java +++ b/java/broker-core/src/main/java/org/apache/qpid/server/model/adapter/StandardVirtualHostFactory.java @@ -23,8 +23,8 @@ package org.apache.qpid.server.model.adapter; import java.util.Map; import org.apache.qpid.server.model.AbstractConfiguredObjectTypeFactory; -import org.apache.qpid.server.model.Broker; import org.apache.qpid.server.model.ConfiguredObject; +import org.apache.qpid.server.model.VirtualHostNode; import org.apache.qpid.server.virtualhost.StandardVirtualHost; public class StandardVirtualHostFactory extends AbstractConfiguredObjectTypeFactory @@ -39,8 +39,8 @@ public class StandardVirtualHostFactory extends AbstractConfiguredObjectTypeFact public StandardVirtualHost createInstance(final Map attributes, final ConfiguredObject... parents) { - final Broker broker = getParent(Broker.class, parents); - return new StandardVirtualHost(attributes, broker); + final VirtualHostNode virtualHostNode = getParent(VirtualHostNode.class, parents); + return new StandardVirtualHost(attributes, virtualHostNode); } diff --git a/java/broker-core/src/main/java/org/apache/qpid/server/model/port/AbstractPort.java b/java/broker-core/src/main/java/org/apache/qpid/server/model/port/AbstractPort.java index 4121e24368..436122d2e1 100644 --- a/java/broker-core/src/main/java/org/apache/qpid/server/model/port/AbstractPort.java +++ b/java/broker-core/src/main/java/org/apache/qpid/server/model/port/AbstractPort.java @@ -47,6 +47,7 @@ import org.apache.qpid.server.model.Transport; import org.apache.qpid.server.model.TrustStore; import org.apache.qpid.server.model.VirtualHost; import org.apache.qpid.server.model.VirtualHostAlias; +import org.apache.qpid.server.model.VirtualHostNode; import org.apache.qpid.server.security.access.Operation; import org.apache.qpid.server.util.MapValueConverter; import org.apache.qpid.server.util.ParameterizedTypeImpl; @@ -238,13 +239,17 @@ abstract public class AbstractPort> extends AbstractCo public Collection getVirtualHostBindings() { List aliases = new ArrayList(); - for(VirtualHost vh : _broker.getVirtualHosts()) + for(VirtualHostNode vhn : _broker.getVirtualHostNodes()) { - for(VirtualHostAlias alias : vh.getAliases()) + VirtualHost vh = vhn.getVirtualHost(); + if (vh != null) { - if(alias.getPort().equals(this)) + for(VirtualHostAlias alias : vh.getAliases()) { - aliases.add(alias); + if(alias.getPort().equals(this)) + { + aliases.add(alias); + } } } } diff --git a/java/broker-core/src/main/java/org/apache/qpid/server/model/port/AmqpPortImpl.java b/java/broker-core/src/main/java/org/apache/qpid/server/model/port/AmqpPortImpl.java index ad52f420b6..3952ea3871 100644 --- a/java/broker-core/src/main/java/org/apache/qpid/server/model/port/AmqpPortImpl.java +++ b/java/broker-core/src/main/java/org/apache/qpid/server/model/port/AmqpPortImpl.java @@ -99,7 +99,8 @@ public class AmqpPortImpl extends AbstractPortWithAuthProvider imp { name = _broker.getDefaultVirtualHost(); } - return (VirtualHostImpl) _broker.getChildByName(VirtualHost.class, name); + + return (VirtualHostImpl) _broker.findVirtualHostByName(name); } protected Set getDefaultProtocols() diff --git a/java/broker-core/src/main/java/org/apache/qpid/server/plugin/DurableConfigurationStoreFactory.java b/java/broker-core/src/main/java/org/apache/qpid/server/plugin/DurableConfigurationStoreFactory.java index b83222f798..ba398f129d 100644 --- a/java/broker-core/src/main/java/org/apache/qpid/server/plugin/DurableConfigurationStoreFactory.java +++ b/java/broker-core/src/main/java/org/apache/qpid/server/plugin/DurableConfigurationStoreFactory.java @@ -21,13 +21,16 @@ package org.apache.qpid.server.plugin; import java.util.Map; + import org.apache.qpid.server.store.DurableConfigurationStore; public interface DurableConfigurationStoreFactory extends Pluggable { + PluggableFactoryLoader FACTORY_LOADER = new PluggableFactoryLoader(DurableConfigurationStoreFactory.class); + String getType(); DurableConfigurationStore createDurableConfigurationStore(); - void validateAttributes(Map attributes); + void validateConfigurationStoreSettings(Map attributes); } diff --git a/java/broker-core/src/main/java/org/apache/qpid/server/store/AbstractDurableConfiguredObjectRecoverer.java b/java/broker-core/src/main/java/org/apache/qpid/server/store/AbstractDurableConfiguredObjectRecoverer.java deleted file mode 100644 index 75fe2a6642..0000000000 --- a/java/broker-core/src/main/java/org/apache/qpid/server/store/AbstractDurableConfiguredObjectRecoverer.java +++ /dev/null @@ -1,118 +0,0 @@ -/* - * - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * - */ -package org.apache.qpid.server.store; - -import java.util.UUID; - -import org.apache.qpid.server.model.ConfiguredObject; - -public abstract class AbstractDurableConfiguredObjectRecoverer implements DurableConfiguredObjectRecoverer -{ - @Override - public void load(final DurableConfigurationRecoverer durableConfigurationRecoverer, - final ConfiguredObjectRecord record) - { - final UnresolvedObject obj = createUnresolvedObject(record); - UnresolvedDependency[] dependencies = obj.getUnresolvedDependencies(); - for(final UnresolvedDependency dependency : dependencies) - { - if(dependency.getId() != null) - { - Object dep; - if ((dep = durableConfigurationRecoverer.getResolvedObject(dependency.getType(), dependency.getId())) - != null) - { - dependency.resolve(dep); - } - else - { - durableConfigurationRecoverer.addResolutionListener(dependency.getType(), dependency.getId(), - null, new DependencyListener() - { - - @Override - public void dependencyResolved(final String depType, - final UUID depId, - final ConfiguredObject o) - { - dependency.resolve(o); - if (obj.getUnresolvedDependencies().length - == 0) - { - durableConfigurationRecoverer.resolve( - getType(), - record.getId(), - obj.resolve()); - } - } - } - ); - } - } - else - { - Object dep; - - if ((dep = durableConfigurationRecoverer.getResolvedObject(dependency.getType(), dependency.getName())) - != null) - { - dependency.resolve(dep); - } - else - { - durableConfigurationRecoverer.addResolutionListener(dependency.getType(), dependency.getId(), - dependency.getName(), new DependencyListener() - { - - @Override - public void dependencyResolved(final String depType, - final UUID depId, - final ConfiguredObject o) - { - dependency.resolve(o); - if (obj.getUnresolvedDependencies().length - == 0) - { - durableConfigurationRecoverer.resolve( - getType(), - record.getId(), - obj.resolve()); - } - } - } - ); - } - } - } - if(obj.getUnresolvedDependencies().length == 0) - { - durableConfigurationRecoverer.resolve(getType(), record.getId(), obj.resolve()); - } - else - { - durableConfigurationRecoverer.addUnresolvedObject(getType(), record.getId(), obj); - } - - } - - public abstract UnresolvedObject createUnresolvedObject(final ConfiguredObjectRecord record); - -} diff --git a/java/broker-core/src/main/java/org/apache/qpid/server/store/AbstractJDBCMessageStore.java b/java/broker-core/src/main/java/org/apache/qpid/server/store/AbstractJDBCMessageStore.java index 0e61ec9b47..2f83b34692 100644 --- a/java/broker-core/src/main/java/org/apache/qpid/server/store/AbstractJDBCMessageStore.java +++ b/java/broker-core/src/main/java/org/apache/qpid/server/store/AbstractJDBCMessageStore.java @@ -2495,5 +2495,12 @@ abstract public class AbstractJDBCMessageStore implements MessageStore, DurableC { return Collections.unmodifiableMap(_parents); } + + @Override + public String toString() + { + return "ConfiguredObjectRecordImpl [_id=" + _id + ", _type=" + _type + ", _attributes=" + _attributes + ", _parents=" + + _parents + "]"; + } } } diff --git a/java/broker-core/src/main/java/org/apache/qpid/server/store/AbstractMemoryMessageStore.java b/java/broker-core/src/main/java/org/apache/qpid/server/store/AbstractMemoryMessageStore.java index 63413fc0de..e2c43f5012 100644 --- a/java/broker-core/src/main/java/org/apache/qpid/server/store/AbstractMemoryMessageStore.java +++ b/java/broker-core/src/main/java/org/apache/qpid/server/store/AbstractMemoryMessageStore.java @@ -32,7 +32,6 @@ import java.util.concurrent.atomic.AtomicLong; import org.apache.qpid.server.message.EnqueueableMessage; import org.apache.qpid.server.model.ConfiguredObject; -import org.apache.qpid.server.model.VirtualHost; import org.apache.qpid.server.store.Transaction.Record; import org.apache.qpid.server.store.handler.ConfiguredObjectRecordHandler; import org.apache.qpid.server.store.handler.DistributedTransactionHandler; diff --git a/java/broker-core/src/main/java/org/apache/qpid/server/store/ConfiguredObjectRecordRecoveverAndUpgrader.java b/java/broker-core/src/main/java/org/apache/qpid/server/store/ConfiguredObjectRecordRecoveverAndUpgrader.java deleted file mode 100644 index e9e6d88f36..0000000000 --- a/java/broker-core/src/main/java/org/apache/qpid/server/store/ConfiguredObjectRecordRecoveverAndUpgrader.java +++ /dev/null @@ -1,60 +0,0 @@ -/* - * - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * - */ -package org.apache.qpid.server.store; - -import java.util.Map; - -import org.apache.qpid.server.store.handler.ConfiguredObjectRecordHandler; -import org.apache.qpid.server.virtualhost.DefaultUpgraderProvider; -import org.apache.qpid.server.virtualhost.VirtualHostImpl; - -public class ConfiguredObjectRecordRecoveverAndUpgrader implements ConfiguredObjectRecordHandler -{ - private DurableConfigurationRecoverer _configRecoverer; - private DurableConfigurationStore _store; - - public ConfiguredObjectRecordRecoveverAndUpgrader(VirtualHostImpl virtualHost, Map recoverers) - { - DefaultUpgraderProvider upgraderProvider = new DefaultUpgraderProvider(virtualHost); - _configRecoverer = new DurableConfigurationRecoverer(virtualHost.getName(), recoverers, upgraderProvider, virtualHost.getEventLogger()); - _store = virtualHost.getDurableConfigurationStore(); - } - - @Override - public void begin() - { - _configRecoverer.beginConfigurationRecovery(_store); - } - - @Override - public boolean handle(ConfiguredObjectRecord record) - { - _configRecoverer.configuredObject(record); - return true; - } - - @Override - public void end() - { - _configRecoverer.completeConfigurationRecovery(); - } - -} diff --git a/java/broker-core/src/main/java/org/apache/qpid/server/store/DurableConfigurationRecoverer.java b/java/broker-core/src/main/java/org/apache/qpid/server/store/DurableConfigurationRecoverer.java deleted file mode 100644 index 52d690df53..0000000000 --- a/java/broker-core/src/main/java/org/apache/qpid/server/store/DurableConfigurationRecoverer.java +++ /dev/null @@ -1,312 +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.store; - -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.UUID; - -import org.apache.log4j.Logger; - -import org.apache.qpid.server.configuration.IllegalConfigurationException; -import org.apache.qpid.server.logging.EventLogger; -import org.apache.qpid.server.logging.messages.ConfigStoreMessages; -import org.apache.qpid.server.logging.subjects.MessageStoreLogSubject; -import org.apache.qpid.server.model.BrokerModel; -import org.apache.qpid.server.model.ConfiguredObject; - -public class DurableConfigurationRecoverer implements ConfigurationRecoveryHandler -{ - private static final Logger _logger = Logger.getLogger(DurableConfigurationRecoverer.class); - - private final Map> _resolvedObjects = new HashMap>(); - - private final Map> _unresolvedObjects = - new HashMap>(); - private final List _records = new ArrayList(); - - private final Map>> _dependencyListeners = - new HashMap>>(); - private final Map>> _dependencyNameListeners = - new HashMap>>(); - - private final Map _recoverers; - private final UpgraderProvider _upgraderProvider; - private final EventLogger _eventLogger; - - private DurableConfigurationStoreUpgrader _upgrader; - - private DurableConfigurationStore _store; - private final String _name; - - private MessageStoreLogSubject _logSubject; - - public DurableConfigurationRecoverer(final String name, - Map recoverers, - UpgraderProvider upgraderProvider, EventLogger eventLogger) - { - _recoverers = recoverers; - _name = name; - _upgraderProvider = upgraderProvider; - _eventLogger = eventLogger; - } - - @Override - public void beginConfigurationRecovery(final DurableConfigurationStore store) - { - _logSubject = new MessageStoreLogSubject(_name, store.getClass().getSimpleName()); - - _store = store; - _eventLogger.message(_logSubject, ConfigStoreMessages.RECOVERY_START()); - } - - @Override - public void configuredObject(ConfiguredObjectRecord record) - { - _records.add(record); - } - - @Override - public String completeConfigurationRecovery() - { - String configVersion = getConfigVersionFromRecords(); - - _upgrader = _upgraderProvider.getUpgrader(configVersion, this); - - for (ConfiguredObjectRecord record : _records) - { - // We don't yet recover the VirtualHost record. - if (!"VirtualHost".equals(record.getType())) - { - _upgrader.configuredObject(record); - } - } - _upgrader.complete(); - checkUnresolvedDependencies(); - applyUpgrade(); - - _eventLogger.message(_logSubject, ConfigStoreMessages.RECOVERY_COMPLETE()); - return BrokerModel.MODEL_VERSION; - } - - private String getConfigVersionFromRecords() - { - String configVersion = BrokerModel.MODEL_VERSION; - for (ConfiguredObjectRecord record : _records) - { - if ("VirtualHost".equals(record.getType())) - { - configVersion = (String) record.getAttributes().get("modelVersion"); - _logger.debug("Confifuration has config version : " + configVersion); - break; - } - } - return configVersion; - } - - void onConfiguredObject(ConfiguredObjectRecord record) - { - DurableConfiguredObjectRecoverer recoverer = getRecoverer(record.getType()); - if(recoverer == null) - { - throw new IllegalConfigurationException("Unknown type for configured object: " + record.getType()); - } - recoverer.load(this, record); - } - - - private DurableConfiguredObjectRecoverer getRecoverer(final String type) - { - DurableConfiguredObjectRecoverer recoverer = _recoverers.get(type); - return recoverer; - } - - private void applyUpgrade() - { - - final Collection updates = new HashSet(_upgrader.getUpdatedRecords().values()); - final Collection deletes = new HashSet(_upgrader.getDeletedRecords().values()); - - // Due to the way the upgraders work it is possible that the updates list may contain nulls - updates.remove(null); - deletes.remove(null); - - if(!updates.isEmpty()) - { - _store.update(true,updates.toArray(new ConfiguredObjectRecord[updates.size()])); - } - if(!deletes.isEmpty()) - { - _store.remove(deletes.toArray(new ConfiguredObjectRecord[deletes.size()])); - } - - } - - private void checkUnresolvedDependencies() - { - if(_unresolvedObjects != null && !_unresolvedObjects.isEmpty()) - { - boolean unresolvedObjectsExist = false; - for(Map.Entry>entry : _unresolvedObjects.entrySet()) - { - for(Map.Entry obj : entry.getValue().entrySet()) - { - unresolvedObjectsExist = true; - StringBuilder errorMessage = new StringBuilder("Durable configured object of type "); - errorMessage.append(entry.getKey()).append(" with id ").append(obj.getKey()) - .append(" has unresolved dependencies: "); - for(UnresolvedDependency dep : obj.getValue().getUnresolvedDependencies()) - { - errorMessage.append(dep.getType()).append(" with id ").append(dep.getId()).append("; "); - } - _logger.error(errorMessage); - } - } - if(unresolvedObjectsExist) - { - throw new IllegalConfigurationException("Durable configuration has unresolved dependencies"); - } - } - } - - void addResolutionListener(final String type, - final UUID id, - final String name, - final DependencyListener dependencyListener) - { - if(id != null) - { - Map> typeListeners = _dependencyListeners.get(type); - if (typeListeners == null) - { - typeListeners = new HashMap>(); - _dependencyListeners.put(type, typeListeners); - } - List objectListeners = typeListeners.get(id); - if (objectListeners == null) - { - objectListeners = new ArrayList(); - typeListeners.put(id, objectListeners); - } - objectListeners.add(dependencyListener); - } - else - { - Map> typeListeners = _dependencyNameListeners.get(type); - if (typeListeners == null) - { - typeListeners = new HashMap>(); - _dependencyNameListeners.put(type, typeListeners); - } - List objectListeners = typeListeners.get(name); - if (objectListeners == null) - { - objectListeners = new ArrayList(); - typeListeners.put(name, objectListeners); - } - objectListeners.add(dependencyListener); - } - } - - Object getResolvedObject(final String type, final UUID id) - { - Map objects = _resolvedObjects.get(type); - return objects == null ? null : objects.get(id); - } - - Object getResolvedObject(final String type, final String name) - { - Map objects = _resolvedObjects.get(type); - if(objects != null) - { - for (ConfiguredObject object : objects.values()) - { - if(object.getName().equals(name)) - { - return object; - } - } - } - return null; - - } - - void resolve(final String type, final UUID id, final ConfiguredObject object) - { - Map typeObjects = _resolvedObjects.get(type); - if(typeObjects == null) - { - typeObjects = new HashMap(); - _resolvedObjects.put(type, typeObjects); - } - typeObjects.put(id, object); - Map unresolved = _unresolvedObjects.get(type); - if(unresolved != null) - { - unresolved.remove(id); - } - - Map> typeListeners = _dependencyListeners.get(type); - if(typeListeners != null) - { - List listeners = typeListeners.remove(id); - if(listeners != null) - { - for(DependencyListener listener : listeners) - { - listener.dependencyResolved(type, id, object); - } - } - } - - Map> typeNameListeners = _dependencyNameListeners.get(type); - if(typeNameListeners != null) - { - List listeners = typeNameListeners.remove(object.getName()); - if(listeners != null) - { - for(DependencyListener listener : listeners) - { - listener.dependencyResolved(type, id, object); - } - } - } - } - - void addUnresolvedObject(final String type, - final UUID id, - final UnresolvedObject obj) - { - Map typeObjects = _unresolvedObjects.get(type); - if(typeObjects == null) - { - typeObjects = new HashMap(); - _unresolvedObjects.put(type, typeObjects); - } - typeObjects.put(id, obj); - } - - -} diff --git a/java/broker-core/src/main/java/org/apache/qpid/server/store/DurableConfigurationStore.java b/java/broker-core/src/main/java/org/apache/qpid/server/store/DurableConfigurationStore.java index 7d93f18906..7d1abb020e 100755 --- a/java/broker-core/src/main/java/org/apache/qpid/server/store/DurableConfigurationStore.java +++ b/java/broker-core/src/main/java/org/apache/qpid/server/store/DurableConfigurationStore.java @@ -30,8 +30,6 @@ public interface DurableConfigurationStore { String STORE_TYPE = "storeType"; String STORE_PATH = "storePath"; - String IS_MESSAGE_STORE_TOO = "isMessageStoreToo"; - public static interface Source { diff --git a/java/broker-core/src/main/java/org/apache/qpid/server/store/DurableConfiguredObjectRecoverer.java b/java/broker-core/src/main/java/org/apache/qpid/server/store/DurableConfiguredObjectRecoverer.java deleted file mode 100644 index 4c618f5089..0000000000 --- a/java/broker-core/src/main/java/org/apache/qpid/server/store/DurableConfiguredObjectRecoverer.java +++ /dev/null @@ -1,32 +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.store; - -import java.util.Map; -import java.util.UUID; - -public interface DurableConfiguredObjectRecoverer -{ - public void load(final DurableConfigurationRecoverer durableConfigurationRecoverer, - final ConfiguredObjectRecord record); - - public String getType(); -} diff --git a/java/broker-core/src/main/java/org/apache/qpid/server/store/JsonFileConfigStore.java b/java/broker-core/src/main/java/org/apache/qpid/server/store/JsonFileConfigStore.java index 23ecc6f243..dcacb1ae7f 100644 --- a/java/broker-core/src/main/java/org/apache/qpid/server/store/JsonFileConfigStore.java +++ b/java/broker-core/src/main/java/org/apache/qpid/server/store/JsonFileConfigStore.java @@ -48,7 +48,6 @@ import org.codehaus.jackson.map.SerializationConfig; import org.codehaus.jackson.map.SerializerProvider; import org.codehaus.jackson.map.module.SimpleModule; -import org.apache.qpid.server.model.BrokerModel; import org.apache.qpid.server.model.ConfiguredObject; import org.apache.qpid.server.model.Model; import org.apache.qpid.server.model.VirtualHost; @@ -57,19 +56,19 @@ import org.apache.qpid.server.store.handler.ConfiguredObjectRecordHandler; public class JsonFileConfigStore implements DurableConfigurationStore { - private Map> _classNameMapping; public static final String TYPE = "JSON"; private final Map _objectsById = new HashMap(); private final Map> _idsByType = new HashMap>(); private final ObjectMapper _objectMapper = new ObjectMapper(); + private final Class _rootClass; + private Map> _classNameMapping; private String _directoryName; private String _name; private FileLock _fileLock; private String _configFileName; private String _backupFileName; - private int _configVersion; private static final Module _module; static @@ -95,9 +94,15 @@ public class JsonFileConfigStore implements DurableConfigurationStore private ConfiguredObject _parent; public JsonFileConfigStore() + { + this(VirtualHost.class); + } + + public JsonFileConfigStore(Class rootClass) { _objectMapper.registerModule(_module); _objectMapper.enable(SerializationConfig.Feature.INDENT_OUTPUT); + _rootClass = rootClass; } @Override @@ -105,7 +110,7 @@ public class JsonFileConfigStore implements DurableConfigurationStore { _parent = parent; _name = parent.getName(); - _classNameMapping = generateClassNameMap(_parent.getModel(), VirtualHost.class); + _classNameMapping = generateClassNameMap(_parent.getModel(), _rootClass); setup(storeSettings); load(); } @@ -260,48 +265,26 @@ public class JsonFileConfigStore implements DurableConfigurationStore } - protected void loadFromMap(final Map data) + protected void loadFromMap(final Map data) { - Collection> childClasses = - _parent.getModel().getChildTypes(VirtualHost.class); - data.remove("modelVersion"); - Object configVersion; - if((configVersion = data.remove("configVersion")) instanceof Integer) + if (!data.isEmpty()) { - _configVersion = (Integer) configVersion; - } - for(Class childClass : childClasses) - { - final String type = childClass.getSimpleName(); - String attrName = type.toLowerCase() + "s"; - Object children = data.remove(attrName); - if(children != null) - { - if(children instanceof Collection) - { - for(Object child : (Collection)children) - { - if(child instanceof Map) - { - loadChild(childClass, (Map)child, VirtualHost.class, null); - } - } - } - } + loadChild(_rootClass, data, null, null); } } + private void loadChild(final Class clazz, final Map data, final Class parentClass, final UUID parentId) { - Collection> childClasses = - _parent.getModel().getChildTypes(clazz); String idStr = (String) data.remove("id"); final UUID id = UUID.fromString(idStr); final String type = clazz.getSimpleName(); + Map parentMap = new HashMap(); + Collection> childClasses = _parent.getModel().getChildTypes(clazz); for(Class childClass : childClasses) { final String childType = childClass.getSimpleName(); @@ -322,7 +305,6 @@ public class JsonFileConfigStore implements DurableConfigurationStore } } - Map parentMap = new HashMap(); if(parentId != null) { parentMap.put(parentClass.getSimpleName(),parentId); @@ -356,7 +338,6 @@ public class JsonFileConfigStore implements DurableConfigurationStore _idsByType.put(type, idsForType); } idsForType.add(id); - } @Override @@ -380,42 +361,38 @@ public class JsonFileConfigStore implements DurableConfigurationStore idsForType = new ArrayList(); _idsByType.put(record.getType(), idsForType); } + + if (_rootClass.getSimpleName().equals(record.getType()) && idsForType.size() > 0) + { + throw new IllegalStateException("Only a single root entry of type " + _rootClass.getSimpleName() + " can exist in the store."); + } + idsForType.add(record.getId()); + save(); } } - private void save() + private UUID getRootId() { - Collection> childClasses = - _parent.getModel().getChildTypes(VirtualHost.class); - - Map virtualHostMap = new LinkedHashMap(); - virtualHostMap.put("modelVersion", BrokerModel.MODEL_VERSION); - virtualHostMap.put("configVersion", _configVersion); - - for(Class childClass : childClasses) + List ids = _idsByType.get(_rootClass.getSimpleName()); + if (ids == null) { - final String type = childClass.getSimpleName(); - String attrName = type.toLowerCase() + "s"; - List childIds = _idsByType.get(type); - if(childIds != null && !childIds.isEmpty()) - { - List> entities = new ArrayList>(); - for(UUID id : childIds) - { - entities.add(build(childClass,id)); - } - virtualHostMap.put(attrName, entities); - } + throw new IllegalStateException("Root entry of type " + _rootClass.getSimpleName() + " does not exist in the store."); } + return ids.get(0); + } + + private void save() + { + UUID rootId = getRootId(); + Map data = build(_rootClass, rootId); try { - File tmpFile = File.createTempFile("cfg","tmp", new File(_directoryName)); tmpFile.deleteOnExit(); - _objectMapper.writeValue(tmpFile,virtualHostMap); + _objectMapper.writeValue(tmpFile,data); renameFile(_configFileName,_backupFileName); renameFile(tmpFile.getName(),_configFileName); tmpFile.delete(); @@ -489,6 +466,11 @@ public class JsonFileConfigStore implements DurableConfigurationStore @Override public synchronized UUID[] remove(final ConfiguredObjectRecord... objects) throws StoreException { + if (objects.length == 0) + { + return new UUID[0]; + } + List removedIds = new ArrayList(); for(ConfiguredObjectRecord requestedRecord : objects) { @@ -508,6 +490,11 @@ public class JsonFileConfigStore implements DurableConfigurationStore public void update(final boolean createIfNecessary, final ConfiguredObjectRecord... records) throws StoreException { + if (records.length == 0) + { + return; + } + for(ConfiguredObjectRecord record : records) { final UUID id = record.getId(); @@ -647,6 +634,15 @@ public class JsonFileConfigStore implements DurableConfigurationStore } return parents; } + + @Override + public String toString() + { + return "ConfiguredObjectRecordImpl [_id=" + _id + ", _type=" + _type + ", _attributes=" + _attributes + ", _parents=" + + _parents + "]"; + } + } + } diff --git a/java/broker-core/src/main/java/org/apache/qpid/server/store/JsonFileConfigStoreFactory.java b/java/broker-core/src/main/java/org/apache/qpid/server/store/JsonFileConfigStoreFactory.java index 83c8ec2a21..b69bd6f45f 100644 --- a/java/broker-core/src/main/java/org/apache/qpid/server/store/JsonFileConfigStoreFactory.java +++ b/java/broker-core/src/main/java/org/apache/qpid/server/store/JsonFileConfigStoreFactory.java @@ -40,12 +40,9 @@ public class JsonFileConfigStoreFactory implements DurableConfigurationStoreFact } @Override - public void validateAttributes(Map attributes) + public void validateConfigurationStoreSettings(Map attributes) { - @SuppressWarnings("unchecked") - Map configurationStoreSettings = (Map) attributes.get(VirtualHost.CONFIGURATION_STORE_SETTINGS); - - Object storePath = configurationStoreSettings.get(DurableConfigurationStore.STORE_PATH); + Object storePath = attributes.get(DurableConfigurationStore.STORE_PATH); if(!(storePath instanceof String)) { throw new IllegalArgumentException("Setting '"+ DurableConfigurationStore.STORE_PATH @@ -53,4 +50,5 @@ public class JsonFileConfigStoreFactory implements DurableConfigurationStoreFact } } + } diff --git a/java/broker-core/src/main/java/org/apache/qpid/server/store/MessageStore.java b/java/broker-core/src/main/java/org/apache/qpid/server/store/MessageStore.java index 433f618d1a..4545aa9211 100644 --- a/java/broker-core/src/main/java/org/apache/qpid/server/store/MessageStore.java +++ b/java/broker-core/src/main/java/org/apache/qpid/server/store/MessageStore.java @@ -67,6 +67,7 @@ public interface MessageStore String getStoreLocation(); + // TODO change to have separate delete methods for configuration and message store. void onDelete(); void visitMessages(MessageHandler handler) throws StoreException; diff --git a/java/broker-core/src/main/java/org/apache/qpid/server/store/NullUpgrader.java b/java/broker-core/src/main/java/org/apache/qpid/server/store/NullUpgrader.java index b17dd4a6f3..ffa224d0f4 100644 --- a/java/broker-core/src/main/java/org/apache/qpid/server/store/NullUpgrader.java +++ b/java/broker-core/src/main/java/org/apache/qpid/server/store/NullUpgrader.java @@ -26,17 +26,10 @@ import java.util.UUID; public final class NullUpgrader implements DurableConfigurationStoreUpgrader { - private DurableConfigurationRecoverer _durableConfigurationRecoverer; - - public NullUpgrader(final DurableConfigurationRecoverer durableConfigurationRecoverer) - { - _durableConfigurationRecoverer = durableConfigurationRecoverer; - } @Override public void configuredObject(final ConfiguredObjectRecord record) { - _durableConfigurationRecoverer.onConfiguredObject(record); } @Override diff --git a/java/broker-core/src/main/java/org/apache/qpid/server/store/UpgraderProvider.java b/java/broker-core/src/main/java/org/apache/qpid/server/store/UpgraderProvider.java deleted file mode 100644 index 9785be78a6..0000000000 --- a/java/broker-core/src/main/java/org/apache/qpid/server/store/UpgraderProvider.java +++ /dev/null @@ -1,26 +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.store; - -public interface UpgraderProvider -{ - DurableConfigurationStoreUpgrader getUpgrader(String configVersion, DurableConfigurationRecoverer recoverer); -} diff --git a/java/broker-core/src/main/java/org/apache/qpid/server/store/VirtualHostStoreUpgraderAndRecoverer.java b/java/broker-core/src/main/java/org/apache/qpid/server/store/VirtualHostStoreUpgraderAndRecoverer.java new file mode 100644 index 0000000000..226371a065 --- /dev/null +++ b/java/broker-core/src/main/java/org/apache/qpid/server/store/VirtualHostStoreUpgraderAndRecoverer.java @@ -0,0 +1,713 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.server.store; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; +import java.util.Iterator; +import java.util.LinkedHashMap; +import java.util.Map; +import java.util.Map.Entry; +import java.util.UUID; + +import org.apache.log4j.Logger; +import org.apache.qpid.server.configuration.startup.StoreUpgraderPhase; +import org.apache.qpid.server.configuration.startup.UpgraderPhaseFactory; +import org.apache.qpid.server.filter.FilterSupport; +import org.apache.qpid.server.model.Binding; +import org.apache.qpid.server.model.BrokerModel; +import org.apache.qpid.server.model.ConfiguredObject; +import org.apache.qpid.server.model.ConfiguredObjectFactory; +import org.apache.qpid.server.model.Exchange; +import org.apache.qpid.server.model.Queue; +import org.apache.qpid.server.model.UUIDGenerator; +import org.apache.qpid.server.model.VirtualHost; +import org.apache.qpid.server.model.VirtualHostNode; +import org.apache.qpid.server.queue.QueueArgumentsConverter; +import org.apache.qpid.server.store.handler.ConfiguredObjectRecordHandler; +import org.apache.qpid.server.util.ServerScopedRuntimeException; + +public class VirtualHostStoreUpgraderAndRecoverer +{ + private final ConfiguredObjectFactory _objectFactory; + private final VirtualHostNode _virtualHostNode; + private Map _upgraders = new HashMap(); + + @SuppressWarnings("serial") + private static final Map DEFAULT_EXCHANGES = Collections.unmodifiableMap(new HashMap() + {{ + put("amq.direct", "direct"); + put("amq.topic", "topic"); + put("amq.fanout", "fanout"); + put("amq.match", "headers"); + }}); + + private final Map _defaultExchangeIds; + + public VirtualHostStoreUpgraderAndRecoverer(VirtualHostNode virtualHostNode, ConfiguredObjectFactory objectFactory) + { + _virtualHostNode = virtualHostNode; + _objectFactory = objectFactory; + register(new UpgraderFactory_0_0()); + register(new UpgraderFactory_0_1()); + register(new UpgraderFactory_0_2()); + register(new UpgraderFactory_0_3()); + register(new UpgraderFactory_0_4()); + + Map defaultExchangeIds = new HashMap(); + for (String exchangeName : DEFAULT_EXCHANGES.keySet()) + { + UUID id = UUIDGenerator.generateExchangeUUID(exchangeName, virtualHostNode.getName()); + defaultExchangeIds.put(exchangeName, id); + } + _defaultExchangeIds = Collections.unmodifiableMap(defaultExchangeIds); + } + + private void register(UpgraderPhaseFactory factory) + { + _upgraders.put(factory.getFromVersion(), factory); + } + + /* + * Removes filters from queue bindings to exchanges other than topic exchanges. In older versions of the broker + * such bindings would have been ignored, starting from the point at which the config version changed, these + * arguments would actually cause selectors to be enforced, thus changing which messages would reach a queue. + */ + private class UpgraderFactory_0_0 extends UpgraderPhaseFactory + { + private final Map _records = new HashMap(); + + public UpgraderFactory_0_0() + { + super("0.0", "0.1"); + } + + + @Override + public StoreUpgraderPhase newInstance() + { + return new StoreUpgraderPhase("modelVersion", getToVersion()) + { + + @Override + public void configuredObject(final ConfiguredObjectRecord record) + { + _records.put(record.getId(), record); + } + + private void removeSelectorArguments(Map binding) + { + @SuppressWarnings("unchecked") + Map arguments = new LinkedHashMap((Map)binding.get(Binding.ARGUMENTS)); + + FilterSupport.removeFilters(arguments); + binding.put(Binding.ARGUMENTS, arguments); + } + + private boolean isTopicExchange(ConfiguredObjectRecord entry) + { + ConfiguredObjectRecord exchangeRecord = entry.getParents().get("Exchange"); + if (exchangeRecord == null) + { + return false; + } + UUID exchangeId = exchangeRecord.getId(); + + if(_records.containsKey(exchangeId)) + { + return "topic".equals(_records.get(exchangeId) + .getAttributes() + .get(org.apache.qpid.server.model.Exchange.TYPE)); + } + else + { + if (_defaultExchangeIds.get("amq.topic").equals(exchangeId)) + { + return true; + } + + return false; + } + + } + + private boolean hasSelectorArguments(Map binding) + { + @SuppressWarnings("unchecked") + Map arguments = (Map) binding.get(Binding.ARGUMENTS); + return (arguments != null) && FilterSupport.argumentsContainFilter(arguments); + } + + @Override + public void complete() + { + for(Map.Entry entry : _records.entrySet()) + { + ConfiguredObjectRecord record = entry.getValue(); + String type = record.getType(); + Map attributes = record.getAttributes(); + UUID id = record.getId(); + if ("org.apache.qpid.server.model.VirtualHost".equals(type)) + { + record = upgradeRootRecord(record); + } + else if(type.equals(Binding.class.getName()) && hasSelectorArguments(attributes) && !isTopicExchange(record)) + { + attributes = new LinkedHashMap(attributes); + removeSelectorArguments(attributes); + + record = new ConfiguredObjectRecordImpl(id, type, attributes, record.getParents()); + getUpdateMap().put(id, record); + entry.setValue(record); + + } + getNextUpgrader().configuredObject(record); + } + + getNextUpgrader().complete(); + } + }; + } + + } + + /* + * Change the type string from org.apache.qpid.server.model.Foo to Foo (in line with the practice in the broker + * configuration store). Also remove bindings which reference nonexistent queues or exchanges. + */ + private class UpgraderFactory_0_1 extends UpgraderPhaseFactory + { + protected UpgraderFactory_0_1() + { + super("0.1", "0.2"); + } + + @Override + public StoreUpgraderPhase newInstance() + { + return new StoreUpgraderPhase("modelVersion", getToVersion()) + { + + @Override + public void configuredObject(final ConfiguredObjectRecord record) + { + String type = record.getType().substring(1 + record.getType().lastIndexOf('.')); + ConfiguredObjectRecord newRecord = new ConfiguredObjectRecordImpl(record.getId(), type, record.getAttributes(), record.getParents()); + getUpdateMap().put(record.getId(), newRecord); + + if ("VirtualHost".equals(type)) + { + newRecord = upgradeRootRecord(newRecord); + } + } + + @Override + public void complete() + { + for (Iterator> iterator = getUpdateMap().entrySet().iterator(); iterator.hasNext();) + { + Map.Entry entry = iterator.next(); + final ConfiguredObjectRecord record = entry.getValue(); + final ConfiguredObjectRecord exchangeParent = record.getParents().get(Exchange.class.getSimpleName()); + final ConfiguredObjectRecord queueParent = record.getParents().get(Queue.class.getSimpleName()); + if(isBinding(record.getType()) && (exchangeParent == null || unknownExchange(exchangeParent.getId()) + || queueParent == null || unknownQueue(queueParent.getId()))) + { + getDeleteMap().put(entry.getKey(), entry.getValue()); + iterator.remove(); + } + else + { + getNextUpgrader().configuredObject(record); + } + } + getNextUpgrader().complete(); + } + + private boolean unknownExchange(final UUID exchangeId) + { + if (_defaultExchangeIds.containsValue(exchangeId)) + { + return false; + } + ConfiguredObjectRecord localRecord = getUpdateMap().get(exchangeId); + return !(localRecord != null && localRecord.getType().equals(Exchange.class.getSimpleName())); + } + + private boolean unknownQueue(final UUID queueId) + { + ConfiguredObjectRecord localRecord = getUpdateMap().get(queueId); + return !(localRecord != null && localRecord.getType().equals(Queue.class.getSimpleName())); + } + + private boolean isBinding(final String type) + { + return Binding.class.getSimpleName().equals(type); + } + }; + } + } + + + /* + * Convert the storage of queue attributes to remove the separate "ARGUMENT" attribute, and flatten the + * attributes into the map using the model attribute names rather than the wire attribute names + */ + private class UpgraderFactory_0_2 extends UpgraderPhaseFactory + { + protected UpgraderFactory_0_2() + { + super("0.2", "0.3"); + } + + @Override + public StoreUpgraderPhase newInstance() + { + return new StoreUpgraderPhase("modelVersion", getToVersion()) + { + private static final String ARGUMENTS = "arguments"; + + @SuppressWarnings("unchecked") + @Override + public void configuredObject(ConfiguredObjectRecord record) + { + if("VirtualHost".equals(record.getType())) + { + record = upgradeRootRecord(record); + } + else if("Queue".equals(record.getType())) + { + Map newAttributes = new LinkedHashMap(); + if(record.getAttributes().get(ARGUMENTS) instanceof Map) + { + newAttributes.putAll(QueueArgumentsConverter.convertWireArgsToModel((Map) record.getAttributes() + .get(ARGUMENTS))); + } + newAttributes.putAll(record.getAttributes()); + + record = new ConfiguredObjectRecordImpl(record.getId(), record.getType(), newAttributes, record.getParents()); + getUpdateMap().put(record.getId(), record); + } + + getNextUpgrader().configuredObject(record); + } + + @Override + public void complete() + { + getNextUpgrader().complete(); + } + }; + } + } + + /* + * Convert the storage of queue attribute exclusive to change exclusive from a boolean to an enum + * where exclusive was false it will now be "NONE", and where true it will now be "CONTAINER" + * ensure OWNER is null unless the exclusivity policy is CONTAINER + */ + private class UpgraderFactory_0_3 extends UpgraderPhaseFactory + { + protected UpgraderFactory_0_3() + { + super("0.3", "0.4"); + } + + @Override + public StoreUpgraderPhase newInstance() + { + return new StoreUpgraderPhase("modelVersion", getToVersion()) + { + private static final String EXCLUSIVE = "exclusive"; + + @Override + public void configuredObject(ConfiguredObjectRecord record) + { + if("VirtualHost".equals(record.getType())) + { + record = upgradeRootRecord(record); + } + else if(Queue.class.getSimpleName().equals(record.getType())) + { + Map newAttributes = new LinkedHashMap(record.getAttributes()); + if(record.getAttributes().get(EXCLUSIVE) instanceof Boolean) + { + boolean isExclusive = (Boolean) record.getAttributes().get(EXCLUSIVE); + newAttributes.put(EXCLUSIVE, isExclusive ? "CONTAINER" : "NONE"); + if(!isExclusive && record.getAttributes().containsKey("owner")) + { + newAttributes.remove("owner"); + } + } + else + { + newAttributes.remove("owner"); + } + if(!record.getAttributes().containsKey("durable")) + { + newAttributes.put("durable","true"); + } + + record = new ConfiguredObjectRecordImpl(record.getId(),record.getType(),newAttributes, record.getParents()); + getUpdateMap().put(record.getId(), record); + } + + getNextUpgrader().configuredObject(record); + } + + @Override + public void complete() + { + getNextUpgrader().complete(); + } + }; + } + } + + private class UpgraderFactory_0_4 extends UpgraderPhaseFactory + { + protected UpgraderFactory_0_4() + { + super("0.4", "2.0"); + } + + @Override + public StoreUpgraderPhase newInstance() + { + return new StoreUpgraderPhase("modelVersion", getToVersion()) + { + private Map _missingAmqpExchanges = new HashMap(DEFAULT_EXCHANGES); + private static final String EXCHANGE_NAME = "name"; + private static final String EXCHANGE_TYPE = "type"; + private static final String EXCHANGE_DURABLE = "durable"; + private ConfiguredObjectRecord _virtualHostRecord; + + @Override + public void configuredObject(ConfiguredObjectRecord record) + { + if("VirtualHost".equals(record.getType())) + { + record = upgradeRootRecord(record); + Map virtualHostAttributes = new HashMap(record.getAttributes()); + virtualHostAttributes.put("name", _virtualHostNode.getName()); + virtualHostAttributes.put("modelVersion", getToVersion()); + record = new ConfiguredObjectRecordImpl(record.getId(), "VirtualHost", virtualHostAttributes, Collections.emptyMap()); + _virtualHostRecord = record; + } + else if("Exchange".equals(record.getType())) + { + Map attributes = record.getAttributes(); + String name = (String)attributes.get(EXCHANGE_NAME); + _missingAmqpExchanges.remove(name); + } + getNextUpgrader().configuredObject(record); + } + + @Override + public void complete() + { + for (Entry entry : _missingAmqpExchanges.entrySet()) + { + String name = entry.getKey(); + String type = entry.getValue(); + UUID id = _defaultExchangeIds.get(name); + + Map attributes = new HashMap(); + attributes.put(EXCHANGE_NAME, name); + attributes.put(EXCHANGE_TYPE, type); + attributes.put(EXCHANGE_DURABLE, true); + + ConfiguredObjectRecord record = new ConfiguredObjectRecordImpl(id, Exchange.class.getSimpleName(), attributes, Collections.singletonMap(_virtualHostRecord.getType(), _virtualHostRecord)); + getUpdateMap().put(id, record); + + getNextUpgrader().configuredObject(record); + + } + + getNextUpgrader().complete(); + } + }; + } + + } + + public void perform(DurableConfigurationStore durableConfigurationStore) + { + UpgradeAndRecoveryHandler vhrh = new UpgradeAndRecoveryHandler(_virtualHostNode, _objectFactory, durableConfigurationStore, _upgraders); + durableConfigurationStore.visitConfiguredObjectRecords(vhrh); + } + + //TODO: generalize this class + private static class UpgradeAndRecoveryHandler implements ConfiguredObjectRecordHandler + { + private static Logger LOGGER = Logger.getLogger(UpgradeAndRecoveryHandler.class); + + private final Map _records = new LinkedHashMap(); + private Map _upgraders; + + private final VirtualHostNode _parent; + private final ConfiguredObjectFactory _configuredObjectFactory; + private final DurableConfigurationStore _store; + + public UpgradeAndRecoveryHandler(VirtualHostNode parent, ConfiguredObjectFactory configuredObjectFactory, DurableConfigurationStore durableConfigurationStore, Map upgraders) + { + super(); + _parent = parent; + _configuredObjectFactory = configuredObjectFactory; + _upgraders = upgraders; + _store = durableConfigurationStore; + } + + @Override + public void begin() + { + } + + @Override + public boolean handle(final ConfiguredObjectRecord record) + { + _records.put(record.getId(), record); + return true; + } + + @Override + public void end() + { + String version = getCurrentVersion(); + + if (LOGGER.isInfoEnabled()) + { + LOGGER.info("Store has model version " + version + ". Number of record(s) " + _records.size()); + } + + DurableConfigurationStoreUpgrader upgrader = buildUpgraderChain(version); + + for(ConfiguredObjectRecord record : _records.values()) + { + upgrader.configuredObject(record); + } + + upgrader.complete(); + + Map deletedRecords = upgrader.getDeletedRecords(); + Map updatedRecords = upgrader.getUpdatedRecords(); + + if (LOGGER.isDebugEnabled()) + { + LOGGER.debug("VirtualHost store upgrade: " + deletedRecords.size() + " record(s) deleted"); + LOGGER.debug("VirtualHost store upgrade: " + updatedRecords.size() + " record(s) updated"); + LOGGER.debug("VirtualHost store upgrade: " + _records.size() + " total record(s)"); + } + + _store.update(true, updatedRecords.values().toArray(new ConfiguredObjectRecord[updatedRecords.size()])); + _store.remove(deletedRecords.values().toArray(new ConfiguredObjectRecord[deletedRecords.size()])); + + _records.keySet().removeAll(deletedRecords.keySet()); + _records.putAll(updatedRecords); + + ConfiguredObjectRecord virtualHostRecord = null; + for (ConfiguredObjectRecord record : _records.values()) + { + LOGGER.debug("Found type " + record.getType()); + if ("VirtualHost".equals(record.getType())) + { + virtualHostRecord = record; + break; + } + } + + if (virtualHostRecord != null) + { + String parentCategory = _parent.getCategoryClass().getSimpleName(); + ConfiguredObjectRecord parentRecord = new ConfiguredObjectRecordImpl(_parent.getId(), parentCategory, Collections.emptyMap()); + Map rootParents = Collections.singletonMap(parentCategory, parentRecord); + _records.put(virtualHostRecord.getId(), new ConfiguredObjectRecordImpl(virtualHostRecord.getId(), VirtualHost.class.getSimpleName(), virtualHostRecord.getAttributes(), rootParents)); + Collection records = _records.values(); + resolveObjects(_configuredObjectFactory, _parent, records.toArray(new ConfiguredObjectRecord[records.size()])); + } + } + + private DurableConfigurationStoreUpgrader buildUpgraderChain(String version) + { + DurableConfigurationStoreUpgrader head = null; + while(!BrokerModel.MODEL_VERSION.equals(version)) + { + if (LOGGER.isDebugEnabled()) + { + LOGGER.debug("Adding virtual host store upgrader from model version: " + version); + } + final UpgraderPhaseFactory upgraderPhaseFactory = _upgraders.get(version); + StoreUpgraderPhase upgrader = upgraderPhaseFactory.newInstance(); + if(head == null) + { + head = upgrader; + } + else + { + head.setNextUpgrader(upgrader); + } + version = upgraderPhaseFactory.getToVersion(); + } + + if(head == null) + { + head = new NullUpgrader(); + } + else + { + head.setNextUpgrader(new NullUpgrader()); + } + + return head; + } + + private String getCurrentVersion() + { + for(ConfiguredObjectRecord record : _records.values()) + { + if(record.getType().equals("VirtualHost")) + { + return (String) record.getAttributes().get(VirtualHost.MODEL_VERSION); + } + } + return BrokerModel.MODEL_VERSION; + } + + + public void resolveObjects(ConfiguredObjectFactory factory, ConfiguredObject root, ConfiguredObjectRecord... records) + { + Map> resolvedObjects = new HashMap>(); + resolvedObjects.put(root.getId(), root); + + Collection recordsWithUnresolvedParents = new ArrayList(Arrays.asList(records)); + Collection> recordsWithUnresolvedDependencies = + new ArrayList>(); + + boolean updatesMade; + + do + { + updatesMade = false; + Iterator iter = recordsWithUnresolvedParents.iterator(); + while (iter.hasNext()) + { + ConfiguredObjectRecord record = iter.next(); + Collection> parents = new ArrayList>(); + boolean foundParents = true; + for (ConfiguredObjectRecord parent : record.getParents().values()) + { + if (!resolvedObjects.containsKey(parent.getId())) + { + foundParents = false; + break; + } + else + { + parents.add(resolvedObjects.get(parent.getId())); + } + } + if (foundParents) + { + iter.remove(); + UnresolvedConfiguredObject recovered = + factory.recover(record, parents.toArray(new ConfiguredObject[parents.size()])); + Collection> dependencies = + recovered.getUnresolvedDependencies(); + if (dependencies.isEmpty()) + { + updatesMade = true; + ConfiguredObject resolved = recovered.resolve(); + resolvedObjects.put(resolved.getId(), resolved); + } + else + { + recordsWithUnresolvedDependencies.add(recovered); + } + } + + } + + Iterator> unresolvedIter = + recordsWithUnresolvedDependencies.iterator(); + + while(unresolvedIter.hasNext()) + { + UnresolvedConfiguredObject unresolvedObject = unresolvedIter.next(); + Collection> dependencies = + new ArrayList>(unresolvedObject.getUnresolvedDependencies()); + + for(ConfiguredObjectDependency dependency : dependencies) + { + if(dependency instanceof ConfiguredObjectIdDependency) + { + UUID id = ((ConfiguredObjectIdDependency)dependency).getId(); + if(resolvedObjects.containsKey(id)) + { + dependency.resolve(resolvedObjects.get(id)); + } + } + else if(dependency instanceof ConfiguredObjectNameDependency) + { + ConfiguredObject dependentObject = null; + for(ConfiguredObject parent : unresolvedObject.getParents()) + { + dependentObject = parent.findConfiguredObject(dependency.getCategoryClass(), ((ConfiguredObjectNameDependency)dependency).getName()); + if(dependentObject != null) + { + break; + } + } + if(dependentObject != null) + { + dependency.resolve(dependentObject); + } + } + else + { + throw new ServerScopedRuntimeException("Unknown dependency type " + dependency.getClass().getSimpleName()); + } + } + if(unresolvedObject.getUnresolvedDependencies().isEmpty()) + { + updatesMade = true; + unresolvedIter.remove(); + ConfiguredObject resolved = unresolvedObject.resolve(); + resolvedObjects.put(resolved.getId(), resolved); + } + } + + } while(updatesMade && !(recordsWithUnresolvedDependencies.isEmpty() && recordsWithUnresolvedParents.isEmpty())); + + if(!recordsWithUnresolvedDependencies.isEmpty()) + { + throw new IllegalArgumentException("Cannot resolve some objects: " + recordsWithUnresolvedDependencies); + } + if(!recordsWithUnresolvedParents.isEmpty()) + { + throw new IllegalArgumentException("Cannot resolve object because their parents cannot be found" + recordsWithUnresolvedParents); + } + } + + } +} diff --git a/java/broker-core/src/main/java/org/apache/qpid/server/virtualhost/AbstractVirtualHost.java b/java/broker-core/src/main/java/org/apache/qpid/server/virtualhost/AbstractVirtualHost.java index 645c6061bd..18f728fdf6 100644 --- a/java/broker-core/src/main/java/org/apache/qpid/server/virtualhost/AbstractVirtualHost.java +++ b/java/broker-core/src/main/java/org/apache/qpid/server/virtualhost/AbstractVirtualHost.java @@ -41,7 +41,6 @@ import java.util.concurrent.atomic.AtomicBoolean; import javax.security.auth.Subject; import org.apache.log4j.Logger; - import org.apache.qpid.exchange.ExchangeDefaults; import org.apache.qpid.server.configuration.BrokerProperties; import org.apache.qpid.server.configuration.IllegalConfigurationException; @@ -51,7 +50,6 @@ import org.apache.qpid.server.exchange.AMQUnknownExchangeType; import org.apache.qpid.server.exchange.DefaultDestination; import org.apache.qpid.server.exchange.ExchangeImpl; import org.apache.qpid.server.logging.EventLogger; -import org.apache.qpid.server.logging.messages.ConfigStoreMessages; import org.apache.qpid.server.logging.messages.MessageStoreMessages; import org.apache.qpid.server.logging.messages.VirtualHostMessages; import org.apache.qpid.server.logging.subjects.MessageStoreLogSubject; @@ -60,9 +58,27 @@ import org.apache.qpid.server.message.MessageInstance; import org.apache.qpid.server.message.MessageNode; import org.apache.qpid.server.message.MessageSource; import org.apache.qpid.server.message.ServerMessage; -import org.apache.qpid.server.model.*; +import org.apache.qpid.server.model.AbstractConfiguredObject; +import org.apache.qpid.server.model.Broker; +import org.apache.qpid.server.model.BrokerModel; +import org.apache.qpid.server.model.ConfiguredObject; +import org.apache.qpid.server.model.Connection; +import org.apache.qpid.server.model.Exchange; +import org.apache.qpid.server.model.IntegrityViolationException; +import org.apache.qpid.server.model.LifetimePolicy; +import org.apache.qpid.server.model.ManagedAttributeField; +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.SystemContext; +import org.apache.qpid.server.model.UUIDGenerator; +import org.apache.qpid.server.model.VirtualHost; +import org.apache.qpid.server.model.VirtualHostAlias; +import org.apache.qpid.server.model.VirtualHostNode; import org.apache.qpid.server.model.adapter.ConnectionAdapter; import org.apache.qpid.server.model.adapter.VirtualHostAliasAdapter; +import org.apache.qpid.server.plugin.MessageStoreFactory; import org.apache.qpid.server.plugin.QpidServiceLoader; import org.apache.qpid.server.plugin.SystemNodeCreator; import org.apache.qpid.server.protocol.AMQConnectionModel; @@ -74,7 +90,6 @@ import org.apache.qpid.server.security.access.Operation; import org.apache.qpid.server.stats.StatisticsCounter; import org.apache.qpid.server.store.ConfiguredObjectRecord; import org.apache.qpid.server.store.DurableConfigurationStore; -import org.apache.qpid.server.store.DurableConfiguredObjectRecoverer; import org.apache.qpid.server.store.Event; import org.apache.qpid.server.store.EventListener; import org.apache.qpid.server.store.MessageStore; @@ -131,13 +146,11 @@ public abstract class AbstractVirtualHost> exte private final List _aliases = new ArrayList(); private final AtomicBoolean _deleted = new AtomicBoolean(); + private final VirtualHostNode _virtualHostNode; @ManagedAttributeField private Map _messageStoreSettings; - @ManagedAttributeField - private Map _configurationStoreSettings; - @ManagedAttributeField private boolean _queue_deadLetterQueueEnabled; @@ -163,12 +176,13 @@ public abstract class AbstractVirtualHost> exte private String _securityAcl; private MessageDestination _defaultDestination; - - public AbstractVirtualHost(final Map attributes, Broker broker) + public AbstractVirtualHost(final Map attributes, VirtualHostNode virtualHostNode) { - super(parentsMap(broker), - enhanceWithId(attributes), broker.getTaskExecutor()); - _broker = broker; + super(Collections.,ConfiguredObject>singletonMap(VirtualHostNode.class, virtualHostNode), + enhanceWithId(attributes), ((Broker)virtualHostNode.getParent(Broker.class)).getTaskExecutor()); + _broker = virtualHostNode.getParent(Broker.class); + _virtualHostNode = virtualHostNode; + _dtxRegistry = new DtxRegistry(); _eventLogger = _broker.getParent(SystemContext.class).getEventLogger(); @@ -209,6 +223,41 @@ public abstract class AbstractVirtualHost> exte { throw new IllegalArgumentException(getClass().getSimpleName() + " must be durable"); } + + DurableConfigurationStore durableConfigurationStore = _virtualHostNode.getConfigurationStore(); + + boolean nodeIsMessageStoreProvider = _virtualHostNode.isMessageStoreProvider(); + if (nodeIsMessageStoreProvider) + { + if (!(durableConfigurationStore instanceof MessageStore)) + { + throw new IllegalConfigurationException("Virtual host node " + _virtualHostNode.getName() + + " is configured as a provider of message store but the MessageStore interface is not implemented on a configuration store of type " + + durableConfigurationStore.getClass().getName()); + } + } + else + { + Map messageStoreSettings = getMessageStoreSettings(); + if (messageStoreSettings == null) + { + throw new IllegalConfigurationException("Message store settings are missed for VirtualHost " + getName() + + ". You can either configure the message store setting on the host or " + + (durableConfigurationStore instanceof MessageStore ? + " configure VirtualHostNode " + _virtualHostNode.getName() + " as a provider of message store" : + " change the node type to one having configuration store implementing the MessageStore inteface") ); + } + String storeType = (String) messageStoreSettings.get(MessageStore.STORE_TYPE); + if (storeType == null) + { + throw new IllegalConfigurationException("Message store type setting is not set"); + } + MessageStoreFactory factory = MessageStoreFactory.FACTORY_LOADER.get(storeType); + if (factory == null) + { + throw new IllegalConfigurationException("Message store factory is not found for type " + storeType + " for VirtualHost " + getName()); + } + } } @Override @@ -224,18 +273,17 @@ public abstract class AbstractVirtualHost> exte protected void onOpen() { super.onOpen(); - _houseKeepingTasks = new ScheduledThreadPoolExecutor(getHousekeepingThreadCount()); registerSystemNodes(); initialiseStatistics(); - Subject.doAs(getSecurityManager().getSubjectWithAddedSystemRights(), new PrivilegedAction() + Subject.doAs(SecurityManager.getSubjectWithAddedSystemRights(), new PrivilegedAction() { @Override public Object run() { - initialiseStorage(AbstractVirtualHost.this); + initialiseStorage(); return null; } }); @@ -280,7 +328,7 @@ public abstract class AbstractVirtualHost> exte } } - abstract protected void initialiseStorage(org.apache.qpid.server.model.VirtualHost virtualHost); + abstract protected void initialiseStorage(); protected boolean isStoreEmpty() { @@ -547,7 +595,6 @@ public abstract class AbstractVirtualHost> exte return _houseKeepingTasks.getActiveCount(); } - public long getCreateTime() { return _createTime; @@ -620,8 +667,6 @@ public abstract class AbstractVirtualHost> exte private AMQQueue addQueueWithoutDLQ(Map attributes) throws QueueExistsException { - - try { return (AMQQueue) getObjectFactory().create(Queue.class, attributes, this); @@ -779,8 +824,6 @@ public abstract class AbstractVirtualHost> exte throws ExchangeExistsException, ReservedExchangeNameException, UnknownExchangeException, AMQUnknownExchangeType { - - try { return (ExchangeImpl) getObjectFactory().create(Exchange.class, attributes, this); @@ -815,6 +858,9 @@ public abstract class AbstractVirtualHost> exte _state = VirtualHostState.STOPPED; _eventLogger.message(VirtualHostMessages.CLOSED(getName())); + + // TODO: The state work will replace this with closure of the virtualhost, rather than deleting it. + deleted(); } private void closeStorage() @@ -830,28 +876,11 @@ public abstract class AbstractVirtualHost> exte _logger.error("Failed to close message store", e); } } - if (getDurableConfigurationStore() != null) + + if (!_virtualHostNode.isMessageStoreProvider()) { - try - { - getDurableConfigurationStore().closeConfigurationStore(); - MessageStoreLogSubject configurationStoreSubject = getConfigurationStoreLogSubject(); - if (configurationStoreSubject != null) - { - getEventLogger().message(configurationStoreSubject, ConfigStoreMessages.CLOSE()); - } - } - catch (StoreException e) - { - _logger.error("Failed to close configuration store", e); - } + getEventLogger().message(getMessageStoreLogSubject(), MessageStoreMessages.CLOSED()); } - getEventLogger().message(getMessageStoreLogSubject(), MessageStoreMessages.CLOSED()); - } - - protected MessageStoreLogSubject getConfigurationStoreLogSubject() - { - return null; } public void registerMessageDelivered(long messageSize) @@ -925,11 +954,6 @@ public abstract class AbstractVirtualHost> exte return _dtxRegistry; } - public String toString() - { - return getName(); - } - public VirtualHostState getVirtualHostState() { return _state; @@ -1029,22 +1053,6 @@ public abstract class AbstractVirtualHost> exte _state = state; } - protected void attainActivation() - { - VirtualHostState finalState = VirtualHostState.ERRORED; - - try - { - initialiseHouseKeeping(getHousekeepingCheckPeriod()); - finalState = VirtualHostState.ACTIVE; - } - finally - { - _state = finalState; - reportIfError(_state); - } - } - protected void reportIfError(VirtualHostState state) { if (state == VirtualHostState.ERRORED) @@ -1053,22 +1061,6 @@ public abstract class AbstractVirtualHost> exte } } - protected Map getDurableConfigurationRecoverers() - { - DurableConfiguredObjectRecoverer[] recoverers = { - new QueueRecoverer(this), - new ExchangeRecoverer(this), - new BindingRecoverer(this) - }; - - final Map recovererMap= new HashMap(); - for(DurableConfiguredObjectRecoverer recoverer : recoverers) - { - recovererMap.put(recoverer.getType(), recoverer); - } - return recovererMap; - } - private static class IsStoreEmptyHandler implements ConfiguredObjectRecordHandler { private boolean _empty = true; @@ -1349,20 +1341,12 @@ public abstract class AbstractVirtualHost> exte return _storeTransactionOpenTimeoutWarn; } - @SuppressWarnings("unchecked") @Override public Map getMessageStoreSettings() { return _messageStoreSettings; } - @SuppressWarnings("unchecked") - @Override - public Map getConfigurationStoreSettings() - { - return _configurationStoreSettings; - } - @Override public long getQueueCount() { @@ -1424,6 +1408,7 @@ public abstract class AbstractVirtualHost> exte { if (desiredState == State.ACTIVE) { + activate(); return true; } else if (desiredState == State.STOPPED) @@ -1473,7 +1458,6 @@ public abstract class AbstractVirtualHost> exte return Collections.unmodifiableCollection(_aliases); } - private String createDLQ(final String queueName) { final String dlExchangeName = getDeadLetterExchangeName(queueName); @@ -1609,5 +1593,63 @@ public abstract class AbstractVirtualHost> exte return name + System.getProperty(BrokerProperties.PROPERTY_DEAD_LETTER_EXCHANGE_SUFFIX, VirtualHostImpl.DEFAULT_DLE_NAME_SUFFIX); } + @Override + public String getModelVersion() + { + return BrokerModel.MODEL_VERSION; + } + + @Override + public DurableConfigurationStore getDurableConfigurationStore() + { + return _virtualHostNode.getConfigurationStore(); + } + + @Override + protected void onCreate() + { + super.onCreate(); + getDurableConfigurationStore().create(asObjectRecord()); + } + + protected void activate() + { + _houseKeepingTasks = new ScheduledThreadPoolExecutor(getHousekeepingThreadCount()); + + boolean nodeIsMessageStoreProvider = _virtualHostNode.isMessageStoreProvider(); + + MessageStore messageStore = getMessageStore(); + Map messageStoreSettings = getMessageStoreSettings(); + if (messageStoreSettings == null) + { + messageStoreSettings = Collections.emptyMap(); + } + messageStore.openMessageStore(this, messageStoreSettings); + + if (!nodeIsMessageStoreProvider) + { + getEventLogger().message(getMessageStoreLogSubject(), MessageStoreMessages.CREATED()); + getEventLogger().message(getMessageStoreLogSubject(), MessageStoreMessages.STORE_LOCATION(messageStore.getStoreLocation())); + } + + if (isStoreEmpty()) + { + createDefaultExchanges(); + } + + new MessageStoreRecoverer(this, getMessageStoreLogSubject()).recover(); + + VirtualHostState finalState = VirtualHostState.ERRORED; + try + { + initialiseHouseKeeping(getHousekeepingCheckPeriod()); + finalState = VirtualHostState.ACTIVE; + } + finally + { + _state = finalState; + reportIfError(_state); + } + } } diff --git a/java/broker-core/src/main/java/org/apache/qpid/server/virtualhost/BindingRecoverer.java b/java/broker-core/src/main/java/org/apache/qpid/server/virtualhost/BindingRecoverer.java deleted file mode 100644 index 8aeff7f847..0000000000 --- a/java/broker-core/src/main/java/org/apache/qpid/server/virtualhost/BindingRecoverer.java +++ /dev/null @@ -1,195 +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.virtualhost; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.UUID; - -import org.apache.log4j.Logger; - -import org.apache.qpid.server.binding.BindingImpl; -import org.apache.qpid.server.exchange.ExchangeImpl; -import org.apache.qpid.server.model.Binding; -import org.apache.qpid.server.model.Broker; -import org.apache.qpid.server.model.ConfiguredObjectFactory; -import org.apache.qpid.server.model.Exchange; -import org.apache.qpid.server.model.Queue; -import org.apache.qpid.server.queue.AMQQueue; -import org.apache.qpid.server.store.AbstractDurableConfiguredObjectRecoverer; -import org.apache.qpid.server.store.ConfiguredObjectRecord; -import org.apache.qpid.server.store.UnresolvedConfiguredObject; -import org.apache.qpid.server.store.UnresolvedDependency; -import org.apache.qpid.server.store.UnresolvedObject; - -public class BindingRecoverer extends AbstractDurableConfiguredObjectRecoverer -{ - private static final Logger _logger = Logger.getLogger(BindingRecoverer.class); - - private final VirtualHostImpl _virtualHost; - private final ConfiguredObjectFactory _objectFactory; - - public BindingRecoverer(final VirtualHostImpl virtualHost) - { - _virtualHost = virtualHost; - Broker broker = _virtualHost.getParent(Broker.class); - _objectFactory = broker.getObjectFactory(); - } - - @Override - public UnresolvedObject createUnresolvedObject(ConfiguredObjectRecord record) - { - return new UnresolvedBinding(record); - } - - @Override - public String getType() - { - return org.apache.qpid.server.model.Binding.class.getSimpleName(); - } - - private class UnresolvedBinding implements UnresolvedObject - { - private final Map _bindingArgumentsMap; - private final String _bindingName; - private final UUID _queueId; - private final UUID _exchangeId; - private final UUID _bindingId; - private final ConfiguredObjectRecord _record; - - private List _unresolvedDependencies = - new ArrayList(); - - private ExchangeImpl _exchange; - private AMQQueue _queue; - - public UnresolvedBinding(final ConfiguredObjectRecord record) - { - _record = record; - _bindingId = record.getId(); - _exchangeId = record.getParents().get(Exchange.class.getSimpleName()).getId(); - _queueId = record.getParents().get(Queue.class.getSimpleName()).getId(); - _exchange = _virtualHost.getExchange(_exchangeId); - if(_exchange == null) - { - _unresolvedDependencies.add(new ExchangeDependency()); - } - _queue = _virtualHost.getQueue(_queueId); - if(_queue == null) - { - _unresolvedDependencies.add(new QueueDependency()); - } - - - _bindingName = (String) record.getAttributes().get(org.apache.qpid.server.model.Binding.NAME); - _bindingArgumentsMap = (Map) record.getAttributes().get(org.apache.qpid.server.model.Binding.ARGUMENTS); - } - - @Override - public UnresolvedDependency[] getUnresolvedDependencies() - { - return _unresolvedDependencies.toArray(new UnresolvedDependency[_unresolvedDependencies.size()]); - } - - @Override - public BindingImpl resolve() - { - if(!_exchange.hasBinding(_bindingName, _queue)) - { - _logger.info("Restoring binding: (Exchange: " + _exchange.getName() + ", Queue: " + _queue.getName() - + ", Routing Key: " + _bindingName + ", Arguments: " + _bindingArgumentsMap + ")"); - - - Map attributesWithId = new HashMap(_record.getAttributes()); - attributesWithId.put(org.apache.qpid.server.model.Exchange.ID,_record.getId()); - attributesWithId.put(org.apache.qpid.server.model.Exchange.DURABLE,true); - - UnresolvedConfiguredObject unresolvedConfiguredObject = - _objectFactory.recover(_record, _exchange, _queue); - Binding binding = (Binding) unresolvedConfiguredObject.resolve(); - binding.open(); - - } - return (_exchange).getBinding(_bindingName, _queue); - } - - private class QueueDependency implements UnresolvedDependency - { - - @Override - public UUID getId() - { - return _queueId; - } - - @Override - public String getName() - { - return null; - } - - @Override - public String getType() - { - return Queue.class.getSimpleName(); - } - - @Override - public void resolve(final AMQQueue dependency) - { - _queue = dependency; - _unresolvedDependencies.remove(this); - } - - } - - private class ExchangeDependency implements UnresolvedDependency - { - - @Override - public UUID getId() - { - return _exchangeId; - } - - @Override - public String getName() - { - return null; - } - - @Override - public String getType() - { - return org.apache.qpid.server.model.Exchange.class.getSimpleName(); - } - - @Override - public void resolve(final ExchangeImpl dependency) - { - _exchange = dependency; - _unresolvedDependencies.remove(this); - } - } - } -} diff --git a/java/broker-core/src/main/java/org/apache/qpid/server/virtualhost/DefaultUpgraderProvider.java b/java/broker-core/src/main/java/org/apache/qpid/server/virtualhost/DefaultUpgraderProvider.java deleted file mode 100644 index 956d44a27e..0000000000 --- a/java/broker-core/src/main/java/org/apache/qpid/server/virtualhost/DefaultUpgraderProvider.java +++ /dev/null @@ -1,413 +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.virtualhost; - -import java.util.Collections; -import java.util.HashMap; -import java.util.LinkedHashMap; -import java.util.Map; -import java.util.Map.Entry; -import java.util.UUID; - -import org.apache.log4j.Logger; -import org.apache.qpid.server.exchange.TopicExchange; -import org.apache.qpid.server.filter.FilterSupport; -import org.apache.qpid.server.model.Binding; -import org.apache.qpid.server.model.BrokerModel; -import org.apache.qpid.server.model.Exchange; -import org.apache.qpid.server.model.Queue; -import org.apache.qpid.server.model.UUIDGenerator; -import org.apache.qpid.server.queue.QueueArgumentsConverter; -import org.apache.qpid.server.store.ConfiguredObjectRecord; -import org.apache.qpid.server.store.ConfiguredObjectRecordImpl; -import org.apache.qpid.server.store.DurableConfigurationRecoverer; -import org.apache.qpid.server.store.DurableConfigurationStoreUpgrader; -import org.apache.qpid.server.store.NonNullUpgrader; -import org.apache.qpid.server.store.NullUpgrader; -import org.apache.qpid.server.store.UpgraderProvider; - -public class DefaultUpgraderProvider implements UpgraderProvider -{ - private static final Logger LOGGER = Logger.getLogger(DefaultUpgraderProvider.class); - - public static final String EXCLUSIVE = "exclusive"; - public static final String NAME = "name"; - private final VirtualHostImpl _virtualHost; - - @SuppressWarnings("serial") - private static final Map DEFAULT_EXCHANGES = Collections.unmodifiableMap(new HashMap() - {{ - put("amq.direct", "direct"); - put("amq.topic", "topic"); - put("amq.fanout", "fanout"); - put("amq.match", "headers"); - }}); - - private final Map _defaultExchangeIds; - - public DefaultUpgraderProvider(final VirtualHostImpl virtualHost) - { - _virtualHost = virtualHost; - Map defaultExchangeIds = new HashMap(); - for (String exchangeName : DEFAULT_EXCHANGES.keySet()) - { - UUID id = UUIDGenerator.generateExchangeUUID(exchangeName, _virtualHost.getName()); - defaultExchangeIds.put(exchangeName, id); - } - _defaultExchangeIds = Collections.unmodifiableMap(defaultExchangeIds); - } - - public DurableConfigurationStoreUpgrader getUpgrader(final String configVersion, DurableConfigurationRecoverer recoverer) - { - if (LOGGER.isDebugEnabled()) - { - LOGGER.debug("Getting upgrader for configVersion: " + configVersion); - } - DurableConfigurationStoreUpgrader currentUpgrader = null; - - int conigVersionAsInteger = Integer.parseInt(configVersion.replace(".", "")); - switch(conigVersionAsInteger) - { - case 0: - currentUpgrader = addUpgrader(currentUpgrader, new Version0Upgrader()); - case 1: - currentUpgrader = addUpgrader(currentUpgrader, new Version1Upgrader()); - case 2: - currentUpgrader = addUpgrader(currentUpgrader, new Version2Upgrader()); - case 3: - currentUpgrader = addUpgrader(currentUpgrader, new Version3Upgrader()); - case 4: - currentUpgrader = addUpgrader(currentUpgrader, new Version4Upgrader()); - case (BrokerModel.MODEL_MAJOR_VERSION * 10) + BrokerModel.MODEL_MINOR_VERSION: - currentUpgrader = addUpgrader(currentUpgrader, new NullUpgrader(recoverer)); - break; - - default: - throw new IllegalStateException("Unknown configuration model version: " + configVersion - + ". Attempting to run an older instance against an upgraded configuration?"); - } - return currentUpgrader; - } - - private DurableConfigurationStoreUpgrader addUpgrader(DurableConfigurationStoreUpgrader currentUpgrader, - final DurableConfigurationStoreUpgrader nextUpgrader) - { - if(currentUpgrader == null) - { - currentUpgrader = nextUpgrader; - } - else - { - currentUpgrader.setNextUpgrader(nextUpgrader); - } - return currentUpgrader; - } - - /* - * Removes filters from queue bindings to exchanges other than topic exchanges. In older versions of the broker - * such bindings would have been ignored, starting from the point at which the config version changed, these - * arguments would actually cause selectors to be enforced, thus changing which messages would reach a queue. - */ - private class Version0Upgrader extends NonNullUpgrader - { - private final Map _records = new HashMap(); - - public Version0Upgrader() - { - } - - @Override - public void configuredObject(final ConfiguredObjectRecord record) - { - _records.put(record.getId(), record); - } - - private void removeSelectorArguments(Map binding) - { - @SuppressWarnings("unchecked") - Map arguments = new LinkedHashMap((Map)binding.get(Binding.ARGUMENTS)); - - FilterSupport.removeFilters(arguments); - binding.put(Binding.ARGUMENTS, arguments); - } - - private boolean isTopicExchange(ConfiguredObjectRecord entry) - { - ConfiguredObjectRecord exchangeRecord = entry.getParents().get("Exchange"); - if (exchangeRecord == null) - { - return false; - } - UUID exchangeId = exchangeRecord.getId(); - - if(_records.containsKey(exchangeId)) - { - return "topic".equals(_records.get(exchangeId) - .getAttributes() - .get(org.apache.qpid.server.model.Exchange.TYPE)); - } - else - { - if (_defaultExchangeIds.get("amq.topic").equals(exchangeId)) - { - return true; - } - - return _virtualHost.getExchange(exchangeId) != null - && _virtualHost.getExchange(exchangeId).getExchangeType() == TopicExchange.TYPE; - } - - } - - private boolean hasSelectorArguments(Map binding) - { - @SuppressWarnings("unchecked") - Map arguments = (Map) binding.get(Binding.ARGUMENTS); - return (arguments != null) && FilterSupport.argumentsContainFilter(arguments); - } - - - - @Override - public void complete() - { - for(Map.Entry entry : _records.entrySet()) - { - ConfiguredObjectRecord record = entry.getValue(); - String type = record.getType(); - Map attributes = record.getAttributes(); - UUID id = record.getId(); - if(type.equals(Binding.class.getName()) && hasSelectorArguments(attributes) && !isTopicExchange(record)) - { - attributes = new LinkedHashMap(attributes); - removeSelectorArguments(attributes); - - record = new ConfiguredObjectRecordImpl(id, type, attributes, record.getParents()); - getUpdateMap().put(id, record); - entry.setValue(record); - - } - getNextUpgrader().configuredObject(record); - } - - getNextUpgrader().complete(); - } - - } - - /* - * Change the type string from org.apache.qpid.server.model.Foo to Foo (in line with the practice in the broker - * configuration store). Also remove bindings which reference nonexistent queues or exchanges. - */ - private class Version1Upgrader extends NonNullUpgrader - { - - - @Override - public void configuredObject(final ConfiguredObjectRecord record) - { - String type = record.getType().substring(1 + record.getType().lastIndexOf('.')); - getUpdateMap().put(record.getId(), - new ConfiguredObjectRecordImpl(record.getId(), type, record.getAttributes(), record.getParents())); - } - - @Override - public void complete() - { - for(Map.Entry entry : getUpdateMap().entrySet()) - { - final ConfiguredObjectRecord record = entry.getValue(); - final ConfiguredObjectRecord exchangeParent = record.getParents().get(Exchange.class.getSimpleName()); - final ConfiguredObjectRecord queueParent = record.getParents().get(Queue.class.getSimpleName()); - if(isBinding(record.getType()) && (exchangeParent == null || unknownExchange(exchangeParent.getId()) - || queueParent == null || unknownQueue(queueParent.getId()))) - { - getDeleteMap().put(entry.getKey(), entry.getValue()); - entry.setValue(null); - } - else - { - getNextUpgrader().configuredObject(record); - } - } - getNextUpgrader().complete(); - } - - private boolean unknownExchange(final UUID exchangeId) - { - if (_defaultExchangeIds.containsValue(exchangeId)) - { - return false; - } - ConfiguredObjectRecord localRecord = getUpdateMap().get(exchangeId); - return !((localRecord != null && localRecord.getType().equals(Exchange.class.getSimpleName())) - || _virtualHost.getExchange(exchangeId) != null); - } - - private boolean unknownQueue(final UUID queueId) - { - ConfiguredObjectRecord localRecord = getUpdateMap().get(queueId); - return !((localRecord != null && localRecord.getType().equals(Queue.class.getSimpleName())) - || _virtualHost.getQueue(queueId) != null); - } - - private boolean isBinding(final String type) - { - return Binding.class.getSimpleName().equals(type); - } - - - } - - /* - * Convert the storage of queue attributes to remove the separate "ARGUMENT" attribute, and flatten the - * attributes into the map using the model attribute names rather than the wire attribute names - */ - private class Version2Upgrader extends NonNullUpgrader - { - - private static final String ARGUMENTS = "arguments"; - - @Override - public void configuredObject(ConfiguredObjectRecord record) - { - - if(Queue.class.getSimpleName().equals(record.getType())) - { - Map newAttributes = new LinkedHashMap(); - if(record.getAttributes().get(ARGUMENTS) instanceof Map) - { - newAttributes.putAll(QueueArgumentsConverter.convertWireArgsToModel((Map) record.getAttributes() - .get(ARGUMENTS))); - } - newAttributes.putAll(record.getAttributes()); - - record = new ConfiguredObjectRecordImpl(record.getId(), record.getType(), newAttributes, record.getParents()); - getUpdateMap().put(record.getId(), record); - } - - getNextUpgrader().configuredObject(record); - } - - @Override - public void complete() - { - getNextUpgrader().complete(); - } - } - - /* - * Convert the storage of queue attribute exclusive to change exclusive from a boolean to an enum - * where exclusive was false it will now be "NONE", and where true it will now be "CONTAINER" - * ensure OWNER is null unless the exclusivity policy is CONTAINER - */ - private class Version3Upgrader extends NonNullUpgrader - { - - @Override - public void configuredObject(ConfiguredObjectRecord record) - { - - if(Queue.class.getSimpleName().equals(record.getType())) - { - Map newAttributes = new LinkedHashMap(record.getAttributes()); - if(record.getAttributes().get(EXCLUSIVE) instanceof Boolean) - { - boolean isExclusive = (Boolean) record.getAttributes().get(EXCLUSIVE); - newAttributes.put(EXCLUSIVE, isExclusive ? "CONTAINER" : "NONE"); - if(!isExclusive && record.getAttributes().containsKey("owner")) - { - newAttributes.remove("owner"); - } - } - else - { - newAttributes.remove("owner"); - } - if(!record.getAttributes().containsKey("durable")) - { - newAttributes.put("durable","true"); - } - - record = new ConfiguredObjectRecordImpl(record.getId(),record.getType(),newAttributes, record.getParents()); - getUpdateMap().put(record.getId(), record); - } - - getNextUpgrader().configuredObject(record); - } - - @Override - public void complete() - { - getNextUpgrader().complete(); - } - } - - private class Version4Upgrader extends NonNullUpgrader - { - private Map _missingAmqpExchanges = new HashMap(DEFAULT_EXCHANGES); - - @Override - public void configuredObject(ConfiguredObjectRecord record) - { - if(Exchange.class.getSimpleName().equals(record.getType())) - { - Map attributes = record.getAttributes(); - String name = (String)attributes.get(NAME); - _missingAmqpExchanges.remove(name); - } - - getNextUpgrader().configuredObject(record); - } - - @Override - public void complete() - { - for (Entry entry : _missingAmqpExchanges.entrySet()) - { - String name = entry.getKey(); - String type = entry.getValue(); - UUID id = _defaultExchangeIds.get(name); - - if (LOGGER.isDebugEnabled()) - { - LOGGER.debug("Creating amqp exchange " + name + " with id " + id); - } - - Map attributes = new HashMap(); - attributes.put(org.apache.qpid.server.model.Exchange.NAME, name); - attributes.put(org.apache.qpid.server.model.Exchange.TYPE, type); - - attributes.put(org.apache.qpid.server.model.Exchange.DURABLE, true); - - ConfiguredObjectRecord virtualHostRecord = new ConfiguredObjectRecordImpl(_virtualHost.getId(), org.apache.qpid.server.model.VirtualHost.class.getSimpleName(), Collections.emptyMap()); - ConfiguredObjectRecord record = new ConfiguredObjectRecordImpl(id, Exchange.class.getSimpleName(), attributes, Collections.singletonMap(virtualHostRecord.getType(), virtualHostRecord)); - getUpdateMap().put(id, record); - - getNextUpgrader().configuredObject(record); - - } - - getNextUpgrader().complete(); - } - } - -} diff --git a/java/broker-core/src/main/java/org/apache/qpid/server/virtualhost/ExchangeRecoverer.java b/java/broker-core/src/main/java/org/apache/qpid/server/virtualhost/ExchangeRecoverer.java deleted file mode 100644 index 920f9f0675..0000000000 --- a/java/broker-core/src/main/java/org/apache/qpid/server/virtualhost/ExchangeRecoverer.java +++ /dev/null @@ -1,114 +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.virtualhost; - -import java.util.HashMap; -import java.util.Map; - -import org.apache.qpid.server.exchange.AMQUnknownExchangeType; -import org.apache.qpid.server.exchange.ExchangeImpl; -import org.apache.qpid.server.model.Broker; -import org.apache.qpid.server.model.ConfiguredObjectFactory; -import org.apache.qpid.server.model.Exchange; -import org.apache.qpid.server.store.AbstractDurableConfiguredObjectRecoverer; -import org.apache.qpid.server.store.ConfiguredObjectRecord; -import org.apache.qpid.server.store.UnresolvedConfiguredObject; -import org.apache.qpid.server.store.UnresolvedDependency; -import org.apache.qpid.server.store.UnresolvedObject; -import org.apache.qpid.server.util.ServerScopedRuntimeException; - -public class ExchangeRecoverer extends AbstractDurableConfiguredObjectRecoverer -{ - private final VirtualHostImpl _vhost; - private final ConfiguredObjectFactory _objectFactory; - - public ExchangeRecoverer(final VirtualHostImpl vhost) - { - _vhost = vhost; - Broker broker = _vhost.getParent(Broker.class); - _objectFactory = broker.getObjectFactory(); - } - - @Override - public String getType() - { - return org.apache.qpid.server.model.Exchange.class.getSimpleName(); - } - - @Override - public UnresolvedObject createUnresolvedObject(final ConfiguredObjectRecord record) - { - return new UnresolvedExchange(record); - } - - private class UnresolvedExchange implements UnresolvedObject - { - private ExchangeImpl _exchange; - - public UnresolvedExchange(ConfiguredObjectRecord record) - { - Map attributeMap = record.getAttributes(); - String exchangeName = (String) attributeMap.get(org.apache.qpid.server.model.Exchange.NAME); - try - { - _exchange = _vhost.getExchange(record.getId()); - if(_exchange == null) - { - _exchange = _vhost.getExchange(exchangeName); - } - if (_exchange == null) - { - Map attributesWithId = new HashMap(attributeMap); - attributesWithId.put(org.apache.qpid.server.model.Exchange.ID,record.getId()); - attributesWithId.put(org.apache.qpid.server.model.Exchange.DURABLE,true); - - UnresolvedConfiguredObject unresolvedConfiguredObject = - _objectFactory.recover(record, _vhost); - _exchange = (ExchangeImpl) unresolvedConfiguredObject.resolve(); - - } - } - catch (AMQUnknownExchangeType e) - { - throw new ServerScopedRuntimeException("Unknown exchange type found when attempting to restore " + - "exchanges, check classpath", e); - } - catch (UnknownExchangeException e) - { - throw new ServerScopedRuntimeException("Unknown alternate exchange type found when attempting to restore " + - "exchanges: ", e); - } - } - - @Override - public UnresolvedDependency[] getUnresolvedDependencies() - { - return new UnresolvedDependency[0]; - } - - @Override - public ExchangeImpl resolve() - { - _exchange.open(); - return _exchange; - } - } -} diff --git a/java/broker-core/src/main/java/org/apache/qpid/server/virtualhost/QueueRecoverer.java b/java/broker-core/src/main/java/org/apache/qpid/server/virtualhost/QueueRecoverer.java deleted file mode 100644 index 221727ab6b..0000000000 --- a/java/broker-core/src/main/java/org/apache/qpid/server/virtualhost/QueueRecoverer.java +++ /dev/null @@ -1,161 +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.virtualhost; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.UUID; - -import org.apache.log4j.Logger; - -import org.apache.qpid.server.exchange.ExchangeImpl; -import org.apache.qpid.server.model.Broker; -import org.apache.qpid.server.model.ConfiguredObjectFactory; -import org.apache.qpid.server.model.Queue; -import org.apache.qpid.server.queue.AMQQueue; -import org.apache.qpid.server.store.AbstractDurableConfiguredObjectRecoverer; -import org.apache.qpid.server.store.ConfiguredObjectRecord; -import org.apache.qpid.server.store.UnresolvedConfiguredObject; -import org.apache.qpid.server.store.UnresolvedDependency; -import org.apache.qpid.server.store.UnresolvedObject; - -public class QueueRecoverer extends AbstractDurableConfiguredObjectRecoverer -{ - private static final Logger _logger = Logger.getLogger(QueueRecoverer.class); - private final VirtualHostImpl _virtualHost; - private final ConfiguredObjectFactory _objectFactory; - - public QueueRecoverer(final VirtualHostImpl virtualHost) - { - _virtualHost = virtualHost; - Broker broker = _virtualHost.getParent(Broker.class); - _objectFactory = broker.getObjectFactory(); - } - - @Override - public String getType() - { - return Queue.class.getSimpleName(); - } - - @Override - public UnresolvedObject createUnresolvedObject(final ConfiguredObjectRecord record) - { - return new UnresolvedQueue(record); - } - - private class UnresolvedQueue implements UnresolvedObject - { - - // private final UUID _alternateExchangeId; - private final ConfiguredObjectRecord _record; - private AMQQueue _queue; - private List _dependencies = new ArrayList(); - private ExchangeImpl _alternateExchange; - private UUID _alternateExchangeId; - private String _alternateExchangeName; - - public UnresolvedQueue(ConfiguredObjectRecord record) - { - _record = record; - Object altExchObj = record.getAttributes().get(Queue.ALTERNATE_EXCHANGE); - if(altExchObj instanceof UUID) - { - _alternateExchangeId = (UUID) altExchObj; - _dependencies.add(new AlternateExchangeDependency()); - } - else if (altExchObj instanceof String) - { - try - { - _alternateExchangeId = UUID.fromString((String)altExchObj); - } - catch (IllegalArgumentException e) - { - _alternateExchangeName = (String) altExchObj; - } - _dependencies.add(new AlternateExchangeDependency()); - } - - } - - @Override - public UnresolvedDependency[] getUnresolvedDependencies() - { - return _dependencies.toArray(new UnresolvedDependency[_dependencies.size()]); - } - - @Override - public AMQQueue resolve() - { - String queueName = (String) _record.getAttributes().get(Queue.NAME); - - _queue = _virtualHost.getQueue(_record.getId()); - if(_queue == null) - { - _queue = _virtualHost.getQueue(queueName); - } - - if (_queue == null) - { - Map attributesWithId = new HashMap(_record.getAttributes()); - attributesWithId.put(Queue.ID,_record.getId()); - attributesWithId.put(Queue.DURABLE,true); - - UnresolvedConfiguredObject unresolvedConfiguredObject = - _objectFactory.recover(_record, _virtualHost); - _queue = (AMQQueue) unresolvedConfiguredObject.resolve(); - } - _queue.open(); - return _queue; - } - - private class AlternateExchangeDependency implements UnresolvedDependency - { - @Override - public UUID getId() - { - return _alternateExchangeId; - } - - @Override - public String getName() - { - return _alternateExchangeName; - } - - @Override - public String getType() - { - return "Exchange"; - } - - @Override - public void resolve(final Object dependency) - { - _alternateExchange = (ExchangeImpl) dependency; - _dependencies.remove(this); - } - } - } -} diff --git a/java/broker-core/src/main/java/org/apache/qpid/server/virtualhost/StandardVirtualHost.java b/java/broker-core/src/main/java/org/apache/qpid/server/virtualhost/StandardVirtualHost.java index e2454b0d18..645ee7ceef 100644 --- a/java/broker-core/src/main/java/org/apache/qpid/server/virtualhost/StandardVirtualHost.java +++ b/java/broker-core/src/main/java/org/apache/qpid/server/virtualhost/StandardVirtualHost.java @@ -21,163 +21,89 @@ package org.apache.qpid.server.virtualhost; import java.util.Collection; -import java.util.HashMap; import java.util.Map; -import org.apache.qpid.server.logging.messages.ConfigStoreMessages; -import org.apache.qpid.server.logging.messages.MessageStoreMessages; import org.apache.qpid.server.logging.subjects.MessageStoreLogSubject; -import org.apache.qpid.server.model.Broker; import org.apache.qpid.server.model.ManagedObject; -import org.apache.qpid.server.model.VirtualHost; +import org.apache.qpid.server.model.VirtualHostNode; import org.apache.qpid.server.plugin.MessageStoreFactory; -import org.apache.qpid.server.store.ConfiguredObjectRecordRecoveverAndUpgrader; -import org.apache.qpid.server.store.DurableConfigurationStore; -import org.apache.qpid.server.store.DurableConfigurationStoreCreator; import org.apache.qpid.server.store.MessageStore; -import org.apache.qpid.server.store.handler.ConfiguredObjectRecordHandler; @ManagedObject( category = false, type = "STANDARD") public class StandardVirtualHost extends AbstractVirtualHost { - public static final String TYPE = "STANDARD"; - private MessageStore _messageStore; - private DurableConfigurationStore _durableConfigurationStore; + public static final String TYPE = "STANDARD"; + MessageStore _messageStore; private MessageStoreLogSubject _messageStoreLogSubject; - private MessageStoreLogSubject _configurationStoreLogSubject; - - public StandardVirtualHost(final Map attributes, Broker broker) + public StandardVirtualHost(final Map attributes, VirtualHostNode virtualHostNode) { - super(attributes, broker); + super(attributes, virtualHostNode); } @Override public void validate() { super.validate(); - Map attributes = getActualAttributes(); - Map messageStoreSettings = getMessageStoreSettings(); - if (messageStoreSettings == null) - { - throw new IllegalArgumentException("Attribute '"+ org.apache.qpid.server.model.VirtualHost.MESSAGE_STORE_SETTINGS + "' is required."); - } - - Object storeType = messageStoreSettings.get(MessageStore.STORE_TYPE); - - // need store type and path - Collection knownTypes = MessageStoreFactory.FACTORY_LOADER.getSupportedTypes(); - if (storeType == null) - { - throw new IllegalArgumentException("Setting '"+ MessageStore.STORE_TYPE - +"' is required in attribute " + org.apache.qpid.server.model.VirtualHost.MESSAGE_STORE_SETTINGS + ". Known types are : " + knownTypes); - } - else if (!(storeType instanceof String)) - { - throw new IllegalArgumentException("Setting '"+ MessageStore.STORE_TYPE - +"' is required and must be of type String. " - +"Known types are : " + knownTypes); - } - MessageStoreFactory factory = MessageStoreFactory.FACTORY_LOADER.get((String)storeType); - if(factory == null) + VirtualHostNode virtualHostNode = getParent(VirtualHostNode.class); + if (!virtualHostNode.isMessageStoreProvider()) { - throw new IllegalArgumentException("Setting '"+ MessageStore.STORE_TYPE - +"' has value '" + storeType + "' which is not one of the valid values: " - + "Known types are : " + knownTypes); + Map attributes = getActualAttributes(); + Map messageStoreSettings = getMessageStoreSettings(); + if (messageStoreSettings == null) + { + throw new IllegalArgumentException("Attribute '"+ org.apache.qpid.server.model.VirtualHost.MESSAGE_STORE_SETTINGS + "' is required."); + } + + Object storeType = messageStoreSettings.get(MessageStore.STORE_TYPE); + + // need store type and path + Collection knownTypes = MessageStoreFactory.FACTORY_LOADER.getSupportedTypes(); + + if (storeType == null) + { + throw new IllegalArgumentException("Setting '"+ MessageStore.STORE_TYPE + +"' is required in attribute " + org.apache.qpid.server.model.VirtualHost.MESSAGE_STORE_SETTINGS + ". Known types are : " + knownTypes); + } + else if (!(storeType instanceof String)) + { + throw new IllegalArgumentException("Setting '"+ MessageStore.STORE_TYPE + +"' is required and must be of type String. " + +"Known types are : " + knownTypes); + } + + MessageStoreFactory factory = MessageStoreFactory.FACTORY_LOADER.get((String)storeType); + if(factory == null) + { + throw new IllegalArgumentException("Setting '"+ MessageStore.STORE_TYPE + +"' has value '" + storeType + "' which is not one of the valid values: " + + "Known types are : " + knownTypes); + } + + factory.validateAttributes(attributes); } - - factory.validateAttributes(attributes); - - - - } - - private DurableConfigurationStore initialiseConfigurationStore(String storeType) - { - DurableConfigurationStore configurationStore; - - if(storeType != null) - { - configurationStore = new DurableConfigurationStoreCreator().createMessageStore(storeType); - } - else if(getMessageStore() instanceof DurableConfigurationStore) - { - configurationStore = (DurableConfigurationStore) getMessageStore(); - } - else - { - throw new ClassCastException(getMessageStore().getClass().getSimpleName() + - " is not an instance of DurableConfigurationStore"); - } - return configurationStore; } @Override - protected void initialiseStorage(VirtualHost virtualHost) + protected void initialiseStorage() { - Map messageStoreSettings = virtualHost.getMessageStoreSettings(); - String storeType = (String) messageStoreSettings.get(MessageStore.STORE_TYPE); - _messageStore = MessageStoreFactory.FACTORY_LOADER.get(storeType).createMessageStore(); - _messageStoreLogSubject = new MessageStoreLogSubject(getName(), _messageStore.getClass().getSimpleName()); - getEventLogger().message(_messageStoreLogSubject, MessageStoreMessages.CREATED()); - - Map configurationStoreSettings = virtualHost.getConfigurationStoreSettings(); - String configurationStoreType = configurationStoreSettings == null - ? null - : (String) configurationStoreSettings.get(DurableConfigurationStore.STORE_TYPE); - _durableConfigurationStore = initialiseConfigurationStore(configurationStoreType); - boolean combinedStores = _durableConfigurationStore == _messageStore; - if (combinedStores) + VirtualHostNode virtualHostNode = getParent(VirtualHostNode.class); + if (virtualHostNode.isMessageStoreProvider()) { - configurationStoreSettings = new HashMap(messageStoreSettings); - configurationStoreSettings.put(DurableConfigurationStore.IS_MESSAGE_STORE_TOO, true); - } - - if (!combinedStores) - { - _configurationStoreLogSubject = - new MessageStoreLogSubject(getName(), _durableConfigurationStore.getClass().getSimpleName()); - getEventLogger().message(_configurationStoreLogSubject, ConfigStoreMessages.CREATED()); - } - - _durableConfigurationStore.openConfigurationStore(virtualHost, configurationStoreSettings); - - _messageStore.openMessageStore(virtualHost, virtualHost.getMessageStoreSettings()); - - getEventLogger().message(_messageStoreLogSubject, - MessageStoreMessages.STORE_LOCATION(_messageStore.getStoreLocation())); - - if (_configurationStoreLogSubject != null) - { - getEventLogger().message(_configurationStoreLogSubject, - ConfigStoreMessages.STORE_LOCATION(configurationStoreSettings.toString())); - getEventLogger().message(_configurationStoreLogSubject, ConfigStoreMessages.RECOVERY_START()); - } - - - if (isStoreEmpty()) - { - createDefaultExchanges(); + _messageStore = (MessageStore)virtualHostNode.getConfigurationStore(); } else { - ConfiguredObjectRecordHandler upgraderRecoverer = - new ConfiguredObjectRecordRecoveverAndUpgrader(this, getDurableConfigurationRecoverers()); - _durableConfigurationStore.visitConfiguredObjectRecords(upgraderRecoverer); + Map messageStoreSettings = getMessageStoreSettings(); + String storeType = (String) messageStoreSettings.get(MessageStore.STORE_TYPE); + _messageStore = MessageStoreFactory.FACTORY_LOADER.get(storeType).createMessageStore(); } - if (_configurationStoreLogSubject != null) - { - getEventLogger().message(_configurationStoreLogSubject, ConfigStoreMessages.RECOVERY_COMPLETE()); - } - - new MessageStoreRecoverer(this, getMessageStoreLogSubject()).recover(); - - attainActivation(); + _messageStoreLogSubject = new MessageStoreLogSubject(getName(), _messageStore.getClass().getSimpleName()); } @Override @@ -186,22 +112,10 @@ public class StandardVirtualHost extends AbstractVirtualHost> extends AbstractConfiguredObject + implements VirtualHostNode +{ + private static final Logger LOGGER = Logger.getLogger(AbstractStandardVirtualHostNode.class); + + private final Broker _broker; + private final AtomicReference _state = new AtomicReference(State.INITIALISING); + private final EventLogger _eventLogger; + + @ManagedAttributeField + private boolean _messageStoreProvider; + + private MessageStoreLogSubject _configurationStoreLogSubject; + private DurableConfigurationStore _durableConfigurationStore; + + @SuppressWarnings("rawtypes") + public AbstractStandardVirtualHostNode(Broker parent, Map attributes, TaskExecutor taskExecutor) + { + super(Collections.,ConfiguredObject>singletonMap(Broker.class, parent), + attributes, taskExecutor); + _broker = parent; + SystemContext systemContext = _broker.getParent(SystemContext.class); + _eventLogger = systemContext.getEventLogger(); + } + + @Override + public void validate() + { + super.validate(); + DurableConfigurationStoreFactory durableConfigurationStoreFactory = getDurableConfigurationStoreFactory(); + Map storeSettings = new HashMap(getActualAttributes()); + storeSettings.put(DurableConfigurationStore.STORE_TYPE, durableConfigurationStoreFactory.getType()); + durableConfigurationStoreFactory.validateConfigurationStoreSettings(storeSettings); + } + + @Override + public void onOpen() + { + super.onOpen(); + DurableConfigurationStoreFactory durableConfigurationStoreFactory = getDurableConfigurationStoreFactory(); + _durableConfigurationStore = durableConfigurationStoreFactory.createDurableConfigurationStore(); + _configurationStoreLogSubject = new MessageStoreLogSubject(getName(), _durableConfigurationStore.getClass().getSimpleName()); + + } + + protected abstract DurableConfigurationStoreFactory getDurableConfigurationStoreFactory(); + + protected Map getDefaultMessageStoreSettings() + { + // TODO perhaps look for the MS with the default annotation and associated default. + Map settings = new HashMap(); + settings.put(MessageStore.STORE_TYPE, "DERBY"); + settings.put(MessageStore.STORE_PATH, "${qpid.work_dir}" + File.separator + "derbystore" + File.separator + getName()); + return settings; + } + + @SuppressWarnings({ "rawtypes", "unchecked" }) + @Override + protected C addChild(Class childClass, Map attributes, + ConfiguredObject... otherParents) + { + if(childClass == VirtualHost.class) + { + return (C) getObjectFactory().create(VirtualHost.class, attributes, this); + } + return super.addChild(childClass, attributes, otherParents); + } + + + + @SuppressWarnings({ "unchecked", "rawtypes" }) + @Override + public T getParent(Class clazz) + { + if (clazz == Broker.class) + { + return (T) _broker; + } + return super.getParent(clazz); + } + + + @Override + public State getState() + { + return _state.get(); + } + + @Override + public LifetimePolicy getLifetimePolicy() + { + return LifetimePolicy.PERMANENT; + } + + @Override + protected boolean setState(State currentState, State desiredState) + { + State state = _state.get(); + if (desiredState == State.DELETED) + { + if (state == State.INITIALISING || state == State.ACTIVE || state == State.STOPPED || state == State.ERRORED) + { + if( _state.compareAndSet(state, State.DELETED)) + { + delete(); + return true; + } + } + else + { + throw new IllegalStateException("Cannot delete virtual host node in " + state + " state"); + } + } + else if (desiredState == State.ACTIVE) + { + if ((state == State.INITIALISING || state == State.STOPPED) && _state.compareAndSet(state, State.ACTIVE)) + { + try + { + activate(); + } + catch(RuntimeException e) + { + _state.compareAndSet(State.ACTIVE, State.ERRORED); + if (_broker.isManagementMode()) + { + LOGGER.warn("Failed to make " + this + " active.", e); + } + else + { + throw e; + } + } + return true; + } + else + { + throw new IllegalStateException("Cannot activate virtual host node in " + state + " state"); + } + } + else if (desiredState == State.STOPPED) + { + if (_state.compareAndSet(state, State.STOPPED)) + { + stop(); + return true; + } + else + { + throw new IllegalStateException("Cannot stop virtual host node in " + state + " state"); + } + } + return false; + } + + + @Override + public boolean isMessageStoreProvider() + { + return _messageStoreProvider; + } + + @Override + public VirtualHost getVirtualHost() + { + Collection children = getChildren(VirtualHost.class); + if (children.size() == 0) + { + return null; + } + else if (children.size() == 1) + { + return children.iterator().next(); + } + else + { + throw new IllegalStateException(this + " has an unexpected number of virtualhost children, size " + children.size()); + } + } + + @Override + public DurableConfigurationStore getConfigurationStore() + { + return _durableConfigurationStore; + } + + private void activate() + { + if (LOGGER.isDebugEnabled()) + { + LOGGER.debug("Activating virtualhost node " + this); + } + + Map attributes = buildAttributesForStore(); + + _durableConfigurationStore.openConfigurationStore(this, attributes); + + _eventLogger.message(_configurationStoreLogSubject, ConfigStoreMessages.CREATED()); + + if (this instanceof FileBasedVirtualHostNode) + { + @SuppressWarnings("rawtypes") + FileBasedVirtualHostNode fileBasedVirtualHostNode = (FileBasedVirtualHostNode) this; + _eventLogger.message(_configurationStoreLogSubject, ConfigStoreMessages.STORE_LOCATION(fileBasedVirtualHostNode.getStorePath())); + } + + _eventLogger.message(_configurationStoreLogSubject, ConfigStoreMessages.RECOVERY_START()); + + VirtualHostStoreUpgraderAndRecoverer upgrader = new VirtualHostStoreUpgraderAndRecoverer(this, getObjectFactory()); + upgrader.perform(_durableConfigurationStore); + + _eventLogger.message(_configurationStoreLogSubject, ConfigStoreMessages.RECOVERY_COMPLETE()); + + VirtualHost host = getVirtualHost(); + + if (host == null) + { + if (LOGGER.isDebugEnabled()) + { + LOGGER.debug("Creating new virtualhost with name : " + getName()); + } + Map hostAttributes = new HashMap(); + hostAttributes.put(VirtualHost.MODEL_VERSION, BrokerModel.MODEL_VERSION); + hostAttributes.put(VirtualHost.NAME, getName()); + hostAttributes.put(VirtualHost.TYPE, StandardVirtualHost.TYPE); + if (!isMessageStoreProvider()) + { + hostAttributes.put(VirtualHost.MESSAGE_STORE_SETTINGS, getDefaultMessageStoreSettings()); + } + host = createChild(VirtualHost.class, hostAttributes); + } + else + { + final VirtualHost recoveredHost = host; + Subject.doAs(SecurityManager.getSubjectWithAddedSystemRights(), new PrivilegedAction() + { + @Override + public Object run() + { + recoveredHost.open(); + return null; + } + }); + } + + host.setDesiredState(host.getState(), State.ACTIVE); + } + + private Map buildAttributesForStore() + { + final Map attributes = new HashMap(); + Subject.doAs(SecurityManager.getSubjectWithAddedSystemRights(), new PrivilegedAction() + { + @Override + public Object run() + { + for (String attributeName : getAttributeNames()) + { + Object value = getAttribute(attributeName); + attributes.put(attributeName, value); + } + return null; + } + }); + + return attributes; + } + + private void delete() + { + VirtualHost virtualHost = getVirtualHost(); + if (virtualHost != null) + { + virtualHost.setDesiredState(virtualHost.getState(), State.DELETED); + } + //TODO: this needs to be called from parent + deleted(); + + // TODO Split onDelete into deleteMessageStore/deleteConfigStore + if (_durableConfigurationStore instanceof MessageStore) + { + ((MessageStore)_durableConfigurationStore).onDelete(); + } + + } + + private void stop() + { + VirtualHost virtualHost = getVirtualHost(); + if (virtualHost != null) + { + virtualHost.setDesiredState(virtualHost.getState(), State.STOPPED); + } + _durableConfigurationStore.closeConfigurationStore(); + + _eventLogger.message(_configurationStoreLogSubject, ConfigStoreMessages.CLOSE()); + } + + +} diff --git a/java/broker-core/src/main/java/org/apache/qpid/server/virtualhostnode/FileBasedVirtualHostNode.java b/java/broker-core/src/main/java/org/apache/qpid/server/virtualhostnode/FileBasedVirtualHostNode.java new file mode 100644 index 0000000000..52c8825e76 --- /dev/null +++ b/java/broker-core/src/main/java/org/apache/qpid/server/virtualhostnode/FileBasedVirtualHostNode.java @@ -0,0 +1,33 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT 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.virtualhostnode; + +import org.apache.qpid.server.model.ManagedAttribute; +import org.apache.qpid.server.model.VirtualHostNode; + +public interface FileBasedVirtualHostNode> extends VirtualHostNode +{ + public static final String STORE_PATH = "storePath"; + + @ManagedAttribute(automate = true, mandatory = true) + public String getStorePath(); + +} diff --git a/java/broker-core/src/main/java/org/apache/qpid/server/virtualhostnode/JsonVirtualHostNodeFactory.java b/java/broker-core/src/main/java/org/apache/qpid/server/virtualhostnode/JsonVirtualHostNodeFactory.java new file mode 100644 index 0000000000..5a753444cc --- /dev/null +++ b/java/broker-core/src/main/java/org/apache/qpid/server/virtualhostnode/JsonVirtualHostNodeFactory.java @@ -0,0 +1,43 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.server.virtualhostnode; + +import java.util.Map; + +import org.apache.qpid.server.model.AbstractConfiguredObjectTypeFactory; +import org.apache.qpid.server.model.Broker; +import org.apache.qpid.server.model.ConfiguredObject; + +public class JsonVirtualHostNodeFactory extends AbstractConfiguredObjectTypeFactory +{ + public JsonVirtualHostNodeFactory() + { + super(JsonVirtualHostNodeImpl.class); + } + + @Override + public JsonVirtualHostNodeImpl createInstance(Map attributes, ConfiguredObject... parents) + { + Broker parent = getParent(Broker.class, parents); + return new JsonVirtualHostNodeImpl(parent, attributes, parent.getTaskExecutor()); + } + +} diff --git a/java/broker-core/src/main/java/org/apache/qpid/server/virtualhostnode/JsonVirtualHostNodeImpl.java b/java/broker-core/src/main/java/org/apache/qpid/server/virtualhostnode/JsonVirtualHostNodeImpl.java new file mode 100644 index 0000000000..8f697ada76 --- /dev/null +++ b/java/broker-core/src/main/java/org/apache/qpid/server/virtualhostnode/JsonVirtualHostNodeImpl.java @@ -0,0 +1,61 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.server.virtualhostnode; + +import java.util.Map; + +import org.apache.qpid.server.configuration.updater.TaskExecutor; +import org.apache.qpid.server.model.Broker; +import org.apache.qpid.server.model.ManagedAttributeField; +import org.apache.qpid.server.model.ManagedObject; +import org.apache.qpid.server.plugin.DurableConfigurationStoreFactory; +import org.apache.qpid.server.store.JsonFileConfigStoreFactory; + +@ManagedObject(category=false, type="JSON") +public class JsonVirtualHostNodeImpl extends AbstractStandardVirtualHostNode implements FileBasedVirtualHostNode +{ + @ManagedAttributeField + private String _storePath; + + public JsonVirtualHostNodeImpl(Broker parent, Map attributes, TaskExecutor taskExecutor) + { + super(parent, attributes, taskExecutor); + } + + @Override + protected DurableConfigurationStoreFactory getDurableConfigurationStoreFactory() + { + return new JsonFileConfigStoreFactory(); + } + + @Override + public String getStorePath() + { + return _storePath; + } + + @Override + public String toString() + { + return getClass().getSimpleName() + " [id=" + getId() + ", name=" + getName() + ", storePath=" + getStorePath() + "]"; + } + +} diff --git a/java/broker-core/src/main/resources/META-INF/services/org.apache.qpid.server.plugin.ConfiguredObjectTypeFactory b/java/broker-core/src/main/resources/META-INF/services/org.apache.qpid.server.plugin.ConfiguredObjectTypeFactory index 3ec2b900e3..6d8dd61ab1 100644 --- a/java/broker-core/src/main/resources/META-INF/services/org.apache.qpid.server.plugin.ConfiguredObjectTypeFactory +++ b/java/broker-core/src/main/resources/META-INF/services/org.apache.qpid.server.plugin.ConfiguredObjectTypeFactory @@ -45,6 +45,5 @@ org.apache.qpid.server.exchange.FanoutExchangeFactory org.apache.qpid.server.exchange.HeadersExchangeFactory org.apache.qpid.server.exchange.TopicExchangeFactory org.apache.qpid.server.binding.BindingFactory - - +org.apache.qpid.server.virtualhostnode.JsonVirtualHostNodeFactory diff --git a/java/broker-core/src/main/resources/initial-config.json b/java/broker-core/src/main/resources/initial-config.json index 600822a033..45b02bd550 100644 --- a/java/broker-core/src/main/resources/initial-config.json +++ b/java/broker-core/src/main/resources/initial-config.json @@ -21,7 +21,7 @@ { "name": "${broker.name}", "storeVersion": 1, - "modelVersion": "1.4", + "modelVersion": "2.0", "defaultVirtualHost" : "default", "authenticationproviders" : [ { "name" : "passwordFile", @@ -52,13 +52,10 @@ "authenticationProvider" : "passwordFile", "protocols" : [ "JMX_RMI" ] }], - "virtualhosts" : [ { + "virtualhostnodes" : [ { "name" : "default", - "type" : "STANDARD", - "messageStoreSettings" : { - "storeType" : "DERBY", - "storePath" : "${qpid.work_dir}/derbystore/default" - } + "type" : "JSON", + "storePath" : "${qpid.work_dir}/json/default" } ], "plugins" : [ { "type" : "MANAGEMENT-HTTP", diff --git a/java/broker-core/src/test/java/org/apache/qpid/server/configuration/startup/BrokerRecovererTest.java b/java/broker-core/src/test/java/org/apache/qpid/server/configuration/startup/BrokerRecovererTest.java index 9eca7458f2..28d7830290 100644 --- a/java/broker-core/src/test/java/org/apache/qpid/server/configuration/startup/BrokerRecovererTest.java +++ b/java/broker-core/src/test/java/org/apache/qpid/server/configuration/startup/BrokerRecovererTest.java @@ -23,8 +23,6 @@ package org.apache.qpid.server.configuration.startup; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; -import java.util.Arrays; -import java.util.Collection; import java.util.Collections; import java.util.HashMap; import java.util.Map; @@ -49,11 +47,8 @@ import org.apache.qpid.server.model.GroupProvider; import org.apache.qpid.server.model.Port; import org.apache.qpid.server.model.SystemContext; import org.apache.qpid.server.model.SystemContextImpl; -import org.apache.qpid.server.model.VirtualHost; import org.apache.qpid.server.store.ConfiguredObjectRecord; import org.apache.qpid.server.store.ConfiguredObjectRecordImpl; -import org.apache.qpid.server.store.MessageStore; -import org.apache.qpid.server.store.TestMemoryMessageStore; import org.apache.qpid.server.store.UnresolvedConfiguredObject; public class BrokerRecovererTest extends TestCase @@ -61,8 +56,6 @@ public class BrokerRecovererTest extends TestCase private ConfiguredObjectRecord _brokerEntry = mock(ConfiguredObjectRecord.class); private UUID _brokerId = UUID.randomUUID(); - private Map> _brokerEntryChildren = new HashMap>(); - private ConfiguredObjectRecord _authenticationProviderEntry1; private AuthenticationProvider _authenticationProvider1; private UUID _authenticationProvider1Id = UUID.randomUUID(); private SystemContext _systemContext; @@ -93,8 +86,6 @@ public class BrokerRecovererTest extends TestCase _authenticationProvider1 = mock(AuthenticationProvider.class); when(_authenticationProvider1.getName()).thenReturn("authenticationProvider1"); when(_authenticationProvider1.getId()).thenReturn(_authenticationProvider1Id); - _authenticationProviderEntry1 = mock(ConfiguredObjectRecord.class); - _brokerEntryChildren.put(AuthenticationProvider.class.getSimpleName(), Arrays.asList(_authenticationProviderEntry1)); } @Override @@ -140,37 +131,6 @@ public class BrokerRecovererTest extends TestCase } } - public void testCreateBrokerWithVirtualHost() - { - final ConfiguredObjectRecord virtualHostEntry = mock(ConfiguredObjectRecord.class); - - String typeName = VirtualHost.class.getSimpleName(); - when(virtualHostEntry.getType()).thenReturn(typeName); - _brokerEntryChildren.put(typeName, Arrays.asList(virtualHostEntry)); - - UUID vhostId = UUID.randomUUID(); - _systemContext.resolveObjects(_brokerEntry, createVhostRecord(vhostId)); - Broker broker = _systemContext.getBroker(); - - assertNotNull(broker); - broker.open(); - assertEquals(_brokerId, broker.getId()); - assertEquals(1, broker.getVirtualHosts().size()); - assertEquals(vhostId, broker.getVirtualHosts().iterator().next().getId()); - - } - - public ConfiguredObjectRecord createVhostRecord(UUID id) - { - final Map vhostAttributes = new HashMap(); - vhostAttributes.put(VirtualHost.NAME, "vhost"); - vhostAttributes.put(VirtualHost.TYPE, "STANDARD"); - vhostAttributes.put(VirtualHost.MESSAGE_STORE_SETTINGS, Collections.singletonMap(MessageStore.STORE_TYPE, - TestMemoryMessageStore.TYPE)); - return new ConfiguredObjectRecordImpl(id, VirtualHost.class.getSimpleName(), vhostAttributes, Collections - .singletonMap(Broker.class.getSimpleName(), _brokerEntry)); - } - public ConfiguredObjectRecord createAuthProviderRecord(UUID id, String name) { final Map authProviderAttrs = new HashMap(); diff --git a/java/broker-core/src/test/java/org/apache/qpid/server/configuration/startup/VirtualHostCreationTest.java b/java/broker-core/src/test/java/org/apache/qpid/server/configuration/startup/VirtualHostCreationTest.java index 9a56d30ac6..78595afb36 100644 --- a/java/broker-core/src/test/java/org/apache/qpid/server/configuration/startup/VirtualHostCreationTest.java +++ b/java/broker-core/src/test/java/org/apache/qpid/server/configuration/startup/VirtualHostCreationTest.java @@ -31,7 +31,6 @@ import java.util.UUID; import junit.framework.TestCase; -import org.apache.qpid.server.configuration.ConfigurationEntry; import org.apache.qpid.server.configuration.IllegalConfigurationException; import org.apache.qpid.server.logging.EventLogger; import org.apache.qpid.server.model.Broker; @@ -41,41 +40,58 @@ import org.apache.qpid.server.model.ConfiguredObjectFactory; import org.apache.qpid.server.model.ConfiguredObjectFactoryImpl; import org.apache.qpid.server.model.SystemContext; import org.apache.qpid.server.model.VirtualHost; +import org.apache.qpid.server.model.VirtualHostNode; import org.apache.qpid.server.security.SecurityManager; +import org.apache.qpid.server.store.DurableConfigurationStore; import org.apache.qpid.server.store.MessageStore; import org.apache.qpid.server.store.TestMemoryMessageStore; +import org.apache.qpid.server.virtualhost.AbstractVirtualHost; import org.apache.qpid.server.virtualhost.StandardVirtualHost; public class VirtualHostCreationTest extends TestCase { + private VirtualHostNode _virtualHostNode; - public void testCreateVirtualHostFromStoreConfigAttributes() + @Override + public void setUp() throws Exception { + super.setUp(); + + EventLogger eventLogger = mock(EventLogger.class); SecurityManager securityManager = mock(SecurityManager.class); - ConfigurationEntry entry = mock(ConfigurationEntry.class); + SystemContext systemContext = mock(SystemContext.class); ConfiguredObjectFactory objectFactory = new ConfiguredObjectFactoryImpl(BrokerModel.getInstance()); when(systemContext.getObjectFactory()).thenReturn(objectFactory); when(systemContext.getModel()).thenReturn(objectFactory.getModel()); + when(systemContext.getEventLogger()).thenReturn(eventLogger); + + Broker broker = mock(Broker.class); + when(broker.getObjectFactory()).thenReturn(objectFactory); + when(broker.getModel()).thenReturn(objectFactory.getModel()); + when(broker.getSecurityManager()).thenReturn(securityManager); + when(broker.getCategoryClass()).thenReturn(Broker.class); + when(broker.getParent(eq(SystemContext.class))).thenReturn(systemContext); + + _virtualHostNode = mock(VirtualHostNode.class); + when(_virtualHostNode.getParent(Broker.class)).thenReturn(broker); + when(_virtualHostNode.getObjectFactory()).thenReturn(objectFactory); + when(_virtualHostNode.getConfigurationStore()).thenReturn(mock(DurableConfigurationStore.class)); + when(_virtualHostNode.getModel()).thenReturn(objectFactory.getModel()); + } - Broker parent = mock(Broker.class); - when(parent.getObjectFactory()).thenReturn(objectFactory); - when(parent.getModel()).thenReturn(objectFactory.getModel()); - when(parent.getSecurityManager()).thenReturn(securityManager); - when(parent.getCategoryClass()).thenReturn(Broker.class); - when(systemContext.getEventLogger()).thenReturn(mock(EventLogger.class)); - when(parent.getParent(eq(SystemContext.class))).thenReturn(systemContext); - + public void testCreateVirtualHostFromStoreConfigAttributes() + { Map attributes = new HashMap(); attributes.put(VirtualHost.NAME, getName()); attributes.put(VirtualHost.TYPE, StandardVirtualHost.TYPE); attributes.put(VirtualHost.ID, UUID.randomUUID()); attributes.put(VirtualHost.MESSAGE_STORE_SETTINGS, Collections.singletonMap(MessageStore.STORE_TYPE, TestMemoryMessageStore.TYPE)); - when(entry.getAttributes()).thenReturn(attributes); - VirtualHost host = new StandardVirtualHost(attributes,parent); + VirtualHost host = new StandardVirtualHost(attributes, _virtualHostNode); host.open(); + assertNotNull("Null is returned", host); assertEquals("Unexpected name", getName(), host.getName()); } @@ -94,19 +110,6 @@ public class VirtualHostCreationTest extends TestCase public void checkMandatoryAttributesAreValidated(String[] mandatoryAttributes, Map attributes) { - SecurityManager securityManager = mock(SecurityManager.class); - SystemContext systemContext = mock(SystemContext.class); - ConfiguredObjectFactory objectFactory = new ConfiguredObjectFactoryImpl(BrokerModel.getInstance()); - when(systemContext.getObjectFactory()).thenReturn(objectFactory); - when(systemContext.getModel()).thenReturn(objectFactory.getModel()); - - Broker parent = mock(Broker.class); - when(parent.getSecurityManager()).thenReturn(securityManager); - when(parent.getParent(eq(SystemContext.class))).thenReturn(systemContext); - when(systemContext.getEventLogger()).thenReturn(mock(EventLogger.class)); - when(parent.getObjectFactory()).thenReturn(objectFactory); - when(parent.getModel()).thenReturn(objectFactory.getModel()); - for (String name : mandatoryAttributes) { Map copy = new HashMap(attributes); @@ -114,7 +117,7 @@ public class VirtualHostCreationTest extends TestCase copy.put(ConfiguredObject.ID, UUID.randomUUID()); try { - VirtualHost host = new StandardVirtualHost(copy,parent); + AbstractVirtualHost host = new StandardVirtualHost(copy,_virtualHostNode); host.open(); fail("Cannot create a virtual host without a mandatory attribute " + name); } @@ -126,7 +129,6 @@ public class VirtualHostCreationTest extends TestCase { // pass } - } } } diff --git a/java/broker-core/src/test/java/org/apache/qpid/server/configuration/store/ConfigurationEntryStoreTestCase.java b/java/broker-core/src/test/java/org/apache/qpid/server/configuration/store/ConfigurationEntryStoreTestCase.java index bc44d00879..691a4f9abf 100644 --- a/java/broker-core/src/test/java/org/apache/qpid/server/configuration/store/ConfigurationEntryStoreTestCase.java +++ b/java/broker-core/src/test/java/org/apache/qpid/server/configuration/store/ConfigurationEntryStoreTestCase.java @@ -47,6 +47,7 @@ import org.apache.qpid.server.model.SystemContextImpl; import org.apache.qpid.server.model.Transport; import org.apache.qpid.server.model.TrustStore; import org.apache.qpid.server.model.VirtualHost; +import org.apache.qpid.server.model.VirtualHostNode; import org.apache.qpid.server.model.adapter.FileSystemPreferencesProvider; import org.apache.qpid.server.security.FileKeyStore; import org.apache.qpid.server.security.FileTrustStore; @@ -60,11 +61,11 @@ public abstract class ConfigurationEntryStoreTestCase extends QpidTestCase private MemoryConfigurationEntryStore _store; private UUID _brokerId; - private UUID _virtualHostId; + private UUID _virtualHostNodeId; protected UUID _authenticationProviderId; private Map _brokerAttributes; - private Map _virtualHostAttributes; + private Map _virtualHostNodeAttributes; private Map _authenticationProviderAttributes; private TaskExecutor _taskExecutor; @@ -90,10 +91,10 @@ public abstract class ConfigurationEntryStoreTestCase extends QpidTestCase _brokerAttributes.put(Broker.STATISTICS_REPORTING_PERIOD, 4000); _brokerAttributes.put(Broker.STATISTICS_REPORTING_RESET_ENABLED, true); - _virtualHostId = UUID.randomUUID(); - _virtualHostAttributes = new HashMap(); - _virtualHostAttributes.put(VirtualHost.NAME, "test"); - _virtualHostAttributes.put(VirtualHost.TYPE, "STANDARD"); + _virtualHostNodeId = UUID.randomUUID(); + _virtualHostNodeAttributes = new HashMap(); + _virtualHostNodeAttributes.put(VirtualHost.NAME, "test"); + _virtualHostNodeAttributes.put(VirtualHost.TYPE, "JSON"); _authenticationProviderId = UUID.randomUUID(); _authenticationProviderAttributes = new HashMap(); @@ -101,7 +102,7 @@ public abstract class ConfigurationEntryStoreTestCase extends QpidTestCase _authenticationProviderAttributes.put(AuthenticationProvider.TYPE, AnonymousAuthenticationManager.class.getSimpleName()); _store = createStore(_brokerId, _brokerAttributes); - addConfiguration(_virtualHostId, VirtualHost.class.getSimpleName(), _virtualHostAttributes); + addConfiguration(_virtualHostNodeId, VirtualHostNode.class.getSimpleName(), _virtualHostNodeAttributes); addConfiguration(_authenticationProviderId, AuthenticationProvider.class.getSimpleName(), _authenticationProviderAttributes); } @@ -282,18 +283,18 @@ public abstract class ConfigurationEntryStoreTestCase extends QpidTestCase public void testSaveExistingVirtualHost() { - ConfigurationEntry hostEntry = _store.getEntry(_virtualHostId); + ConfigurationEntry hostEntry = _store.getEntry(_virtualHostNodeId); assertNotNull("Host configuration is not found", hostEntry); Map virtualHostAttributes = new HashMap(); virtualHostAttributes.put(VirtualHost.NAME, "test"); virtualHostAttributes.put(VirtualHost.TYPE, "STANDARD"); - ConfigurationEntry updatedEntry = new ConfigurationEntryImpl(_virtualHostId, VirtualHost.class.getSimpleName(), virtualHostAttributes, + ConfigurationEntry updatedEntry = new ConfigurationEntryImpl(_virtualHostNodeId, VirtualHost.class.getSimpleName(), virtualHostAttributes, hostEntry.getChildrenIds(), _store); _store.save(updatedEntry); - ConfigurationEntry newHostEntry = _store.getEntry(_virtualHostId); + ConfigurationEntry newHostEntry = _store.getEntry(_virtualHostNodeId); assertEquals("Unexpected virtual host configuration", updatedEntry, newHostEntry); assertEquals("Unexpected type", VirtualHost.class.getSimpleName(), newHostEntry.getType()); assertEquals("Unexpected virtual host attributes", updatedEntry.getAttributes(), newHostEntry.getAttributes()); diff --git a/java/broker-core/src/test/java/org/apache/qpid/server/configuration/store/StoreConfigurationChangeListenerTest.java b/java/broker-core/src/test/java/org/apache/qpid/server/configuration/store/StoreConfigurationChangeListenerTest.java index f8277f0113..c832f47af1 100644 --- a/java/broker-core/src/test/java/org/apache/qpid/server/configuration/store/StoreConfigurationChangeListenerTest.java +++ b/java/broker-core/src/test/java/org/apache/qpid/server/configuration/store/StoreConfigurationChangeListenerTest.java @@ -32,9 +32,9 @@ import java.util.UUID; import org.apache.qpid.server.configuration.ConfigurationEntryStore; import org.apache.qpid.server.model.Broker; import org.apache.qpid.server.model.ConfiguredObject; -import org.apache.qpid.server.model.Queue; import org.apache.qpid.server.model.State; import org.apache.qpid.server.model.VirtualHost; +import org.apache.qpid.server.model.VirtualHostNode; import org.apache.qpid.server.store.ConfiguredObjectRecord; import org.apache.qpid.test.utils.QpidTestCase; @@ -82,13 +82,13 @@ public class StoreConfigurationChangeListenerTest extends QpidTestCase verify(_store).update(eq(false),any(ConfiguredObjectRecord.class)); } - public void testChildAddedForVirtualHost() + public void testChildAddedForVirtualHostNode() { notifyBrokerStarted(); - VirtualHost object = mock(VirtualHost.class); - Queue queue = mock(Queue.class); - _listener.childAdded(object, queue); + VirtualHostNode object = mock(VirtualHostNode.class); + VirtualHost virtualHost = mock(VirtualHost.class); + _listener.childAdded(object, virtualHost); verifyNoMoreInteractions(_store); } diff --git a/java/broker-core/src/test/java/org/apache/qpid/server/logging/actors/BaseActorTestCase.java b/java/broker-core/src/test/java/org/apache/qpid/server/logging/actors/BaseActorTestCase.java index 3fa6c475cf..896127cc08 100644 --- a/java/broker-core/src/test/java/org/apache/qpid/server/logging/actors/BaseActorTestCase.java +++ b/java/broker-core/src/test/java/org/apache/qpid/server/logging/actors/BaseActorTestCase.java @@ -23,15 +23,13 @@ package org.apache.qpid.server.logging.actors; import org.apache.qpid.server.logging.EventLogger; import org.apache.qpid.server.logging.LogMessage; import org.apache.qpid.server.logging.LogSubject; -import org.apache.qpid.server.logging.MessageLogger; import org.apache.qpid.server.logging.UnitTestMessageLogger; import org.apache.qpid.test.utils.QpidTestCase; -public class BaseActorTestCase extends QpidTestCase +public abstract class BaseActorTestCase extends QpidTestCase { private boolean _statusUpdatesEnabled = true; private UnitTestMessageLogger _rawLogger; - private MessageLogger _rootLogger; private EventLogger _eventLogger; @Override @@ -40,7 +38,6 @@ public class BaseActorTestCase extends QpidTestCase super.setUp(); _rawLogger = new UnitTestMessageLogger(_statusUpdatesEnabled); _eventLogger = new EventLogger(_rawLogger); - _rootLogger = _rawLogger; } @Override @@ -57,10 +54,10 @@ public class BaseActorTestCase extends QpidTestCase { String message = "Test logging: " + getName(); sendTestLogMessage(message); - + return message; } - + public void sendTestLogMessage(final String message) { getEventLogger().message(new LogSubject() diff --git a/java/broker-core/src/test/java/org/apache/qpid/server/logging/actors/BaseConnectionActorTestCase.java b/java/broker-core/src/test/java/org/apache/qpid/server/logging/actors/BaseConnectionActorTestCase.java index 7fee259e29..65f9b4b148 100644 --- a/java/broker-core/src/test/java/org/apache/qpid/server/logging/actors/BaseConnectionActorTestCase.java +++ b/java/broker-core/src/test/java/org/apache/qpid/server/logging/actors/BaseConnectionActorTestCase.java @@ -25,7 +25,7 @@ import org.apache.qpid.server.protocol.AMQConnectionModel; import org.apache.qpid.server.util.BrokerTestHelper; import org.apache.qpid.server.virtualhost.VirtualHostImpl; -public class BaseConnectionActorTestCase extends BaseActorTestCase +public abstract class BaseConnectionActorTestCase extends BaseActorTestCase { private AMQConnectionModel _session; private VirtualHostImpl _virtualHost; diff --git a/java/broker-core/src/test/java/org/apache/qpid/server/model/VirtualHostTest.java b/java/broker-core/src/test/java/org/apache/qpid/server/model/VirtualHostTest.java index ec108a419d..26d54761cc 100644 --- a/java/broker-core/src/test/java/org/apache/qpid/server/model/VirtualHostTest.java +++ b/java/broker-core/src/test/java/org/apache/qpid/server/model/VirtualHostTest.java @@ -28,9 +28,8 @@ import java.util.HashMap; import java.util.Map; import java.util.UUID; -import org.apache.qpid.server.configuration.RecovererProvider; import org.apache.qpid.server.configuration.updater.TaskExecutor; -import org.apache.qpid.server.stats.StatisticsGatherer; +import org.apache.qpid.server.store.DurableConfigurationStore; import org.apache.qpid.server.store.MessageStore; import org.apache.qpid.server.store.TestMemoryMessageStore; import org.apache.qpid.server.util.BrokerTestHelper; @@ -39,11 +38,9 @@ import org.apache.qpid.test.utils.QpidTestCase; public class VirtualHostTest extends QpidTestCase { - private Broker _broker; - private StatisticsGatherer _statisticsGatherer; - private RecovererProvider _recovererProvider; private TaskExecutor _taskExecutor; + private VirtualHostNode _virtualHostNode; @Override protected void setUp() throws Exception @@ -55,8 +52,12 @@ public class VirtualHostTest extends QpidTestCase _taskExecutor.start(); when(_broker.getTaskExecutor()).thenReturn(_taskExecutor); - _recovererProvider = mock(RecovererProvider.class); - _statisticsGatherer = mock(StatisticsGatherer.class); + _virtualHostNode = mock(VirtualHostNode.class); + when(_virtualHostNode.getConfigurationStore()).thenReturn(mock(DurableConfigurationStore.class)); + when(_virtualHostNode.getParent(Broker.class)).thenReturn(_broker); + ConfiguredObjectFactory objectFactory = _broker.getObjectFactory(); + when(_virtualHostNode.getModel()).thenReturn(objectFactory.getModel()); + when(_virtualHostNode.getObjectFactory()).thenReturn(objectFactory); } @@ -69,26 +70,26 @@ public class VirtualHostTest extends QpidTestCase public void testInitialisingState() { - VirtualHost host = createHost(); + VirtualHost host = createHost(); assertEquals("Unexpected state", State.INITIALISING, host.getAttribute(VirtualHost.STATE)); } public void testActiveState() { - VirtualHost host = createHost(); + VirtualHost host = createHost(); + host.setDesiredState(State.INITIALISING, State.ACTIVE); - host.open(); assertEquals("Unexpected state", State.ACTIVE, host.getAttribute(VirtualHost.STATE)); } public void testStoppedState() { - VirtualHost host = createHost(); + VirtualHost host = createHost(); assertEquals("Unexpected state", State.INITIALISING, host.getAttribute(VirtualHost.STATE)); - host.open(); + host.setDesiredState(State.INITIALISING, State.ACTIVE); assertEquals("Unexpected state", State.ACTIVE, host.getAttribute(VirtualHost.STATE)); @@ -98,7 +99,7 @@ public class VirtualHostTest extends QpidTestCase public void testDeletedState() { - VirtualHost host = createHost(); + VirtualHost host = createHost(); assertEquals("Unexpected state", State.INITIALISING, host.getAttribute(VirtualHost.STATE)); @@ -108,8 +109,8 @@ public class VirtualHostTest extends QpidTestCase public void testCreateQueueChildHavingMessageGroupingAttributes() { - VirtualHost host = createHost(); - host.open(); + VirtualHost host = createHost(); + host.setDesiredState(State.INITIALISING, State.ACTIVE); String queueName = getTestName(); @@ -120,7 +121,7 @@ public class VirtualHostTest extends QpidTestCase host.createChild(Queue.class, arguments); - Queue queue = (Queue) ConfiguredObjectFinder.findConfiguredObjectByName(host.getQueues(), queueName); + Queue queue = (Queue) ConfiguredObjectFinder.findConfiguredObjectByName(host.getQueues(), queueName); Object messageGroupKey = queue.getAttribute(Queue.MESSAGE_GROUP_KEY); assertEquals("Unexpected message group key attribute", "mykey", messageGroupKey); @@ -129,22 +130,24 @@ public class VirtualHostTest extends QpidTestCase } - private VirtualHost createHost() + private VirtualHost createHost() { Map attributes = new HashMap(); attributes.put(VirtualHost.NAME, getName()); attributes.put(VirtualHost.TYPE, StandardVirtualHost.TYPE); attributes.put(VirtualHost.MESSAGE_STORE_SETTINGS, Collections.singletonMap(MessageStore.STORE_TYPE, TestMemoryMessageStore.TYPE)); - VirtualHost host = createHost(attributes); + VirtualHost host = createHost(attributes); return host; } - private VirtualHost createHost(Map attributes) + private VirtualHost createHost(Map attributes) { attributes = new HashMap(attributes); attributes.put(VirtualHost.ID, UUID.randomUUID()); - return new StandardVirtualHost(attributes, _broker); + StandardVirtualHost host= new StandardVirtualHost(attributes, _virtualHostNode); + host.create(); + return host; } } diff --git a/java/broker-core/src/test/java/org/apache/qpid/server/store/AbstractDurableConfigurationStoreTestCase.java b/java/broker-core/src/test/java/org/apache/qpid/server/store/AbstractDurableConfigurationStoreTestCase.java index 4e3e6d3e8a..f0838be380 100644 --- a/java/broker-core/src/test/java/org/apache/qpid/server/store/AbstractDurableConfigurationStoreTestCase.java +++ b/java/broker-core/src/test/java/org/apache/qpid/server/store/AbstractDurableConfigurationStoreTestCase.java @@ -28,6 +28,7 @@ import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import java.io.File; +import java.util.Collections; import java.util.HashMap; import java.util.LinkedHashMap; import java.util.Map; @@ -37,7 +38,6 @@ import org.mockito.ArgumentCaptor; import org.mockito.ArgumentMatcher; import org.mockito.invocation.InvocationOnMock; import org.mockito.stubbing.Answer; - import org.apache.qpid.common.AMQPFilterTypes; import org.apache.qpid.server.binding.BindingImpl; import org.apache.qpid.server.exchange.ExchangeImpl; @@ -51,6 +51,7 @@ import org.apache.qpid.server.model.ExclusivityPolicy; import org.apache.qpid.server.model.LifetimePolicy; import org.apache.qpid.server.model.Queue; import org.apache.qpid.server.model.UUIDGenerator; +import org.apache.qpid.server.model.VirtualHost; import org.apache.qpid.server.plugin.ExchangeType; import org.apache.qpid.server.queue.AMQQueue; import org.apache.qpid.server.security.SecurityManager; @@ -86,6 +87,10 @@ public abstract class AbstractDurableConfigurationStoreTestCase extends QpidTest protected Map _configurationStoreSettings; private ConfiguredObjectFactoryImpl _factory; + private ConfiguredObject _parent; + + private ConfiguredObjectRecord _rootRecord; + public void setUp() throws Exception { super.setUp(); @@ -108,7 +113,16 @@ public abstract class AbstractDurableConfigurationStoreTestCase extends QpidTest String argValue = "some selector expression"; _bindingArgs.put(argKey, argValue); - reopenStore(); + + _parent = mock(ConfiguredObject.class); + when(_parent.getName()).thenReturn("testName"); + when(_parent.getObjectFactory()).thenReturn(_factory); + when(_parent.getModel()).thenReturn(_factory.getModel()); + + _configStore = createConfigStore(); + _configStore.openConfigurationStore(_parent, _configurationStoreSettings); + _rootRecord = new ConfiguredObjectRecordImpl(UUID.randomUUID(), VirtualHost.class.getSimpleName(), Collections.emptyMap()); + _configStore.create(_rootRecord); } public void tearDown() throws Exception @@ -130,6 +144,8 @@ public abstract class AbstractDurableConfigurationStoreTestCase extends QpidTest _configStore.create(exchange.asObjectRecord()); reopenStore(); + _configStore.visitConfiguredObjectRecords(_handler); + verify(_handler).handle(matchesRecord(_exchangeId, EXCHANGE, map( org.apache.qpid.server.model.Exchange.NAME, getName(), org.apache.qpid.server.model.Exchange.TYPE, getName()+"Type", @@ -178,6 +194,7 @@ public abstract class AbstractDurableConfigurationStoreTestCase extends QpidTest _configStore.create(binding.asObjectRecord()); reopenStore(); + _configStore.visitConfiguredObjectRecords(_handler); Map map = new HashMap(); map.put(Binding.NAME, ROUTING_KEY); @@ -280,6 +297,8 @@ public abstract class AbstractDurableConfigurationStoreTestCase extends QpidTest _configStore.create(queue.asObjectRecord()); reopenStore(); + _configStore.visitConfiguredObjectRecords(_handler); + Map queueAttributes = new HashMap(); queueAttributes.put(Queue.NAME, getName()); queueAttributes.put(Queue.OWNER, getName()+"Owner"); @@ -297,7 +316,7 @@ public abstract class AbstractDurableConfigurationStoreTestCase extends QpidTest _configStore.create(queue.asObjectRecord()); reopenStore(); - + _configStore.visitConfiguredObjectRecords(_handler); Map queueAttributes = new HashMap(); @@ -317,6 +336,7 @@ public abstract class AbstractDurableConfigurationStoreTestCase extends QpidTest _configStore.create(queue.asObjectRecord()); reopenStore(); + _configStore.visitConfiguredObjectRecords(_handler); Map queueAttributes = new HashMap(); queueAttributes.put(Queue.NAME, getName()); @@ -351,6 +371,7 @@ public abstract class AbstractDurableConfigurationStoreTestCase extends QpidTest _configStore.update(false, queue.asObjectRecord()); reopenStore(); + _configStore.visitConfiguredObjectRecords(_handler); Map queueAttributes = new HashMap(); @@ -377,6 +398,7 @@ public abstract class AbstractDurableConfigurationStoreTestCase extends QpidTest _configStore.update(false, queue.asObjectRecord()); reopenStore(); + _configStore.visitConfiguredObjectRecords(_handler); Map queueAttributes = new HashMap(); @@ -461,6 +483,7 @@ public abstract class AbstractDurableConfigurationStoreTestCase extends QpidTest when(objectRecord.getId()).thenReturn(_queueId); when(objectRecord.getType()).thenReturn(Queue.class.getSimpleName()); when(objectRecord.getAttributes()).thenReturn(attributes); + when(objectRecord.getParents()).thenReturn(Collections.singletonMap(_rootRecord.getType(), _rootRecord)); when(queue.asObjectRecord()).thenReturn(objectRecord); return queue; } @@ -485,6 +508,7 @@ public abstract class AbstractDurableConfigurationStoreTestCase extends QpidTest when(exchangeRecord.getId()).thenReturn(_exchangeId); when(exchangeRecord.getType()).thenReturn(Exchange.class.getSimpleName()); when(exchangeRecord.getAttributes()).thenReturn(actualAttributes); + when(exchangeRecord.getParents()).thenReturn(Collections.singletonMap(_rootRecord.getType(), _rootRecord)); when(exchange.asObjectRecord()).thenReturn(exchangeRecord); when(exchange.getExchangeType()).thenReturn(mock(ExchangeType.class)); when(exchange.getEventLogger()).thenReturn(new EventLogger()); @@ -495,14 +519,7 @@ public abstract class AbstractDurableConfigurationStoreTestCase extends QpidTest { closeConfigStore(); _configStore = createConfigStore(); - - ConfiguredObject parent = mock(ConfiguredObject.class); - when(parent.getName()).thenReturn("testName"); - - when(parent.getObjectFactory()).thenReturn(_factory); - when(parent.getModel()).thenReturn(_factory.getModel()); - _configStore.openConfigurationStore(parent, _configurationStoreSettings); - _configStore.visitConfiguredObjectRecords(_handler); + _configStore.openConfigurationStore(_parent, _configurationStoreSettings); } protected abstract DurableConfigurationStore createConfigStore() throws Exception; diff --git a/java/broker-core/src/test/java/org/apache/qpid/server/store/JsonFileConfigStoreTest.java b/java/broker-core/src/test/java/org/apache/qpid/server/store/JsonFileConfigStoreTest.java index 27c1b7db13..67161370de 100644 --- a/java/broker-core/src/test/java/org/apache/qpid/server/store/JsonFileConfigStoreTest.java +++ b/java/broker-core/src/test/java/org/apache/qpid/server/store/JsonFileConfigStoreTest.java @@ -24,7 +24,6 @@ import static org.mockito.Matchers.any; import static org.mockito.Matchers.argThat; import static org.mockito.Mockito.inOrder; import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.never; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; @@ -35,9 +34,6 @@ import java.util.HashMap; import java.util.Map; import java.util.UUID; -import org.mockito.ArgumentMatcher; -import org.mockito.InOrder; - import org.apache.qpid.server.model.BrokerModel; import org.apache.qpid.server.model.ConfiguredObject; import org.apache.qpid.server.model.ConfiguredObjectFactory; @@ -48,29 +44,34 @@ import org.apache.qpid.server.util.ServerScopedRuntimeException; import org.apache.qpid.test.utils.QpidTestCase; import org.apache.qpid.test.utils.TestFileUtils; import org.apache.qpid.util.FileUtils; +import org.mockito.ArgumentMatcher; +import org.mockito.InOrder; public class JsonFileConfigStoreTest extends QpidTestCase { private JsonFileConfigStore _store; private HashMap _configurationStoreSettings; - private ConfiguredObject _virtualHost; + private ConfiguredObject _parent; private File _storeLocation; private ConfiguredObjectRecordHandler _handler; private static final UUID ANY_UUID = UUID.randomUUID(); private static final Map ANY_MAP = new HashMap(); + private static final String VIRTUAL_HOST_TYPE = "VirtualHost"; + private ConfiguredObjectRecord _rootRecord; @Override public void setUp() throws Exception { super.setUp(); - _virtualHost = mock(ConfiguredObject.class); - when(_virtualHost.getName()).thenReturn(getName()); ConfiguredObjectFactory factory = new ConfiguredObjectFactoryImpl(BrokerModel.getInstance()); - when(_virtualHost.getObjectFactory()).thenReturn(factory); - when(_virtualHost.getModel()).thenReturn(factory.getModel()); + + _parent = mock(ConfiguredObject.class); + when(_parent.getName()).thenReturn(getName()); + when(_parent.getObjectFactory()).thenReturn(factory); + when(_parent.getModel()).thenReturn(factory.getModel()); _storeLocation = TestFileUtils.createTestDirectory("json", true); _configurationStoreSettings = new HashMap(); _configurationStoreSettings.put(JsonFileConfigStore.STORE_TYPE, JsonFileConfigStore.TYPE); @@ -99,7 +100,7 @@ public class JsonFileConfigStoreTest extends QpidTestCase _configurationStoreSettings.put(JsonFileConfigStore.STORE_PATH, null); try { - _store.openConfigurationStore(_virtualHost, _configurationStoreSettings); + _store.openConfigurationStore(_parent, _configurationStoreSettings); fail("Store should not successfully configure if there is no path set"); } catch (ServerScopedRuntimeException e) @@ -114,7 +115,7 @@ public class JsonFileConfigStoreTest extends QpidTestCase _configurationStoreSettings.put(JsonFileConfigStore.STORE_PATH, System.getProperty("file.separator")); try { - _store.openConfigurationStore(_virtualHost, _configurationStoreSettings); + _store.openConfigurationStore(_parent, _configurationStoreSettings); fail("Store should not successfully configure if there is an invalid path set"); } catch (ServerScopedRuntimeException e) @@ -125,50 +126,76 @@ public class JsonFileConfigStoreTest extends QpidTestCase public void testVisitEmptyStore() { - _store.openConfigurationStore(_virtualHost, _configurationStoreSettings); + _store.openConfigurationStore(_parent, _configurationStoreSettings); _store.visitConfiguredObjectRecords(_handler); InOrder inorder = inOrder(_handler); inorder.verify(_handler).begin(); - inorder.verify(_handler,never()).handle(any(ConfiguredObjectRecord.class)); + inorder.verify(_handler,times(0)).handle(any(ConfiguredObjectRecord.class)); inorder.verify(_handler).end(); + + _store.closeConfigurationStore(); + } + + public void testInsertAndUpdateTopLevelObject() throws Exception + { + _store.openConfigurationStore(_parent, _configurationStoreSettings); + createRootRecord(); + _store.closeConfigurationStore(); + + _store.openConfigurationStore(_parent, _configurationStoreSettings); + Map newAttributes = new HashMap(_rootRecord.getAttributes()); + newAttributes.put("attributeName", "attributeValue"); + _store.update(false, new ConfiguredObjectRecordImpl(_rootRecord.getId(), _rootRecord.getType(), newAttributes)); + _store.closeConfigurationStore(); + + _store.openConfigurationStore(_parent, _configurationStoreSettings); + + _store.visitConfiguredObjectRecords(_handler); + + Map expectedAttributes = new HashMap(newAttributes); + verify(_handler, times(1)).handle(matchesRecord(_rootRecord.getId(), _rootRecord.getType(), expectedAttributes)); _store.closeConfigurationStore(); } public void testCreateObject() throws Exception { - _store.openConfigurationStore(_virtualHost, _configurationStoreSettings); + _store.openConfigurationStore(_parent, _configurationStoreSettings); + createRootRecord(); + final UUID queueId = new UUID(0, 1); final String queueType = Queue.class.getSimpleName(); final Map queueAttr = Collections.singletonMap("name", (Object) "q1"); - _store.create(new ConfiguredObjectRecordImpl(queueId, queueType, queueAttr)); + _store.create(new ConfiguredObjectRecordImpl(queueId, queueType, queueAttr, getRootAsParentMap())); _store.closeConfigurationStore(); - _store.openConfigurationStore(_virtualHost, _configurationStoreSettings); + _store.openConfigurationStore(_parent, _configurationStoreSettings); _store.visitConfiguredObjectRecords(_handler); - verify(_handler, times(1)).handle(matchesRecord(queueId, queueType, queueAttr)); + verify(_handler).handle(matchesRecord(queueId, queueType, queueAttr)); + verify(_handler).handle(matchesRecord(ANY_UUID, VIRTUAL_HOST_TYPE, ANY_MAP)); _store.closeConfigurationStore(); } public void testCreateAndUpdateObject() throws Exception { - _store.openConfigurationStore(_virtualHost, _configurationStoreSettings); + _store.openConfigurationStore(_parent, _configurationStoreSettings); + createRootRecord(); + final UUID queueId = new UUID(0, 1); final String queueType = Queue.class.getSimpleName(); Map queueAttr = Collections.singletonMap("name", (Object) "q1"); - _store.create(new ConfiguredObjectRecordImpl(queueId, queueType, queueAttr)); - + _store.create(new ConfiguredObjectRecordImpl(queueId, queueType, queueAttr, getRootAsParentMap())); queueAttr = new HashMap(queueAttr); queueAttr.put("owner", "theowner"); - _store.update(false, new ConfiguredObjectRecordImpl(queueId, queueType, queueAttr)); + _store.update(false, new ConfiguredObjectRecordImpl(queueId, queueType, queueAttr, getRootAsParentMap())); _store.closeConfigurationStore(); - _store.openConfigurationStore(_virtualHost, _configurationStoreSettings); + _store.openConfigurationStore(_parent, _configurationStoreSettings); _store.visitConfiguredObjectRecords(_handler); verify(_handler, times(1)).handle(matchesRecord(queueId, queueType, queueAttr)); _store.closeConfigurationStore(); @@ -177,12 +204,14 @@ public class JsonFileConfigStoreTest extends QpidTestCase public void testCreateAndRemoveObject() throws Exception { - _store.openConfigurationStore(_virtualHost, _configurationStoreSettings); + _store.openConfigurationStore(_parent, _configurationStoreSettings); + createRootRecord(); + final UUID queueId = new UUID(0, 1); final String queueType = Queue.class.getSimpleName(); Map queueAttr = Collections.singletonMap("name", (Object) "q1"); - final ConfiguredObjectRecordImpl record = new ConfiguredObjectRecordImpl(queueId, queueType, queueAttr); + final ConfiguredObjectRecordImpl record = new ConfiguredObjectRecordImpl(queueId, queueType, queueAttr, getRootAsParentMap()); _store.create(record); @@ -190,18 +219,20 @@ public class JsonFileConfigStoreTest extends QpidTestCase _store.closeConfigurationStore(); - _store.openConfigurationStore(_virtualHost, _configurationStoreSettings); + _store.openConfigurationStore(_parent, _configurationStoreSettings); _store.visitConfiguredObjectRecords(_handler); - verify(_handler, never()).handle(any(ConfiguredObjectRecord.class)); + verify(_handler, times(1)).handle(matchesRecord(ANY_UUID, VIRTUAL_HOST_TYPE, ANY_MAP)); _store.closeConfigurationStore(); } public void testCreateUnknownObjectType() throws Exception { - _store.openConfigurationStore(_virtualHost, _configurationStoreSettings); + _store.openConfigurationStore(_parent, _configurationStoreSettings); + createRootRecord(); + try { - _store.create(new ConfiguredObjectRecordImpl(UUID.randomUUID(), "wibble", Collections.emptyMap())); + _store.create(new ConfiguredObjectRecordImpl(UUID.randomUUID(), "wibble", Collections.emptyMap(), getRootAsParentMap())); fail("Should not be able to create instance of type wibble"); } catch (StoreException e) @@ -212,12 +243,14 @@ public class JsonFileConfigStoreTest extends QpidTestCase public void testTwoObjectsWithSameId() throws Exception { - _store.openConfigurationStore(_virtualHost, _configurationStoreSettings); + _store.openConfigurationStore(_parent, _configurationStoreSettings); + createRootRecord(); + final UUID id = UUID.randomUUID(); - _store.create(new ConfiguredObjectRecordImpl(id, "Queue", Collections.emptyMap())); + _store.create(new ConfiguredObjectRecordImpl(id, "Queue", Collections.emptyMap(), getRootAsParentMap())); try { - _store.create(new ConfiguredObjectRecordImpl(id, "Exchange", Collections.emptyMap())); + _store.create(new ConfiguredObjectRecordImpl(id, "Exchange", Collections.emptyMap(), getRootAsParentMap())); fail("Should not be able to create two objects with same id"); } catch (StoreException e) @@ -229,15 +262,17 @@ public class JsonFileConfigStoreTest extends QpidTestCase public void testChangeTypeOfObject() throws Exception { - _store.openConfigurationStore(_virtualHost, _configurationStoreSettings); + _store.openConfigurationStore(_parent, _configurationStoreSettings); + createRootRecord(); + final UUID id = UUID.randomUUID(); - _store.create(new ConfiguredObjectRecordImpl(id, "Queue", Collections.emptyMap())); + _store.create(new ConfiguredObjectRecordImpl(id, "Queue", Collections.emptyMap(), getRootAsParentMap())); _store.closeConfigurationStore(); - _store.openConfigurationStore(_virtualHost, _configurationStoreSettings); + _store.openConfigurationStore(_parent, _configurationStoreSettings); try { - _store.update(false, new ConfiguredObjectRecordImpl(id, "Exchange", Collections.emptyMap())); + _store.update(false, new ConfiguredObjectRecordImpl(id, "Exchange", Collections.emptyMap(), getRootAsParentMap())); fail("Should not be able to update object to different type"); } catch (StoreException e) @@ -248,13 +283,13 @@ public class JsonFileConfigStoreTest extends QpidTestCase public void testLockFileGuaranteesExclusiveAccess() throws Exception { - _store.openConfigurationStore(_virtualHost, _configurationStoreSettings); + _store.openConfigurationStore(_parent, _configurationStoreSettings); JsonFileConfigStore secondStore = new JsonFileConfigStore(); try { - secondStore.openConfigurationStore(_virtualHost, _configurationStoreSettings); + secondStore.openConfigurationStore(_parent, _configurationStoreSettings); fail("Should not be able to open a second store with the same path"); } catch(ServerScopedRuntimeException e) @@ -262,15 +297,16 @@ public class JsonFileConfigStoreTest extends QpidTestCase // pass } _store.closeConfigurationStore(); - secondStore.openConfigurationStore(_virtualHost, _configurationStoreSettings); + secondStore.openConfigurationStore(_parent, _configurationStoreSettings); } public void testCreatedNestedObjects() throws Exception { + _store.openConfigurationStore(_parent, _configurationStoreSettings); + createRootRecord(); - _store.openConfigurationStore(_virtualHost, _configurationStoreSettings); final UUID queueId = new UUID(0, 1); final UUID queue2Id = new UUID(1, 1); @@ -280,11 +316,12 @@ public class JsonFileConfigStoreTest extends QpidTestCase final UUID bindingId = new UUID(0, 3); final UUID binding2Id = new UUID(1, 3); - final ConfiguredObjectRecordImpl queueRecord = new ConfiguredObjectRecordImpl(queueId, "Queue", EMPTY_ATTR); + Map parents = getRootAsParentMap(); + final ConfiguredObjectRecordImpl queueRecord = new ConfiguredObjectRecordImpl(queueId, "Queue", EMPTY_ATTR, parents); _store.create(queueRecord); - final ConfiguredObjectRecordImpl queue2Record = new ConfiguredObjectRecordImpl(queue2Id, "Queue", EMPTY_ATTR); + final ConfiguredObjectRecordImpl queue2Record = new ConfiguredObjectRecordImpl(queue2Id, "Queue", EMPTY_ATTR, parents); _store.create(queue2Record); - final ConfiguredObjectRecordImpl exchangeRecord = new ConfiguredObjectRecordImpl(exchangeId, "Exchange", EMPTY_ATTR); + final ConfiguredObjectRecordImpl exchangeRecord = new ConfiguredObjectRecordImpl(exchangeId, "Exchange", EMPTY_ATTR, parents); _store.create(exchangeRecord); Map bindingParents = new HashMap(); bindingParents.put("Exchange", exchangeRecord); @@ -300,7 +337,7 @@ public class JsonFileConfigStoreTest extends QpidTestCase new ConfiguredObjectRecordImpl(binding2Id, "Binding", EMPTY_ATTR, binding2Parents); _store.update(true, bindingRecord, binding2Record); _store.closeConfigurationStore(); - _store.openConfigurationStore(_virtualHost, _configurationStoreSettings); + _store.openConfigurationStore(_parent, _configurationStoreSettings); _store.visitConfiguredObjectRecords(_handler); verify(_handler).handle(matchesRecord(queueId, "Queue", EMPTY_ATTR)); verify(_handler).handle(matchesRecord(queue2Id, "Queue", EMPTY_ATTR)); @@ -311,22 +348,36 @@ public class JsonFileConfigStoreTest extends QpidTestCase } + + private void createRootRecord() + { + UUID rootRecordId = UUID.randomUUID(); + _rootRecord = new ConfiguredObjectRecordImpl(rootRecordId, VIRTUAL_HOST_TYPE, Collections.emptyMap()); + _store.create(_rootRecord); + } + + private Map getRootAsParentMap() + { + return Collections.singletonMap(VIRTUAL_HOST_TYPE, _rootRecord); + } + private ConfiguredObjectRecord matchesRecord(UUID id, String type, Map attributes) { return argThat(new ConfiguredObjectMatcher(id, type, attributes)); } + private static class ConfiguredObjectMatcher extends ArgumentMatcher { - private final Map _matchingMap; - private final UUID _id; - private final String _name; + private final Map _expectedAttributes; + private final UUID _expectedId; + private final String _expectedType; private ConfiguredObjectMatcher(final UUID id, final String type, final Map matchingMap) { - _id = id; - _name = type; - _matchingMap = matchingMap; + _expectedId = id; + _expectedType = type; + _expectedAttributes = matchingMap; } @Override @@ -339,9 +390,9 @@ public class JsonFileConfigStoreTest extends QpidTestCase Map arg = new HashMap(binding.getAttributes()); arg.remove("createdBy"); arg.remove("createdTime"); - return (_id == ANY_UUID || _id.equals(binding.getId())) - && _name.equals(binding.getType()) - && (_matchingMap == ANY_MAP || arg.equals(_matchingMap)); + return (_expectedId == ANY_UUID || _expectedId.equals(binding.getId())) + && _expectedType.equals(binding.getType()) + && (_expectedAttributes == ANY_MAP || arg.equals(_expectedAttributes)); } return false; diff --git a/java/broker-core/src/test/java/org/apache/qpid/server/store/TestMemoryMessageStoreFactory.java b/java/broker-core/src/test/java/org/apache/qpid/server/store/TestMemoryMessageStoreFactory.java index 73e14389d5..d7c11ea226 100644 --- a/java/broker-core/src/test/java/org/apache/qpid/server/store/TestMemoryMessageStoreFactory.java +++ b/java/broker-core/src/test/java/org/apache/qpid/server/store/TestMemoryMessageStoreFactory.java @@ -23,9 +23,10 @@ package org.apache.qpid.server.store; import java.util.Map; +import org.apache.qpid.server.plugin.DurableConfigurationStoreFactory; import org.apache.qpid.server.plugin.MessageStoreFactory; -public class TestMemoryMessageStoreFactory implements MessageStoreFactory +public class TestMemoryMessageStoreFactory implements MessageStoreFactory, DurableConfigurationStoreFactory { @Override @@ -44,4 +45,15 @@ public class TestMemoryMessageStoreFactory implements MessageStoreFactory public void validateAttributes(Map attributes) { } + + @Override + public DurableConfigurationStore createDurableConfigurationStore() + { + return new TestMemoryMessageStore(); + } + + @Override + public void validateConfigurationStoreSettings(Map attributes) + { + } } diff --git a/java/broker-core/src/test/java/org/apache/qpid/server/util/BrokerTestHelper.java b/java/broker-core/src/test/java/org/apache/qpid/server/util/BrokerTestHelper.java index 0f2813f1d1..da03509524 100644 --- a/java/broker-core/src/test/java/org/apache/qpid/server/util/BrokerTestHelper.java +++ b/java/broker-core/src/test/java/org/apache/qpid/server/util/BrokerTestHelper.java @@ -21,7 +21,6 @@ package org.apache.qpid.server.util; import static org.mockito.Matchers.any; -import static org.mockito.Matchers.eq; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; @@ -50,6 +49,7 @@ import org.apache.qpid.server.model.SystemContext; import org.apache.qpid.server.model.SystemContextImpl; import org.apache.qpid.server.model.UUIDGenerator; import org.apache.qpid.server.model.VirtualHost; +import org.apache.qpid.server.model.VirtualHostNode; import org.apache.qpid.server.protocol.AMQConnectionModel; import org.apache.qpid.server.protocol.AMQSessionModel; import org.apache.qpid.server.queue.AMQQueue; @@ -75,29 +75,31 @@ public class BrokerTestHelper TASK_EXECUTOR.start(); } - public static Broker createBrokerMock() + public static Broker createBrokerMock() { ConfiguredObjectFactory objectFactory = new ConfiguredObjectFactoryImpl(BrokerModel.getInstance()); - SubjectCreator subjectCreator = mock(SubjectCreator.class); + EventLogger eventLogger = new EventLogger(); + + SystemContext systemContext = mock(SystemContext.class); + when(systemContext.getEventLogger()).thenReturn(eventLogger); + when(systemContext.getObjectFactory()).thenReturn(objectFactory); + when(systemContext.getModel()).thenReturn(objectFactory.getModel()); + when(systemContext.getCategoryClass()).thenReturn(SystemContext.class); + SubjectCreator subjectCreator = mock(SubjectCreator.class); when(subjectCreator.getMechanisms()).thenReturn(""); + Broker broker = mock(Broker.class); when(broker.getConnection_sessionCountLimit()).thenReturn(1); when(broker.getConnection_closeWhenNoRoute()).thenReturn(false); when(broker.getId()).thenReturn(UUID.randomUUID()); when(broker.getSubjectCreator(any(SocketAddress.class))).thenReturn(subjectCreator); - when(broker.getSecurityManager()).thenReturn(new SecurityManager(mock(Broker.class), false)); + when(broker.getSecurityManager()).thenReturn(new SecurityManager(broker, false)); when(broker.getObjectFactory()).thenReturn(objectFactory); when(broker.getModel()).thenReturn(objectFactory.getModel()); - when(broker.getEventLogger()).thenReturn(new EventLogger()); + when(broker.getEventLogger()).thenReturn(eventLogger); when(broker.getCategoryClass()).thenReturn(Broker.class); - - SystemContext systemContext = mock(SystemContext.class); - when(systemContext.getObjectFactory()).thenReturn(objectFactory); - when(systemContext.getModel()).thenReturn(objectFactory.getModel()); - when(systemContext.getCategoryClass()).thenReturn(SystemContext.class); - when(systemContext.getEventLogger()).thenReturn(new EventLogger()); - when(broker.getParent(eq(SystemContext.class))).thenReturn(systemContext); + when(broker.getParent(SystemContext.class)).thenReturn(systemContext); return broker; } @@ -110,34 +112,33 @@ public class BrokerTestHelper { } - public static VirtualHostImpl createVirtualHost(Map attributes) + public static VirtualHostImpl createVirtualHost(Map attributes) throws Exception { //VirtualHostFactory factory = new PluggableFactoryLoader(VirtualHostFactory.class).get(hostType); + Broker broker = createBrokerMock(); + ConfiguredObjectFactory objectFactory = broker.getObjectFactory(); SystemContext systemContext = new SystemContextImpl(TASK_EXECUTOR, - new ConfiguredObjectFactoryImpl(BrokerModel.getInstance()), + objectFactory, mock(EventLogger.class), mock(LogRecorder.class), new BrokerOptions()); - ConfiguredObjectFactory objectFactory = new ConfiguredObjectFactoryImpl(BrokerModel.getInstance()); - Broker broker = mock(Broker.class); - when(broker.getParent(eq(SystemContext.class))).thenReturn(systemContext); when(broker.getTaskExecutor()).thenReturn(TASK_EXECUTOR); - SecurityManager securityManager = new SecurityManager(broker, false); - when(broker.getSecurityManager()).thenReturn(securityManager); - when(broker.getCategoryClass()).thenReturn(Broker.class); - when(broker.getObjectFactory()).thenReturn(objectFactory); - when(broker.getModel()).thenReturn(objectFactory.getModel()); - - AbstractVirtualHost host = (AbstractVirtualHost) objectFactory.create(VirtualHost.class,attributes, broker); + VirtualHostNode virtualHostNode = mock(VirtualHostNode.class); + DurableConfigurationStore dcs = mock(DurableConfigurationStore.class); + when(virtualHostNode.getConfigurationStore()).thenReturn(dcs); + when(virtualHostNode.getParent(Broker.class)).thenReturn(broker); + when(virtualHostNode.getModel()).thenReturn(objectFactory.getModel()); + when(virtualHostNode.getObjectFactory()).thenReturn(objectFactory); + AbstractVirtualHost host = (AbstractVirtualHost) objectFactory.create(VirtualHost.class, attributes, virtualHostNode ); host.setDesiredState(host.getState(), State.ACTIVE); return host; } - public static VirtualHostImpl createVirtualHost(String name) throws Exception + public static VirtualHostImpl createVirtualHost(String name) throws Exception { Map attributes = new HashMap(); attributes.put(org.apache.qpid.server.model.VirtualHost.TYPE, StandardVirtualHost.TYPE); @@ -151,41 +152,40 @@ public class BrokerTestHelper return createVirtualHost(attributes); } - public static AMQSessionModel createSession(int channelId, AMQConnectionModel connection) + public static AMQSessionModel createSession(int channelId, AMQConnectionModel connection) { + @SuppressWarnings("rawtypes") AMQSessionModel session = mock(AMQSessionModel.class); when(session.getConnectionModel()).thenReturn(connection); when(session.getChannelId()).thenReturn(channelId); return session; } - public static AMQSessionModel createSession(int channelId) throws Exception + public static AMQSessionModel createSession(int channelId) throws Exception { - AMQConnectionModel session = createConnection(); + AMQConnectionModel session = createConnection(); return createSession(channelId, session); } - public static AMQSessionModel createSession() throws Exception + public static AMQSessionModel createSession() throws Exception { return createSession(1); } - public static AMQConnectionModel createConnection() throws Exception + public static AMQConnectionModel createConnection() throws Exception { return createConnection("test"); } - public static AMQConnectionModel createConnection(String hostName) throws Exception + public static AMQConnectionModel createConnection(String hostName) throws Exception { - VirtualHostImpl virtualHost = createVirtualHost(hostName); - AMQConnectionModel connection = mock(AMQConnectionModel.class); - return connection; + return mock(AMQConnectionModel.class); } - public static ExchangeImpl createExchange(String hostName, final boolean durable, final EventLogger eventLogger) throws Exception + public static ExchangeImpl createExchange(String hostName, final boolean durable, final EventLogger eventLogger) throws Exception { SecurityManager securityManager = new SecurityManager(mock(Broker.class), false); - final VirtualHostImpl virtualHost = mock(VirtualHostImpl.class); + final VirtualHostImpl virtualHost = mock(VirtualHostImpl.class); when(virtualHost.getName()).thenReturn(hostName); when(virtualHost.getSecurityManager()).thenReturn(securityManager); when(virtualHost.getEventLogger()).thenReturn(eventLogger); @@ -210,13 +210,13 @@ public class BrokerTestHelper } - public static AMQQueue createQueue(String queueName, VirtualHostImpl virtualHost) + public static AMQQueue createQueue(String queueName, VirtualHostImpl virtualHost) throws QueueExistsException { Map attributes = new HashMap(); attributes.put(Queue.ID, UUIDGenerator.generateRandomUUID()); attributes.put(Queue.NAME, queueName); - AMQQueue queue = virtualHost.createQueue(attributes); + AMQQueue queue = virtualHost.createQueue(attributes); return queue; } diff --git a/java/broker-core/src/test/java/org/apache/qpid/server/virtualhost/DurableConfigurationRecovererTest.java b/java/broker-core/src/test/java/org/apache/qpid/server/virtualhost/DurableConfigurationRecovererTest.java deleted file mode 100644 index 17c1958cec..0000000000 --- a/java/broker-core/src/test/java/org/apache/qpid/server/virtualhost/DurableConfigurationRecovererTest.java +++ /dev/null @@ -1,545 +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.virtualhost; - -import static org.mockito.Matchers.any; -import static org.mockito.Matchers.anyBoolean; -import static org.mockito.Matchers.anyMap; -import static org.mockito.Matchers.eq; -import static org.mockito.Mockito.doAnswer; -import static org.mockito.Mockito.doThrow; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; - -import java.util.Arrays; -import java.util.Collections; -import java.util.HashMap; -import java.util.HashSet; -import java.util.LinkedHashMap; -import java.util.Map; -import java.util.UUID; - -import org.mockito.ArgumentCaptor; -import org.mockito.invocation.InvocationOnMock; -import org.mockito.stubbing.Answer; - -import org.apache.qpid.server.configuration.IllegalConfigurationException; -import org.apache.qpid.server.exchange.DirectExchange; -import org.apache.qpid.server.exchange.ExchangeImpl; -import org.apache.qpid.server.exchange.HeadersExchange; -import org.apache.qpid.server.exchange.TopicExchange; -import org.apache.qpid.server.logging.EventLogger; -import org.apache.qpid.server.model.Binding; -import org.apache.qpid.server.model.Broker; -import org.apache.qpid.server.model.BrokerModel; -import org.apache.qpid.server.model.ConfiguredObject; -import org.apache.qpid.server.model.ConfiguredObjectFactory; -import org.apache.qpid.server.model.Exchange; -import org.apache.qpid.server.model.Queue; -import org.apache.qpid.server.model.SystemContext; -import org.apache.qpid.server.model.UUIDGenerator; -import org.apache.qpid.server.model.VirtualHost; -import org.apache.qpid.server.plugin.ConfiguredObjectTypeFactory; -import org.apache.qpid.server.plugin.ExchangeType; -import org.apache.qpid.server.queue.AMQQueue; -import org.apache.qpid.server.store.ConfiguredObjectRecord; -import org.apache.qpid.server.store.ConfiguredObjectRecordImpl; -import org.apache.qpid.server.store.DurableConfigurationRecoverer; -import org.apache.qpid.server.store.DurableConfigurationStore; -import org.apache.qpid.server.store.DurableConfiguredObjectRecoverer; -import org.apache.qpid.server.store.StoreException; -import org.apache.qpid.server.store.UnresolvedConfiguredObject; -import org.apache.qpid.test.utils.QpidTestCase; - -public class DurableConfigurationRecovererTest extends QpidTestCase -{ - private static final String VIRTUAL_HOST_NAME = "test"; - private static final UUID VIRTUAL_HOST_ID = UUID.randomUUID(); - private static final UUID QUEUE_ID = new UUID(0,0); - private static final UUID TOPIC_EXCHANGE_ID = UUIDGenerator.generateExchangeUUID(TopicExchange.TYPE.getDefaultExchangeName(), VIRTUAL_HOST_NAME); - private static final UUID DIRECT_EXCHANGE_ID = UUIDGenerator.generateExchangeUUID(DirectExchange.TYPE.getDefaultExchangeName(), VIRTUAL_HOST_NAME); - private static final String CUSTOM_EXCHANGE_NAME = "customExchange"; - - private DurableConfigurationRecoverer _durableConfigurationRecoverer; - private VirtualHostImpl _vhost; - private DurableConfigurationStore _store; - private ConfiguredObjectFactory _configuredObjectFactory; - private ConfiguredObjectTypeFactory _exchangeFactory; - private ConfiguredObjectTypeFactory _queueFactory; - private ConfiguredObjectTypeFactory _bindingFactory; - - @Override - public void setUp() throws Exception - { - super.setUp(); - _configuredObjectFactory = mock(ConfiguredObjectFactory.class); - _exchangeFactory = mock(ConfiguredObjectTypeFactory.class); - _queueFactory = mock(ConfiguredObjectTypeFactory.class); - _bindingFactory = mock(ConfiguredObjectTypeFactory.class); - - - - AMQQueue queue = mock(AMQQueue.class); - - _vhost = mock(VirtualHostImpl.class); - when(_vhost.getName()).thenReturn(VIRTUAL_HOST_NAME); - final Broker broker = mock(Broker.class); - final SystemContext systemContext = mock(SystemContext.class); - when(systemContext.getObjectFactory()).thenReturn(_configuredObjectFactory); - when(broker.getObjectFactory()).thenReturn(_configuredObjectFactory); - when(broker.getParent(eq(SystemContext.class))).thenReturn(systemContext); - when(_vhost.getParent(eq(Broker.class))).thenReturn(broker); - - when(_vhost.getQueue(eq(QUEUE_ID))).thenReturn(queue); - - when(_configuredObjectFactory.getConfiguredObjectTypeFactory(eq(Exchange.class), anyMap())).thenReturn(_exchangeFactory); - when(_configuredObjectFactory.getConfiguredObjectTypeFactory(eq(Queue.class), anyMap())).thenReturn(_queueFactory); - when(_configuredObjectFactory.getConfiguredObjectTypeFactory(eq(Binding.class), anyMap())).thenReturn(_bindingFactory); - final ArgumentCaptor recordArgumentCaptor = ArgumentCaptor.forClass(ConfiguredObjectRecord.class); - when(_configuredObjectFactory.recover(recordArgumentCaptor.capture(), any(ConfiguredObject.class))).thenAnswer(new Answer() - { - @Override - public Object answer(final InvocationOnMock invocation) throws Throwable - { - ConfiguredObjectRecord record = recordArgumentCaptor.getValue(); - if(record.getType().equals("Queue")) - { - return _queueFactory.recover(mock(ConfiguredObjectFactory.class), record, _vhost); - } - else if(record.getType().equals("Exchange")) - { - return _exchangeFactory.recover(mock(ConfiguredObjectFactory.class), record, _vhost); - } - return null; - } - }); - - final ArgumentCaptor bindingRecordArgumentCaptor = ArgumentCaptor.forClass(ConfiguredObjectRecord.class); - when(_configuredObjectFactory.recover(bindingRecordArgumentCaptor.capture(), any(ConfiguredObject.class), any(ConfiguredObject.class))).thenAnswer(new Answer() - { - @Override - public Object answer(final InvocationOnMock invocation) throws Throwable - { - ConfiguredObjectRecord record = bindingRecordArgumentCaptor.getValue(); - if(record.getType().equals("Binding")) - { - return _bindingFactory.recover(mock(ConfiguredObjectFactory.class), record, mock(ConfiguredObject.class),mock(ConfiguredObject.class)); - } - return null; - } - }); - - - final ArgumentCaptor recoveredExchange = ArgumentCaptor.forClass(ConfiguredObjectRecord.class); - doAnswer(new Answer() - { - - @Override - public Object answer(final InvocationOnMock invocation) throws Throwable - { - ConfiguredObjectRecord exchangeRecord = recoveredExchange.getValue(); - ExchangeImpl exchange = mock(ExchangeImpl.class); - UUID id = exchangeRecord.getId(); - String name = (String) exchangeRecord.getAttributes().get("name"); - when(exchange.getId()).thenReturn(id); - when(exchange.getName()).thenReturn(name); - when(_vhost.getExchange(eq(id))).thenReturn(exchange); - when(_vhost.getExchange(eq(name))).thenReturn(exchange); - - UnresolvedConfiguredObject unresolved = mock(UnresolvedConfiguredObject.class); - when(unresolved.resolve()).thenReturn(exchange); - return unresolved; - } - }).when(_exchangeFactory).recover(any(ConfiguredObjectFactory.class), recoveredExchange.capture(), any(ConfiguredObject.class)); - - - - - final ArgumentCaptor recoveredQueue = ArgumentCaptor.forClass(ConfiguredObjectRecord.class); - doAnswer(new Answer() - { - - @Override - public Object answer(final InvocationOnMock invocation) throws Throwable - { - ConfiguredObjectRecord queueRecord = recoveredQueue.getValue(); - AMQQueue queue = mock(AMQQueue.class); - UUID id = queueRecord.getId(); - String name = (String) queueRecord.getAttributes().get("name"); - when(queue.getId()).thenReturn(id); - when(queue.getName()).thenReturn(name); - when(_vhost.getQueue(eq(id))).thenReturn(queue); - when(_vhost.getQueue(eq(name))).thenReturn(queue); - - UnresolvedConfiguredObject unresolved = mock(UnresolvedConfiguredObject.class); - when(unresolved.resolve()).thenReturn(queue); - - Map args = queueRecord.getAttributes(); - if (args.containsKey(Queue.ALTERNATE_EXCHANGE)) - { - final UUID exchangeId = UUID.fromString(args.get(Queue.ALTERNATE_EXCHANGE).toString()); - final ExchangeImpl exchange = - _vhost.getExchange(exchangeId); - when(queue.getAlternateExchange()).thenReturn(exchange); - } - - return unresolved; - } - }).when(_queueFactory).recover(any(ConfiguredObjectFactory.class), recoveredQueue.capture(), any(ConfiguredObject.class)); - - - final ArgumentCaptor recoveredBinding = ArgumentCaptor.forClass(ConfiguredObjectRecord.class); - final ArgumentCaptor parent1 = ArgumentCaptor.forClass(ConfiguredObject.class); - final ArgumentCaptor parent2 = ArgumentCaptor.forClass(ConfiguredObject.class); - - doAnswer(new Answer() - { - - @Override - public Object answer(final InvocationOnMock invocation) throws Throwable - { - ConfiguredObjectRecord bindingRecord = recoveredBinding.getValue(); - Binding binding = mock(Binding.class); - UUID id = bindingRecord.getId(); - String name = (String) bindingRecord.getAttributes().get("name"); - when(binding.getId()).thenReturn(id); - when(binding.getName()).thenReturn(name); - - UnresolvedConfiguredObject unresolved = mock(UnresolvedConfiguredObject.class); - when(unresolved.resolve()).thenReturn(binding); - - - return unresolved; - } - }).when(_bindingFactory).recover(any(ConfiguredObjectFactory.class), recoveredBinding.capture(), parent1.capture(), parent2.capture()); - - - - DurableConfiguredObjectRecoverer[] recoverers = { - new QueueRecoverer(_vhost), - new ExchangeRecoverer(_vhost), - new BindingRecoverer(_vhost) - }; - - final Map recovererMap= new HashMap(); - for(DurableConfiguredObjectRecoverer recoverer : recoverers) - { - recovererMap.put(recoverer.getType(), recoverer); - } - _durableConfigurationRecoverer = - new DurableConfigurationRecoverer(_vhost.getName(), recovererMap, - new DefaultUpgraderProvider(_vhost), new EventLogger()); - - _store = mock(DurableConfigurationStore.class); - - } - - public void testUpgradeEmptyStore() throws Exception - { - _durableConfigurationRecoverer.beginConfigurationRecovery(_store); - assertEquals("Did not upgrade to the expected version", - BrokerModel.MODEL_VERSION, - _durableConfigurationRecoverer.completeConfigurationRecovery()); - } - - public void testUpgradeNewerStoreFails() throws Exception - { - String bumpedModelVersion = BrokerModel.MODEL_MAJOR_VERSION + "." + (BrokerModel.MODEL_MINOR_VERSION + 1); - try - { - - _durableConfigurationRecoverer.beginConfigurationRecovery(_store); - _durableConfigurationRecoverer.configuredObject(getVirtualHostModelRecord(bumpedModelVersion)); - String newVersion = _durableConfigurationRecoverer.completeConfigurationRecovery(); - fail("Should not be able to start when config model is newer than current. Actually upgraded to " + newVersion); - } - catch (IllegalStateException e) - { - // pass - } - } - - private ConfiguredObjectRecordImpl getVirtualHostModelRecord( - String modelVersion) - { - ConfiguredObjectRecordImpl virtualHostRecord = new ConfiguredObjectRecordImpl(VIRTUAL_HOST_ID, - VirtualHost.class.getSimpleName(), - Collections.singletonMap("modelVersion", modelVersion)); - return virtualHostRecord; - } - - public void testUpgradeRemovesBindingsToNonTopicExchanges() throws Exception - { - - _durableConfigurationRecoverer.beginConfigurationRecovery(_store); - _durableConfigurationRecoverer.configuredObject(getVirtualHostModelRecord("0.0")); - - _durableConfigurationRecoverer.configuredObject(new ConfiguredObjectRecordImpl(new UUID(1, 0), - "org.apache.qpid.server.model.Binding", - createBinding("key", - "x-filter-jms-selector", - "wibble"), - createBindingParents(DIRECT_EXCHANGE_ID, QUEUE_ID))); - - final ConfiguredObjectRecord[] expected = { - new ConfiguredObjectRecordImpl(new UUID(1, 0), "Binding", - createBinding("key")) - }; - - verifyCorrectUpdates(expected); - - _durableConfigurationRecoverer.completeConfigurationRecovery(); - } - - - - public void testUpgradeOnlyRemovesSelectorBindings() throws Exception - { - - _durableConfigurationRecoverer.beginConfigurationRecovery(_store); - _durableConfigurationRecoverer.configuredObject(getVirtualHostModelRecord("0.0")); - - _durableConfigurationRecoverer.configuredObject(new ConfiguredObjectRecordImpl(new UUID(1, 0), - "org.apache.qpid.server.model.Binding", - createBinding("key", - "x-filter-jms-selector", - "wibble", - "not-a-selector", - "moo"), - createBindingParents(DIRECT_EXCHANGE_ID, QUEUE_ID))); - - - final UUID customExchangeId = new UUID(3,0); - - _durableConfigurationRecoverer.configuredObject(new ConfiguredObjectRecordImpl(new UUID(2, 0), - "org.apache.qpid.server.model.Binding", - createBinding("key", - "x-filter-jms-selector", - "wibble", - "not-a-selector", - "moo"), - createBindingParents(customExchangeId,QUEUE_ID))); - - _durableConfigurationRecoverer.configuredObject(new ConfiguredObjectRecordImpl(customExchangeId, - "org.apache.qpid.server.model.Exchange", - createExchange(CUSTOM_EXCHANGE_NAME, HeadersExchange.TYPE))); - - final ConfiguredObjectRecord[] expected = { - new ConfiguredObjectRecordImpl(new UUID(1, 0), "org.apache.qpid.server.model.Binding", - createBinding("key", "not-a-selector", "moo")), - new ConfiguredObjectRecordImpl(new UUID(2, 0), "org.apache.qpid.server.model.Binding", - createBinding("key", "not-a-selector", "moo")) - }; - - verifyCorrectUpdates(expected); - - _durableConfigurationRecoverer.completeConfigurationRecovery(); - } - - - public void testUpgradeKeepsBindingsToTopicExchanges() throws Exception - { - - _durableConfigurationRecoverer.beginConfigurationRecovery(_store); - _durableConfigurationRecoverer.configuredObject(getVirtualHostModelRecord("0.0")); - - _durableConfigurationRecoverer.configuredObject(new ConfiguredObjectRecordImpl(new UUID(1, 0), - "org.apache.qpid.server.model.Binding", - createBinding("key", - "x-filter-jms-selector", - "wibble"), - createBindingParents(TOPIC_EXCHANGE_ID,QUEUE_ID))); - - final ConfiguredObjectRecord[] expected = { - new ConfiguredObjectRecordImpl(new UUID(1, 0), "Binding", - createBinding("key", "x-filter-jms-selector", "wibble")) - }; - - verifyCorrectUpdates(expected); - - _durableConfigurationRecoverer.completeConfigurationRecovery(); - } - - public void testUpgradeDoesNotRecur() throws Exception - { - - _durableConfigurationRecoverer.beginConfigurationRecovery(_store); - _durableConfigurationRecoverer.configuredObject(getVirtualHostModelRecord("0.0")); - - _durableConfigurationRecoverer.configuredObject(new ConfiguredObjectRecordImpl(new UUID(1, 0), - "Binding", - createBinding("key", - "x-filter-jms-selector", - "wibble"), - createBindingParents(DIRECT_EXCHANGE_ID,QUEUE_ID))); - - doThrow(new RuntimeException("Update Should not be called")) - .when(_store).update(anyBoolean(), any(ConfiguredObjectRecordImpl[].class)); - - _durableConfigurationRecoverer.completeConfigurationRecovery(); - } - - public void testFailsWithUnresolvedObjects() - { - _durableConfigurationRecoverer.beginConfigurationRecovery(_store); - - - _durableConfigurationRecoverer.configuredObject(new ConfiguredObjectRecordImpl(new UUID(1, 0), - "Binding", - createBinding("key", - "x-filter-jms-selector", - "wibble"), - createBindingParents(new UUID(3,0), - QUEUE_ID))); - - try - { - _durableConfigurationRecoverer.completeConfigurationRecovery(); - fail("Expected resolution to fail due to unknown object"); - } - catch(IllegalConfigurationException e) - { - assertEquals("Durable configuration has unresolved dependencies", e.getMessage()); - } - - } - - public void testFailsWithUnknownObjectType() - { - _durableConfigurationRecoverer.beginConfigurationRecovery(_store); - - - try - { - final Map emptyArguments = Collections.emptyMap(); - _durableConfigurationRecoverer.configuredObject(new ConfiguredObjectRecordImpl(new UUID(1, 0), - "Wibble", emptyArguments)); - _durableConfigurationRecoverer.completeConfigurationRecovery(); - fail("Expected resolution to fail due to unknown object type"); - } - catch(IllegalConfigurationException e) - { - assertEquals("Unknown type for configured object: Wibble", e.getMessage()); - } - - - } - - public void testRecoveryOfQueueAlternateExchange() throws Exception - { - - final UUID queueId = new UUID(1, 0); - final UUID exchangeId = new UUID(2, 0); - - _durableConfigurationRecoverer.beginConfigurationRecovery(_store); - - _durableConfigurationRecoverer.configuredObject(new ConfiguredObjectRecordImpl(queueId, Queue.class.getSimpleName(), - createQueue("testQueue", exchangeId))); - _durableConfigurationRecoverer.configuredObject(new ConfiguredObjectRecordImpl(exchangeId, - org.apache.qpid.server.model.Exchange.class.getSimpleName(), - createExchange(CUSTOM_EXCHANGE_NAME, HeadersExchange.TYPE))); - - _durableConfigurationRecoverer.completeConfigurationRecovery(); - - assertEquals(CUSTOM_EXCHANGE_NAME, _vhost.getQueue(queueId).getAlternateExchange().getName()); - } - - private void verifyCorrectUpdates(final ConfiguredObjectRecord[] expected) throws StoreException - { - doAnswer(new Answer() - { - @Override - public Object answer(InvocationOnMock invocation) throws Throwable - { - Object[] args = invocation.getArguments(); - final HashSet actual = new HashSet(Arrays.asList(args[1])); - assertEquals("Updated records are not as expected", new HashSet(Arrays.asList( - expected)), actual); - - return null; - } - }).when(_store).update(anyBoolean(), any(ConfiguredObjectRecordImpl[].class)); - } - - private Map createBinding(String bindingKey, String... args) - { - Map binding = new LinkedHashMap(); - - binding.put("name", bindingKey); - Map argumentMap = new LinkedHashMap(); - if(args != null && args.length != 0) - { - String key = null; - for(String arg : args) - { - if(key == null) - { - key = arg; - } - else - { - argumentMap.put(key, arg); - key = null; - } - } - } - binding.put(Binding.ARGUMENTS, argumentMap); - return binding; - } - - private Map createBindingParents(UUID exchangeId, UUID queueId) - { - Map parents = new HashMap(); - parents.put("Exchange", new ConfiguredObjectRecordImpl(exchangeId,"Exchange",Collections.emptyMap())); - parents.put("Queue", new ConfiguredObjectRecordImpl(queueId,"Queue",Collections.emptyMap())); - - return parents; - } - - - private Map createExchange(String name, ExchangeType type) - { - Map exchange = new LinkedHashMap(); - - exchange.put(org.apache.qpid.server.model.Exchange.NAME, name); - exchange.put(org.apache.qpid.server.model.Exchange.TYPE, type.getType()); - - return exchange; - - } - - - private Map createQueue(String name, UUID alternateExchangeId) - { - Map queue = new LinkedHashMap(); - - queue.put(Queue.NAME, name); - if(alternateExchangeId != null) - { - queue.put(Queue.ALTERNATE_EXCHANGE, alternateExchangeId.toString()); - } - - return queue; - - } - - -} diff --git a/java/broker-core/src/test/java/org/apache/qpid/server/virtualhost/MockVirtualHost.java b/java/broker-core/src/test/java/org/apache/qpid/server/virtualhost/MockVirtualHost.java index e92d63a6fc..3f104de77b 100644 --- a/java/broker-core/src/test/java/org/apache/qpid/server/virtualhost/MockVirtualHost.java +++ b/java/broker-core/src/test/java/org/apache/qpid/server/virtualhost/MockVirtualHost.java @@ -286,12 +286,6 @@ public class MockVirtualHost implements VirtualHostImpl getConfigurationStoreSettings() - { - return null; - } - @Override public long getQueueCount() { @@ -658,4 +652,11 @@ public class MockVirtualHost implements VirtualHostImpl _virtualHost; + private VirtualHostNode _virtualHostNode; + private TaskExecutor _taskExecutor; + @SuppressWarnings({ "rawtypes", "unchecked" }) @Override public void setUp() throws Exception { super.setUp(); - _broker = BrokerTestHelper.createBrokerMock(); - TaskExecutor taskExecutor = mock(TaskExecutor.class); - when(taskExecutor.isTaskExecutorThread()).thenReturn(true); - when(_broker.getTaskExecutor()).thenReturn(taskExecutor); + EventLogger eventLogger = mock(EventLogger.class); + SecurityManager securityManager = mock(SecurityManager.class); + ConfiguredObjectFactory objectFactory = new ConfiguredObjectFactoryImpl(BrokerModel.getInstance()); - _virtualHost = createHost(); - _virtualHost.open(); + _taskExecutor = new TaskExecutor(); + _taskExecutor.start(); + + SystemContext context = mock(SystemContext.class); + when(context.getEventLogger()).thenReturn(eventLogger); + + Broker broker = mock(Broker.class); + when(broker.getObjectFactory()).thenReturn(objectFactory); + when(broker.getCategoryClass()).thenReturn(Broker.class); + when(broker.getParent(SystemContext.class)).thenReturn(context); + when(broker.getSecurityManager()).thenReturn(securityManager); + when(broker.getModel()).thenReturn(objectFactory.getModel()); + when(broker.getTaskExecutor()).thenReturn(_taskExecutor); + _virtualHostNode = mock(VirtualHostNode.class); + when(_virtualHostNode.getParent(Broker.class)).thenReturn(broker); + when(_virtualHostNode.getConfigurationStore()).thenReturn(mock(DurableConfigurationStore.class)); + when(_virtualHostNode.getObjectFactory()).thenReturn(objectFactory); + when(_virtualHostNode.getModel()).thenReturn(objectFactory.getModel()); + _virtualHost = createHost(); + } + @Override + public void tearDown() throws Exception + { + try + { + _taskExecutor.stopImmediately(); + } + finally + { + super.tearDown(); + } } - private VirtualHostImpl createHost() + private VirtualHostImpl createHost() { Map attributes = new HashMap(); attributes.put(VirtualHost.NAME, getName()); @@ -77,13 +115,10 @@ public class VirtualHostQueueCreationTest extends QpidTestCase attributes = new HashMap(attributes); attributes.put(VirtualHost.ID, UUID.randomUUID()); - return new StandardVirtualHost(attributes, _broker); - } - - @Override - public void tearDown() throws Exception - { - super.tearDown(); + StandardVirtualHost host = new StandardVirtualHost(attributes, _virtualHostNode); + host.create(); + host.setDesiredState(host.getState(), State.ACTIVE); + return host; } private void verifyRegisteredQueueCount(int count) diff --git a/java/broker-core/src/test/java/org/apache/qpid/server/virtualhostnode/AbstractStandardVirtualHostNodeTest.java b/java/broker-core/src/test/java/org/apache/qpid/server/virtualhostnode/AbstractStandardVirtualHostNodeTest.java new file mode 100644 index 0000000000..3154a1e524 --- /dev/null +++ b/java/broker-core/src/test/java/org/apache/qpid/server/virtualhostnode/AbstractStandardVirtualHostNodeTest.java @@ -0,0 +1,170 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT 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.virtualhostnode; + +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +import java.util.HashMap; +import java.util.Map; +import java.util.UUID; + +import org.apache.qpid.server.configuration.updater.TaskExecutor; +import org.apache.qpid.server.model.Broker; +import org.apache.qpid.server.model.BrokerModel; +import org.apache.qpid.server.model.ConfiguredObjectFactoryImpl; +import org.apache.qpid.server.model.Model; +import org.apache.qpid.server.model.State; +import org.apache.qpid.server.model.SystemContext; +import org.apache.qpid.server.model.VirtualHost; +import org.apache.qpid.server.model.VirtualHostNode; +import org.apache.qpid.server.plugin.DurableConfigurationStoreFactory; +import org.apache.qpid.server.store.ConfiguredObjectRecord; +import org.apache.qpid.server.store.DurableConfigurationStore; +import org.apache.qpid.server.store.MessageStore; +import org.apache.qpid.server.store.NullMessageStore; +import org.apache.qpid.server.store.StoreException; +import org.apache.qpid.server.store.TestMemoryMessageStore; +import org.apache.qpid.server.store.handler.ConfiguredObjectRecordHandler; +import org.apache.qpid.server.util.BrokerTestHelper; +import org.apache.qpid.server.virtualhost.StandardVirtualHost; +import org.apache.qpid.test.utils.QpidTestCase; + +public class AbstractStandardVirtualHostNodeTest extends QpidTestCase +{ + private static final String TEST_VIRTUAL_HOST_NODE_NAME = "testNode"; + private static final String TEST_VIRTUAL_HOST_NAME = "testVirtualHost"; + + private DurableConfigurationStoreFactory _configStoreFactory = mock(DurableConfigurationStoreFactory.class); + private UUID _nodeId = UUID.randomUUID(); + private Broker _broker; + private DurableConfigurationStore _configStore; + private ConfiguredObjectRecord _record; + private TaskExecutor _taskExecutor; + + @Override + protected void setUp() throws Exception + { + super.setUp(); + + _broker = BrokerTestHelper.createBrokerMock(); + SystemContext systemContext = _broker.getParent(SystemContext.class); + when(systemContext.getObjectFactory()).thenReturn(new ConfiguredObjectFactoryImpl(mock(Model.class))); + + _taskExecutor = new TaskExecutor(); + _taskExecutor.start(); + when(_broker.getTaskExecutor()).thenReturn(_taskExecutor); + } + + @Override + protected void tearDown() throws Exception + { + try + { + _taskExecutor.stopImmediately(); + } + finally + { + super.tearDown(); + } + } + public void testActivationOpensConfigStoreWithExistingVirtualHostRecord() throws Exception + { + UUID virtualHostId = UUID.randomUUID(); + _record = createMockVirtualHostCOR(virtualHostId); + + _configStore = new NullMessageStore(){ + + @Override + public void visitConfiguredObjectRecords(ConfiguredObjectRecordHandler handler) throws StoreException + { + handler.begin(); + handler.handle(_record); + handler.end(); + } + }; + when(_configStoreFactory.createDurableConfigurationStore()).thenReturn(_configStore); + + Map nodeAttributes = new HashMap(); + nodeAttributes.put(VirtualHostNode.NAME, TEST_VIRTUAL_HOST_NODE_NAME); + nodeAttributes.put(VirtualHostNode.ID, _nodeId); + + VirtualHostNode node = new TestVirtualHostNode(_broker, nodeAttributes, _taskExecutor, _configStore); + node.open(); + node.setDesiredState(node.getState(), State.ACTIVE); + + VirtualHost virtualHost = node.getVirtualHost(); + assertNotNull("Virtual host was not recovered", virtualHost); + assertTrue("Unexpected virtual host type", virtualHost instanceof StandardVirtualHost); + assertEquals("Unexpected virtual host name", TEST_VIRTUAL_HOST_NAME, virtualHost.getName()); + assertEquals("Unexpected virtual host state", State.ACTIVE, virtualHost.getState()); + assertEquals("Unexpected virtual host id", virtualHostId, virtualHost.getId()); + } + + public void testActivationOpensConfigStoreWithoutVirtualHostRecord() throws Exception + { + _configStore = new NullMessageStore() { + + @Override + public void visitConfiguredObjectRecords(ConfiguredObjectRecordHandler handler) throws StoreException + { + handler.begin(); + // No records + handler.end(); + } + }; + when(_configStoreFactory.createDurableConfigurationStore()).thenReturn(_configStore); + + Map nodeAttributes = new HashMap(); + nodeAttributes.put(VirtualHostNode.NAME, TEST_VIRTUAL_HOST_NODE_NAME); + nodeAttributes.put(VirtualHostNode.ID, _nodeId); + + VirtualHostNode node = new TestVirtualHostNode(_broker, nodeAttributes, _taskExecutor, _configStore); + node.open(); + node.setDesiredState(node.getState(), State.ACTIVE); + + VirtualHost virtualHost = node.getVirtualHost(); + assertNotNull("Virtual host was not recovered", virtualHost); + assertTrue("Unexpected virtual host type", virtualHost instanceof StandardVirtualHost); + + // Virtualhost name taken from VHN and ID is random. + assertEquals("Unexpected virtual host name", TEST_VIRTUAL_HOST_NODE_NAME, virtualHost.getName()); + assertEquals("Unexpected virtual host state", State.ACTIVE, virtualHost.getState()); + assertNotNull("Unexpected virtual host id", virtualHost.getId()); + } + + private ConfiguredObjectRecord createMockVirtualHostCOR(UUID virtualHostId) + { + Map virtualHostAttributes = new HashMap(); + virtualHostAttributes.put(VirtualHost.NAME, TEST_VIRTUAL_HOST_NAME); + virtualHostAttributes.put(VirtualHost.TYPE, StandardVirtualHost.TYPE); + virtualHostAttributes.put(VirtualHost.MODEL_VERSION, BrokerModel.MODEL_VERSION); + Map messageStoreSettings = new HashMap(); + virtualHostAttributes.put(VirtualHost.MESSAGE_STORE_SETTINGS, messageStoreSettings); + messageStoreSettings.put(MessageStore.STORE_TYPE, TestMemoryMessageStore.TYPE); + + ConfiguredObjectRecord record = mock(ConfiguredObjectRecord.class); + when(record.getId()).thenReturn(virtualHostId); + when(record.getAttributes()).thenReturn(virtualHostAttributes); + when(record.getType()).thenReturn(VirtualHost.class.getSimpleName()); + return record; + } +} diff --git a/java/broker-core/src/test/java/org/apache/qpid/server/virtualhostnode/TestVirtualHostNode.java b/java/broker-core/src/test/java/org/apache/qpid/server/virtualhostnode/TestVirtualHostNode.java new file mode 100644 index 0000000000..e129ce778f --- /dev/null +++ b/java/broker-core/src/test/java/org/apache/qpid/server/virtualhostnode/TestVirtualHostNode.java @@ -0,0 +1,85 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.server.virtualhostnode; + +import java.util.Collections; +import java.util.Map; + +import org.apache.qpid.server.configuration.updater.TaskExecutor; +import org.apache.qpid.server.model.Broker; +import org.apache.qpid.server.model.ManagedObject; +import org.apache.qpid.server.plugin.DurableConfigurationStoreFactory; +import org.apache.qpid.server.store.DurableConfigurationStore; +import org.apache.qpid.server.store.MessageStore; +import org.apache.qpid.server.store.TestMemoryMessageStore; +import org.apache.qpid.server.store.TestMemoryMessageStoreFactory; +@ManagedObject(type="TestMemory", category=false) +public class TestVirtualHostNode extends AbstractStandardVirtualHostNode +{ + private final DurableConfigurationStore _store; + + public TestVirtualHostNode(Broker parent, Map attributes, TaskExecutor taskExecutor) + { + this(parent, attributes, taskExecutor, null); + } + + public TestVirtualHostNode(Broker parent, Map attributes, TaskExecutor taskExecutor, DurableConfigurationStore store) + { + super(parent, attributes, taskExecutor); + _store = store; + } + + @Override + protected DurableConfigurationStoreFactory getDurableConfigurationStoreFactory() + { + if (_store != null) + { + return new DurableConfigurationStoreFactory() + { + + @Override + public void validateConfigurationStoreSettings(Map attributes) + { + } + + @Override + public String getType() + { + return null; + } + + @Override + public DurableConfigurationStore createDurableConfigurationStore() + { + return _store; + } + }; + } + + return new TestMemoryMessageStoreFactory(); + } + + @Override + public Map getDefaultMessageStoreSettings() + { + return Collections.singletonMap(MessageStore.STORE_TYPE, TestMemoryMessageStore.TYPE); + } +} \ No newline at end of file diff --git a/java/broker-core/src/test/java/org/apache/qpid/server/virtualhostnode/TestVirtualHostNodeFactory.java b/java/broker-core/src/test/java/org/apache/qpid/server/virtualhostnode/TestVirtualHostNodeFactory.java new file mode 100644 index 0000000000..2f21c21e67 --- /dev/null +++ b/java/broker-core/src/test/java/org/apache/qpid/server/virtualhostnode/TestVirtualHostNodeFactory.java @@ -0,0 +1,43 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.server.virtualhostnode; + +import java.util.Map; + +import org.apache.qpid.server.model.AbstractConfiguredObjectTypeFactory; +import org.apache.qpid.server.model.Broker; +import org.apache.qpid.server.model.ConfiguredObject; + +public class TestVirtualHostNodeFactory extends AbstractConfiguredObjectTypeFactory +{ + public TestVirtualHostNodeFactory() + { + super(TestVirtualHostNode.class); + } + + @Override + public TestVirtualHostNode createInstance(Map attributes, ConfiguredObject... parents) + { + Broker broker = getParent(Broker.class, parents); + return new TestVirtualHostNode(broker, attributes, broker.getTaskExecutor()); + } + +} diff --git a/java/broker-core/src/test/resources/META-INF/services/org.apache.qpid.server.plugin.ConfiguredObjectTypeFactory b/java/broker-core/src/test/resources/META-INF/services/org.apache.qpid.server.plugin.ConfiguredObjectTypeFactory new file mode 100644 index 0000000000..58b646abbf --- /dev/null +++ b/java/broker-core/src/test/resources/META-INF/services/org.apache.qpid.server.plugin.ConfiguredObjectTypeFactory @@ -0,0 +1,20 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# +org.apache.qpid.server.virtualhostnode.TestVirtualHostNodeFactory + diff --git a/java/broker-core/src/test/resources/META-INF/services/org.apache.qpid.server.plugin.DurableConfigurationStoreFactory b/java/broker-core/src/test/resources/META-INF/services/org.apache.qpid.server.plugin.DurableConfigurationStoreFactory new file mode 100644 index 0000000000..9512fb8117 --- /dev/null +++ b/java/broker-core/src/test/resources/META-INF/services/org.apache.qpid.server.plugin.DurableConfigurationStoreFactory @@ -0,0 +1,19 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# +org.apache.qpid.server.store.TestMemoryMessageStoreFactory diff --git a/java/broker-plugins/derby-store/src/main/java/org/apache/qpid/server/store/derby/DerbyMessageStoreFactory.java b/java/broker-plugins/derby-store/src/main/java/org/apache/qpid/server/store/derby/DerbyMessageStoreFactory.java index e7a330102e..75711547e1 100644 --- a/java/broker-plugins/derby-store/src/main/java/org/apache/qpid/server/store/derby/DerbyMessageStoreFactory.java +++ b/java/broker-plugins/derby-store/src/main/java/org/apache/qpid/server/store/derby/DerbyMessageStoreFactory.java @@ -66,8 +66,11 @@ public class DerbyMessageStoreFactory implements MessageStoreFactory, DurableCon } } - @SuppressWarnings("unchecked") - Map configurationStoreSettings = (Map) attributes.get(VirtualHost.CONFIGURATION_STORE_SETTINGS); + } + + @Override + public void validateConfigurationStoreSettings(Map configurationStoreSettings) + { if(configurationStoreSettings != null && getType().equals(configurationStoreSettings.get(DurableConfigurationStore.STORE_TYPE))) { Object storePath = configurationStoreSettings.get(DurableConfigurationStore.STORE_PATH); diff --git a/java/broker-plugins/derby-store/src/main/java/org/apache/qpid/server/virtualhostnode/derby/DerbyVirtualHostNode.java b/java/broker-plugins/derby-store/src/main/java/org/apache/qpid/server/virtualhostnode/derby/DerbyVirtualHostNode.java new file mode 100644 index 0000000000..f01391c0bf --- /dev/null +++ b/java/broker-plugins/derby-store/src/main/java/org/apache/qpid/server/virtualhostnode/derby/DerbyVirtualHostNode.java @@ -0,0 +1,63 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT 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.virtualhostnode.derby; + +import java.util.Map; + +import org.apache.qpid.server.configuration.updater.TaskExecutor; +import org.apache.qpid.server.model.Broker; +import org.apache.qpid.server.model.ManagedAttributeField; +import org.apache.qpid.server.model.ManagedObject; +import org.apache.qpid.server.plugin.DurableConfigurationStoreFactory; +import org.apache.qpid.server.store.derby.DerbyMessageStoreFactory; +import org.apache.qpid.server.virtualhostnode.AbstractStandardVirtualHostNode; +import org.apache.qpid.server.virtualhostnode.FileBasedVirtualHostNode; + +@ManagedObject( category = false, type = "DERBY" ) +public class DerbyVirtualHostNode extends AbstractStandardVirtualHostNode implements FileBasedVirtualHostNode +{ + @ManagedAttributeField + private String _storePath; + + public DerbyVirtualHostNode(Broker parent, Map attributes, TaskExecutor taskExecutor) + { + super(parent, attributes, taskExecutor); + } + + @Override + protected DurableConfigurationStoreFactory getDurableConfigurationStoreFactory() + { + return new DerbyMessageStoreFactory(); + } + + @Override + public String getStorePath() + { + return _storePath; + } + + @Override + public String toString() + { + return getClass().getSimpleName() + " [id=" + getId() + ", name=" + getName() + ", storePath=" + getStorePath() + "]"; + } +} diff --git a/java/broker-plugins/derby-store/src/main/java/org/apache/qpid/server/virtualhostnode/derby/DerbyVirtualHostNodeFactory.java b/java/broker-plugins/derby-store/src/main/java/org/apache/qpid/server/virtualhostnode/derby/DerbyVirtualHostNodeFactory.java new file mode 100644 index 0000000000..7b01511036 --- /dev/null +++ b/java/broker-plugins/derby-store/src/main/java/org/apache/qpid/server/virtualhostnode/derby/DerbyVirtualHostNodeFactory.java @@ -0,0 +1,45 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT 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.virtualhostnode.derby; + +import java.util.Map; + +import org.apache.qpid.server.model.AbstractConfiguredObjectTypeFactory; +import org.apache.qpid.server.model.Broker; +import org.apache.qpid.server.model.ConfiguredObject; + +public class DerbyVirtualHostNodeFactory extends AbstractConfiguredObjectTypeFactory +{ + + public DerbyVirtualHostNodeFactory() + { + super(DerbyVirtualHostNode.class); + } + + @Override + public DerbyVirtualHostNode createInstance(Map attributes, ConfiguredObject... parents) + { + Broker broker = getParent(Broker.class, parents); + return new DerbyVirtualHostNode(broker, attributes, broker.getTaskExecutor()); + } + +} diff --git a/java/broker-plugins/derby-store/src/main/resources/META-INF/services/org.apache.qpid.server.plugin.ConfiguredObjectTypeFactory b/java/broker-plugins/derby-store/src/main/resources/META-INF/services/org.apache.qpid.server.plugin.ConfiguredObjectTypeFactory new file mode 100644 index 0000000000..9a942db521 --- /dev/null +++ b/java/broker-plugins/derby-store/src/main/resources/META-INF/services/org.apache.qpid.server.plugin.ConfiguredObjectTypeFactory @@ -0,0 +1,19 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# +org.apache.qpid.server.virtualhostnode.derby.DerbyVirtualHostNodeFactory diff --git a/java/broker-plugins/jdbc-store/src/main/java/org/apache/qpid/server/store/jdbc/JDBCMessageStore.java b/java/broker-plugins/jdbc-store/src/main/java/org/apache/qpid/server/store/jdbc/JDBCMessageStore.java index 509184d243..037b9ee037 100644 --- a/java/broker-plugins/jdbc-store/src/main/java/org/apache/qpid/server/store/jdbc/JDBCMessageStore.java +++ b/java/broker-plugins/jdbc-store/src/main/java/org/apache/qpid/server/store/jdbc/JDBCMessageStore.java @@ -51,11 +51,11 @@ public class JDBCMessageStore extends AbstractJDBCMessageStore implements Messag public static final String TYPE = "JDBC"; public static final String CONNECTION_URL = "connectionURL"; - public static final String CONNECTION_POOL = "connectionPool"; - public static final String JDBC_BIG_INT_TYPE = "jdbcBigIntType"; - public static final String JDBC_BYTES_FOR_BLOB = "jdbcBytesForBlob"; - public static final String JDBC_VARBINARY_TYPE = "jdbcVarbinaryType"; - public static final String JDBC_BLOB_TYPE = "jdbcBlobType"; + public static final String CONNECTION_POOL_TYPE = "connectionPoolType"; + public static final String JDBC_BIG_INT_TYPE = "bigIntType"; + public static final String JDBC_BYTES_FOR_BLOB = "bytesForBlob"; + public static final String JDBC_VARBINARY_TYPE = "varbinaryType"; + public static final String JDBC_BLOB_TYPE = "blobType"; protected String _connectionURL; private ConnectionProvider _connectionProvider; @@ -290,7 +290,7 @@ public class JDBCMessageStore extends AbstractJDBCMessageStore implements Messag throws ClassNotFoundException, SQLException { _connectionURL = String.valueOf(storeSettings.get(CONNECTION_URL)); - Object poolAttribute = storeSettings.get(CONNECTION_POOL); + Object poolAttribute = storeSettings.get(CONNECTION_POOL_TYPE); JDBCDetails details = null; diff --git a/java/broker-plugins/jdbc-store/src/main/java/org/apache/qpid/server/store/jdbc/JDBCMessageStoreFactory.java b/java/broker-plugins/jdbc-store/src/main/java/org/apache/qpid/server/store/jdbc/JDBCMessageStoreFactory.java index acce1b75a2..b5a9d64a04 100644 --- a/java/broker-plugins/jdbc-store/src/main/java/org/apache/qpid/server/store/jdbc/JDBCMessageStoreFactory.java +++ b/java/broker-plugins/jdbc-store/src/main/java/org/apache/qpid/server/store/jdbc/JDBCMessageStoreFactory.java @@ -64,9 +64,11 @@ public class JDBCMessageStoreFactory implements MessageStoreFactory, DurableConf } } + } - @SuppressWarnings("unchecked") - Map configurationStoreSettings = (Map) attributes.get(VirtualHost.CONFIGURATION_STORE_SETTINGS); + @Override + public void validateConfigurationStoreSettings(Map configurationStoreSettings) + { if(configurationStoreSettings != null && getType().equals(configurationStoreSettings.get(DurableConfigurationStore.STORE_TYPE))) { Object connectionURL = configurationStoreSettings.get(JDBCMessageStore.CONNECTION_URL); diff --git a/java/broker-plugins/jdbc-store/src/main/java/org/apache/qpid/server/virtualhostnode/jdbc/JDBCVirtualHostNode.java b/java/broker-plugins/jdbc-store/src/main/java/org/apache/qpid/server/virtualhostnode/jdbc/JDBCVirtualHostNode.java new file mode 100644 index 0000000000..e6e4f960d8 --- /dev/null +++ b/java/broker-plugins/jdbc-store/src/main/java/org/apache/qpid/server/virtualhostnode/jdbc/JDBCVirtualHostNode.java @@ -0,0 +1,48 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.server.virtualhostnode.jdbc; + +import org.apache.qpid.server.model.ManagedAttribute; +import org.apache.qpid.server.store.jdbc.DefaultConnectionProviderFactory; + + +public interface JDBCVirtualHostNode +{ + //TODO: Split this attribute into connectionUrl, username and password. Make the password attribute secure. + @ManagedAttribute(automate=true, mandatory=true) + String getConnectionUrl(); + + @ManagedAttribute(automate=true, defaultValue=DefaultConnectionProviderFactory.TYPE) + String getConnectionPoolType(); + + @ManagedAttribute(automate=true) + String getBigIntType(); + + @ManagedAttribute(automate=true) + boolean isBytesForBlob(); + + @ManagedAttribute(automate=true) + String getVarBinaryType(); + + @ManagedAttribute(automate=true) + String getBlobType(); + +} \ No newline at end of file diff --git a/java/broker-plugins/jdbc-store/src/main/java/org/apache/qpid/server/virtualhostnode/jdbc/JDBCVirtualHostNodeFactory.java b/java/broker-plugins/jdbc-store/src/main/java/org/apache/qpid/server/virtualhostnode/jdbc/JDBCVirtualHostNodeFactory.java new file mode 100644 index 0000000000..aa3c38ce65 --- /dev/null +++ b/java/broker-plugins/jdbc-store/src/main/java/org/apache/qpid/server/virtualhostnode/jdbc/JDBCVirtualHostNodeFactory.java @@ -0,0 +1,44 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ + +package org.apache.qpid.server.virtualhostnode.jdbc; + +import java.util.Map; + +import org.apache.qpid.server.model.AbstractConfiguredObjectTypeFactory; +import org.apache.qpid.server.model.Broker; +import org.apache.qpid.server.model.ConfiguredObject; + +public class JDBCVirtualHostNodeFactory extends AbstractConfiguredObjectTypeFactory +{ + public JDBCVirtualHostNodeFactory() + { + super(JDBCVirtualHostNodeImpl.class); + } + + @Override + public JDBCVirtualHostNodeImpl createInstance(Map attributes, ConfiguredObject... parents) + { + Broker broker = getParent(Broker.class, parents); + return new JDBCVirtualHostNodeImpl(broker, attributes, broker.getTaskExecutor()); + } + +} diff --git a/java/broker-plugins/jdbc-store/src/main/java/org/apache/qpid/server/virtualhostnode/jdbc/JDBCVirtualHostNodeImpl.java b/java/broker-plugins/jdbc-store/src/main/java/org/apache/qpid/server/virtualhostnode/jdbc/JDBCVirtualHostNodeImpl.java new file mode 100644 index 0000000000..2a1279e74b --- /dev/null +++ b/java/broker-plugins/jdbc-store/src/main/java/org/apache/qpid/server/virtualhostnode/jdbc/JDBCVirtualHostNodeImpl.java @@ -0,0 +1,103 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT 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.virtualhostnode.jdbc; + +import java.util.Map; + +import org.apache.qpid.server.configuration.updater.TaskExecutor; +import org.apache.qpid.server.model.Broker; +import org.apache.qpid.server.model.ManagedAttribute; +import org.apache.qpid.server.model.ManagedAttributeField; +import org.apache.qpid.server.model.ManagedObject; +import org.apache.qpid.server.plugin.DurableConfigurationStoreFactory; +import org.apache.qpid.server.store.jdbc.JDBCMessageStore; +import org.apache.qpid.server.store.jdbc.JDBCMessageStoreFactory; +import org.apache.qpid.server.virtualhostnode.AbstractStandardVirtualHostNode; + +@ManagedObject( category = false, type = "JDBC" ) +public class JDBCVirtualHostNodeImpl extends AbstractStandardVirtualHostNode implements JDBCVirtualHostNode +{ + @ManagedAttributeField + private String _connectionUrl; + + @ManagedAttributeField + private String _connectionPoolType; + + @ManagedAttributeField + private String _bigIntType; + + @ManagedAttributeField + private boolean _bytesForBlob; + + @ManagedAttributeField + private String _varBinaryType; + + @ManagedAttributeField + private String _blobType; + + public JDBCVirtualHostNodeImpl(Broker parent, Map attributes, TaskExecutor taskExecutor) + { + super(parent, attributes, taskExecutor); + } + + @Override + protected DurableConfigurationStoreFactory getDurableConfigurationStoreFactory() + { + return new JDBCMessageStoreFactory(); + } + + @Override + public String getConnectionUrl() + { + return _connectionUrl; + } + + @Override + public String getConnectionPoolType() + { + return _connectionPoolType; + } + + @Override + public String getBigIntType() + { + return _bigIntType; + } + + @Override + public boolean isBytesForBlob() + { + return _bytesForBlob; + } + + @Override + public String getVarBinaryType() + { + return _varBinaryType; + } + + @Override + public String getBlobType() + { + return _blobType; + } + +} diff --git a/java/broker-plugins/jdbc-store/src/main/resources/META-INF/services/org.apache.qpid.server.plugin.ConfiguredObjectTypeFactory b/java/broker-plugins/jdbc-store/src/main/resources/META-INF/services/org.apache.qpid.server.plugin.ConfiguredObjectTypeFactory new file mode 100644 index 0000000000..03e3a963a5 --- /dev/null +++ b/java/broker-plugins/jdbc-store/src/main/resources/META-INF/services/org.apache.qpid.server.plugin.ConfiguredObjectTypeFactory @@ -0,0 +1,19 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# +org.apache.qpid.server.virtualhostnode.jdbc.JDBCVirtualHostNodeFactory diff --git a/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/HttpManagement.java b/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/HttpManagement.java index b72ecb950d..b9651c2d8f 100644 --- a/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/HttpManagement.java +++ b/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/HttpManagement.java @@ -320,24 +320,26 @@ public class HttpManagement extends AbstractPluginAdapter implem root.addFilter(new FilterHolder(new RedirectingAuthorisationFilter()), "/", EnumSet.of(DispatcherType.REQUEST)); addRestServlet(root, "broker"); - addRestServlet(root, "virtualhost", VirtualHost.class); + addRestServlet(root, "virtualhostnode", VirtualHostNode.class); addRestServlet(root, "authenticationprovider", AuthenticationProvider.class); addRestServlet(root, "accesscontrolprovider", AccessControlProvider.class); addRestServlet(root, "user", AuthenticationProvider.class, User.class); addRestServlet(root, "groupprovider", GroupProvider.class); addRestServlet(root, "group", GroupProvider.class, Group.class); addRestServlet(root, "groupmember", GroupProvider.class, Group.class, GroupMember.class); - addRestServlet(root, "exchange", VirtualHost.class, Exchange.class); - addRestServlet(root, "queue", VirtualHost.class, Queue.class); - addRestServlet(root, "connection", VirtualHost.class, Connection.class); - addRestServlet(root, "binding", VirtualHost.class, Exchange.class, Queue.class, Binding.class); addRestServlet(root, "port", Port.class); - addRestServlet(root, "session", VirtualHost.class, Connection.class, Session.class); addRestServlet(root, "keystore", KeyStore.class); addRestServlet(root, "truststore", TrustStore.class); addRestServlet(root, "plugin", Plugin.class); addRestServlet(root, "preferencesprovider", AuthenticationProvider.class, PreferencesProvider.class); + addRestServlet(root, "virtualhost", VirtualHostNode.class, VirtualHost.class); + addRestServlet(root, "exchange", VirtualHostNode.class, VirtualHost.class, Exchange.class); + addRestServlet(root, "queue", VirtualHostNode.class, VirtualHost.class, Queue.class); + addRestServlet(root, "connection", VirtualHostNode.class, VirtualHost.class, Connection.class); + addRestServlet(root, "binding", VirtualHostNode.class, VirtualHost.class, Exchange.class, Queue.class, Binding.class); + addRestServlet(root, "session", VirtualHostNode.class, VirtualHost.class, Connection.class, Session.class); + root.addServlet(new ServletHolder(new UserPreferencesServlet()), "/rest/userpreferences/*"); root.addServlet(new ServletHolder(new LoggedOnUserPreferencesServlet()), "/rest/preferences"); root.addServlet(new ServletHolder(new StructureServlet()), "/rest/structure"); diff --git a/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/rest/MessageContentServlet.java b/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/rest/MessageContentServlet.java index 7aa86313b2..074ca865a6 100644 --- a/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/rest/MessageContentServlet.java +++ b/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/rest/MessageContentServlet.java @@ -77,17 +77,11 @@ public class MessageContentServlet extends AbstractServlet String vhostName = pathInfoElements[0]; String queueName = pathInfoElements[1]; - VirtualHost vhost = null; - - for(VirtualHost vh : getBroker().getVirtualHosts()) + VirtualHost vhost = getBroker().findVirtualHostByName(vhostName); + if (vhost == null) { - if(vh.getName().equals(vhostName)) - { - vhost = vh; - break; - } + throw new IllegalArgumentException("Could not find virtual host with name '" + vhostName + "'"); } - return getQueueFromVirtualHost(queueName, vhost); } diff --git a/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/rest/MessageServlet.java b/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/rest/MessageServlet.java index f72471b7d4..3ee53ad892 100644 --- a/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/rest/MessageServlet.java +++ b/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/rest/MessageServlet.java @@ -33,7 +33,6 @@ import javax.servlet.http.HttpServletResponse; import org.apache.log4j.Logger; import org.codehaus.jackson.map.ObjectMapper; import org.codehaus.jackson.map.SerializationConfig; - import org.apache.qpid.server.consumer.ConsumerImpl; import org.apache.qpid.server.message.AMQMessageHeader; import org.apache.qpid.server.message.MessageReference; @@ -135,15 +134,10 @@ public class MessageServlet extends AbstractServlet String vhostName = pathInfoElements[0]; String queueName = pathInfoElements[1]; - VirtualHost vhost = null; - - for(VirtualHost vh : getBroker().getVirtualHosts()) + VirtualHost vhost = getBroker().findVirtualHostByName(vhostName); + if (vhost == null) { - if(vh.getName().equals(vhostName)) - { - vhost = vh; - break; - } + throw new IllegalArgumentException("Could not find virtual host with name '" + vhostName + "'"); } return getQueueFromVirtualHost(queueName, vhost); diff --git a/java/broker-plugins/management-jmx/src/main/java/org/apache/qpid/server/jmx/JMXManagementPluginImpl.java b/java/broker-plugins/management-jmx/src/main/java/org/apache/qpid/server/jmx/JMXManagementPluginImpl.java index 9ece703973..82aa806bba 100644 --- a/java/broker-plugins/management-jmx/src/main/java/org/apache/qpid/server/jmx/JMXManagementPluginImpl.java +++ b/java/broker-plugins/management-jmx/src/main/java/org/apache/qpid/server/jmx/JMXManagementPluginImpl.java @@ -31,7 +31,6 @@ import java.util.Set; import javax.management.JMException; import org.apache.log4j.Logger; - import org.apache.qpid.server.configuration.IllegalConfigurationException; import org.apache.qpid.server.jmx.mbeans.LoggingManagementMBean; import org.apache.qpid.server.jmx.mbeans.ServerInformationMBean; @@ -49,6 +48,7 @@ import org.apache.qpid.server.model.Port; import org.apache.qpid.server.model.Protocol; import org.apache.qpid.server.model.State; import org.apache.qpid.server.model.VirtualHost; +import org.apache.qpid.server.model.VirtualHostNode; import org.apache.qpid.server.model.adapter.AbstractPluginAdapter; import org.apache.qpid.server.plugin.QpidServiceLoader; import org.apache.qpid.server.util.ServerScopedRuntimeException; @@ -74,6 +74,7 @@ public class JMXManagementPluginImpl private JMXManagedObjectRegistry _objectRegistry; + private final Object _childrenLock = new Object(); private final Map _children = new HashMap(); @ManagedAttributeField @@ -142,25 +143,25 @@ public class JMXManagementPluginImpl broker.addChangeListener(this); - synchronized (_children) + synchronized (_childrenLock) { - for(VirtualHost virtualHost : broker.getVirtualHosts()) + for(VirtualHostNode virtualHostNode : broker.getVirtualHostNodes()) { - if(!_children.containsKey(virtualHost)) + virtualHostNode.addChangeListener(this); + + // Virtualhostnodes may or may not have a virtualhost at this point. In the HA + // case, JE may spontaneously make the node a master causing it to create a virtualhost. + // Creation of the vhost uses the task executor (same thread that executes this code + // so there is no potential for a race here). + VirtualHost host = virtualHostNode.getVirtualHost(); + if (host != null) { - if(LOGGER.isDebugEnabled()) - { - LOGGER.debug("Create MBean for virtual host:" + virtualHost.getName()); - } - VirtualHostMBean mbean = new VirtualHostMBean(virtualHost, _objectRegistry); - - if(LOGGER.isDebugEnabled()) - { - LOGGER.debug("Check for additional MBeans for virtual host:" + virtualHost.getName()); - } - createAdditionalMBeansFromProviders(virtualHost, mbean); + VirtualHostMBean mbean = new VirtualHostMBean(host, _objectRegistry); + _children.put(host, mbean); } + createAdditionalMBeansFromProviders(virtualHostNode, _objectRegistry); } + Collection> authenticationProviders = broker.getAuthenticationProviders(); for (AuthenticationProvider authenticationProvider : authenticationProviders) { @@ -171,6 +172,7 @@ public class JMXManagementPluginImpl _objectRegistry); _children.put(authenticationProvider, mbean); } + createAdditionalMBeansFromProviders(authenticationProvider, _objectRegistry); } } new Shutdown(_objectRegistry); @@ -182,6 +184,13 @@ public class JMXManagementPluginImpl _objectRegistry.start(); } + @Override + protected void onOpen() + { + super.onOpen(); + + } + private boolean isConnectorPort(Port port) { return port.getAvailableProtocols().contains(Protocol.JMX_RMI); @@ -194,7 +203,7 @@ public class JMXManagementPluginImpl private void stop() { - synchronized (_children) + synchronized (_childrenLock) { for(ConfiguredObject object : _children.keySet()) { @@ -227,11 +236,16 @@ public class JMXManagementPluginImpl @Override public void childAdded(ConfiguredObject object, ConfiguredObject child) { - synchronized (_children) + + synchronized (_childrenLock) { try { AMQManagedObject mbean; + if (child instanceof VirtualHostNode) + { + child.addChangeListener(this); + } if(child instanceof VirtualHost) { VirtualHost vhostChild = (VirtualHost)child; @@ -248,8 +262,9 @@ public class JMXManagementPluginImpl if (mbean != null) { - createAdditionalMBeansFromProviders(child, mbean); + _children.put(child, mbean); } + createAdditionalMBeansFromProviders(child, _objectRegistry); } catch(Exception e) { @@ -262,8 +277,10 @@ public class JMXManagementPluginImpl @Override public void childRemoved(ConfiguredObject object, ConfiguredObject child) { - synchronized (_children) + synchronized (_childrenLock) { + child.removeChangeListener(this); + AMQManagedObject mbean = _children.remove(child); if(mbean != null) { @@ -286,10 +303,8 @@ public class JMXManagementPluginImpl // no-op } - private void createAdditionalMBeansFromProviders(ConfiguredObject child, AMQManagedObject mbean) throws JMException + private void createAdditionalMBeansFromProviders(ConfiguredObject child, ManagedObjectRegistry registry) throws JMException { - _children.put(child, mbean); - QpidServiceLoader qpidServiceLoader = new QpidServiceLoader(); for (MBeanProvider provider : qpidServiceLoader.instancesOf(MBeanProvider.class)) { @@ -298,16 +313,22 @@ public class JMXManagementPluginImpl LOGGER.debug("Consulting mbean provider : " + provider + " for child : " + child); } + ManagedObject mBean = null; if (provider.isChildManageableByMBean(child)) { if(LOGGER.isDebugEnabled()) { LOGGER.debug("Provider will create mbean"); } - provider.createMBean(child, mbean); + mBean = provider.createMBean(child, registry); // TODO track the mbeans that have been created on behalf of a child in a map, then // if the child is ever removed, destroy these beans too. } + + if(LOGGER.isDebugEnabled()) + { + LOGGER.debug("Provider " + provider + " mBean for child " + child + " " + mBean); + } } } diff --git a/java/broker-plugins/management-jmx/src/main/java/org/apache/qpid/server/jmx/MBeanProvider.java b/java/broker-plugins/management-jmx/src/main/java/org/apache/qpid/server/jmx/MBeanProvider.java index a0ef052314..8817c16f83 100644 --- a/java/broker-plugins/management-jmx/src/main/java/org/apache/qpid/server/jmx/MBeanProvider.java +++ b/java/broker-plugins/management-jmx/src/main/java/org/apache/qpid/server/jmx/MBeanProvider.java @@ -22,7 +22,6 @@ package org.apache.qpid.server.jmx; import javax.management.JMException; -import javax.management.StandardMBean; import org.apache.qpid.server.model.ConfiguredObject; import org.apache.qpid.server.plugin.Pluggable; @@ -44,9 +43,10 @@ public interface MBeanProvider extends Pluggable /** * Creates a mbean for this child. This method should only be called if * {@link #isChildManageableByMBean(ConfiguredObject)} has previously returned true. + * @param registry managed object registry * * @return newly created mbean */ - StandardMBean createMBean(ConfiguredObject child, StandardMBean parent) throws JMException; + ManagedObject createMBean(ConfiguredObject child, ManagedObjectRegistry registry) throws JMException; } diff --git a/java/broker-plugins/memory-store/src/main/java/org/apache/qpid/server/store/MemoryMessageStoreFactory.java b/java/broker-plugins/memory-store/src/main/java/org/apache/qpid/server/store/MemoryMessageStoreFactory.java index db4cae1258..92f1e05870 100644 --- a/java/broker-plugins/memory-store/src/main/java/org/apache/qpid/server/store/MemoryMessageStoreFactory.java +++ b/java/broker-plugins/memory-store/src/main/java/org/apache/qpid/server/store/MemoryMessageStoreFactory.java @@ -22,9 +22,10 @@ package org.apache.qpid.server.store; import java.util.Map; +import org.apache.qpid.server.plugin.DurableConfigurationStoreFactory; import org.apache.qpid.server.plugin.MessageStoreFactory; -public class MemoryMessageStoreFactory implements MessageStoreFactory +public class MemoryMessageStoreFactory implements MessageStoreFactory, DurableConfigurationStoreFactory { @Override @@ -43,4 +44,15 @@ public class MemoryMessageStoreFactory implements MessageStoreFactory public void validateAttributes(Map attributes) { } + + @Override + public DurableConfigurationStore createDurableConfigurationStore() + { + return new MemoryMessageStore(); + } + + @Override + public void validateConfigurationStoreSettings(Map attributes) + { + } } diff --git a/java/broker-plugins/memory-store/src/main/java/org/apache/qpid/server/virtualhostnode/memory/MemoryVirtualHostNode.java b/java/broker-plugins/memory-store/src/main/java/org/apache/qpid/server/virtualhostnode/memory/MemoryVirtualHostNode.java new file mode 100644 index 0000000000..89c4851b38 --- /dev/null +++ b/java/broker-plugins/memory-store/src/main/java/org/apache/qpid/server/virtualhostnode/memory/MemoryVirtualHostNode.java @@ -0,0 +1,47 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.server.virtualhostnode.memory; + +import java.util.Map; + +import org.apache.qpid.server.configuration.updater.TaskExecutor; +import org.apache.qpid.server.model.Broker; +import org.apache.qpid.server.model.ManagedObject; +import org.apache.qpid.server.plugin.DurableConfigurationStoreFactory; +import org.apache.qpid.server.store.MemoryMessageStoreFactory; +import org.apache.qpid.server.virtualhostnode.AbstractStandardVirtualHostNode; + +@ManagedObject(type="Memory",category=false) +public class MemoryVirtualHostNode extends AbstractStandardVirtualHostNode +{ + + public MemoryVirtualHostNode(Broker parent, Map attributes, TaskExecutor taskExecutor) + { + super(parent, attributes, taskExecutor); + } + + @Override + public DurableConfigurationStoreFactory getDurableConfigurationStoreFactory() + { + return new MemoryMessageStoreFactory(); + } + +} diff --git a/java/broker-plugins/memory-store/src/main/java/org/apache/qpid/server/virtualhostnode/memory/MemoryVirtualHostNodeFactory.java b/java/broker-plugins/memory-store/src/main/java/org/apache/qpid/server/virtualhostnode/memory/MemoryVirtualHostNodeFactory.java new file mode 100644 index 0000000000..f19ff037de --- /dev/null +++ b/java/broker-plugins/memory-store/src/main/java/org/apache/qpid/server/virtualhostnode/memory/MemoryVirtualHostNodeFactory.java @@ -0,0 +1,44 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.server.virtualhostnode.memory; + +import java.util.Map; + +import org.apache.qpid.server.model.AbstractConfiguredObjectTypeFactory; +import org.apache.qpid.server.model.Broker; +import org.apache.qpid.server.model.ConfiguredObject; + +public class MemoryVirtualHostNodeFactory extends AbstractConfiguredObjectTypeFactory +{ + + public MemoryVirtualHostNodeFactory() + { + super(MemoryVirtualHostNode.class); + } + + @Override + protected MemoryVirtualHostNode createInstance(Map attributes, ConfiguredObject... parents) + { + Broker broker = getParent(Broker.class, parents); + return new MemoryVirtualHostNode(broker, attributes, broker.getTaskExecutor()); + } + +} diff --git a/java/broker-plugins/memory-store/src/main/resources/META-INF/services/org.apache.qpid.server.plugin.ConfiguredObjectTypeFactory b/java/broker-plugins/memory-store/src/main/resources/META-INF/services/org.apache.qpid.server.plugin.ConfiguredObjectTypeFactory new file mode 100644 index 0000000000..a29a1b43f9 --- /dev/null +++ b/java/broker-plugins/memory-store/src/main/resources/META-INF/services/org.apache.qpid.server.plugin.ConfiguredObjectTypeFactory @@ -0,0 +1,19 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# +org.apache.qpid.server.virtualhostnode.memory.MemoryVirtualHostNodeFactory diff --git a/java/common/src/main/java/org/apache/qpid/util/Strings.java b/java/common/src/main/java/org/apache/qpid/util/Strings.java index 3a1a619981..5b544014a3 100644 --- a/java/common/src/main/java/org/apache/qpid/util/Strings.java +++ b/java/common/src/main/java/org/apache/qpid/util/Strings.java @@ -227,6 +227,10 @@ public final class Strings private static final String expand(String input, Resolver resolver, Stack stack, boolean failOnUnresolved) { + if (input == null) + { + throw new IllegalArgumentException("Expansion input cannot be null"); + } Matcher m = VAR.matcher(input); StringBuffer result = new StringBuffer(); while (m.find()) diff --git a/java/qpid-test-utils/src/main/java/org/apache/qpid/test/utils/QpidTestCase.java b/java/qpid-test-utils/src/main/java/org/apache/qpid/test/utils/QpidTestCase.java index 7113f79829..f30e856ef4 100644 --- a/java/qpid-test-utils/src/main/java/org/apache/qpid/test/utils/QpidTestCase.java +++ b/java/qpid-test-utils/src/main/java/org/apache/qpid/test/utils/QpidTestCase.java @@ -157,6 +157,10 @@ public class QpidTestCase extends TestCase return storeType != null ? storeType : "TestableMemory"; } + public String getTestProfileVirtualHostNodeType() + { + return getTestProfileMessageStoreType(); + } public static final int MIN_PORT_NUMBER = 1; public static final int MAX_PORT_NUMBER = 49151; diff --git a/java/systests/etc/config-systests.json b/java/systests/etc/config-systests.json index dac8ee4fd4..b01399fbd8 100644 --- a/java/systests/etc/config-systests.json +++ b/java/systests/etc/config-systests.json @@ -22,7 +22,7 @@ "name": "Broker", "defaultVirtualHost" : "test", "storeVersion": 1, - "modelVersion": "1.4", + "modelVersion": "2.0", "authenticationproviders" : [ { "name" : "plain", "type" : "PlainPasswordFile", @@ -57,12 +57,10 @@ "port" : "${test.cport}", "protocols" : [ "JMX_RMI" ] }], - "virtualhosts" : [ { + "virtualhostnodes" : [ { "name" : "test", - "type" : "STANDARD", - "messageStoreSettings": { - "storeType": "${messagestore.type}", - "storePath" : "${QPID_WORK}/test/${test.port}" - } + "type" : "${messagestore.type}", + "messageStoreProvider": true, + "storePath" : "${QPID_WORK}/test/${test.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 index afc630296d..15ec0f9a4d 100644 --- 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 @@ -98,7 +98,7 @@ public class MultipleBrokersFailoverTest extends QpidBrokerTestCase implements C { host = NON_FAILOVER_VIRTUAL_HOST; } - createTestVirtualHost(port, host); + createTestVirtualHostNode(port, host); startBroker(port); revertSystemProperties(); 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 c5049467c9..31888167af 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 @@ -186,7 +186,7 @@ public class AlertingTest extends AbstractTestLogging setTestSystemProperty("queue.alertThresholdQueueDepthMessages","5"); brokerConfiguration.setSaved(false); - restTestHelper.submitRequest("/rest/queue/test/" + getTestQueueName(), "PUT", Collections.singletonMap(org.apache.qpid.server.model.Queue.ALERT_THRESHOLD_QUEUE_DEPTH_MESSAGES, 5)); + restTestHelper.submitRequest("/rest/queue/test/test/" + getTestQueueName(), "PUT", Collections.singletonMap(org.apache.qpid.server.model.Queue.ALERT_THRESHOLD_QUEUE_DEPTH_MESSAGES, 5)); // Trigger the new value sendMessage(_session, _destination, 3); _session.commit(); 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 1ecf43aa9b..165fbed00c 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 @@ -45,10 +45,10 @@ public class ExternalACLJMXTest extends AbstractACLTestCase public void setUp() throws Exception { //remove the normal 'test' vhost, we will configure the vhosts below - getBrokerConfiguration(0).removeObjectConfiguration(org.apache.qpid.server.model.VirtualHost.class, TestBrokerConfiguration.ENTRY_NAME_VIRTUAL_HOST); + getBrokerConfiguration(0).removeObjectConfiguration(org.apache.qpid.server.model.VirtualHostNode.class, TestBrokerConfiguration.ENTRY_NAME_VIRTUAL_HOST); - createTestVirtualHost(0, TEST_VHOST); - createTestVirtualHost(0, TEST2_VHOST); + createTestVirtualHostNode(0, TEST_VHOST); + createTestVirtualHostNode(0, TEST2_VHOST); getBrokerConfiguration().addJmxManagementConfiguration(); 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 f2e72be447..04b8385e69 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 @@ -39,6 +39,7 @@ import org.apache.qpid.exchange.ExchangeDefaults; import org.apache.qpid.framing.AMQShortString; import org.apache.qpid.server.model.Broker; import org.apache.qpid.server.model.VirtualHost; +import org.apache.qpid.server.model.VirtualHostNode; import org.apache.qpid.test.utils.QpidBrokerTestCase; import org.apache.qpid.test.utils.TestBrokerConfiguration; import org.apache.qpid.util.LogMonitor; @@ -66,14 +67,14 @@ public class StatisticsReportingTest extends QpidBrokerTestCase @Override public void setUp() throws Exception { - createTestVirtualHost(0, VHOST_NAME1); - createTestVirtualHost(0, VHOST_NAME2); - createTestVirtualHost(0, VHOST_NAME3); + createTestVirtualHostNode(0, VHOST_NAME1); + createTestVirtualHostNode(0, VHOST_NAME2); + createTestVirtualHostNode(0, VHOST_NAME3); if (getName().equals("testEnabledStatisticsReporting")) { TestBrokerConfiguration config = getBrokerConfiguration(); - config.removeObjectConfiguration(VirtualHost.class, TestBrokerConfiguration.ENTRY_NAME_VIRTUAL_HOST); + config.removeObjectConfiguration(VirtualHostNode.class, TestBrokerConfiguration.ENTRY_NAME_VIRTUAL_HOST); config.setBrokerAttribute(Broker.STATISTICS_REPORTING_PERIOD, STATISTICS_REPORTING_PERIOD_IN_SECONDS); } diff --git a/java/systests/src/main/java/org/apache/qpid/server/store/SplitStoreTest.java b/java/systests/src/main/java/org/apache/qpid/server/store/SplitStoreTest.java index 1b7f443705..6b93338f3f 100644 --- a/java/systests/src/main/java/org/apache/qpid/server/store/SplitStoreTest.java +++ b/java/systests/src/main/java/org/apache/qpid/server/store/SplitStoreTest.java @@ -31,9 +31,11 @@ import javax.jms.Queue; import javax.jms.Session; import org.apache.qpid.configuration.ClientProperties; -import org.apache.qpid.server.model.VirtualHost; +import org.apache.qpid.server.model.VirtualHostNode; import org.apache.qpid.test.utils.QpidBrokerTestCase; import org.apache.qpid.test.utils.TestBrokerConfiguration; +import org.apache.qpid.test.utils.TestFileUtils; +import org.apache.qpid.test.utils.TestUtils; import org.apache.qpid.util.FileUtils; public class SplitStoreTest extends QpidBrokerTestCase @@ -51,6 +53,19 @@ public class SplitStoreTest extends QpidBrokerTestCase _configStorePath = virtualHostWorkDir + "configStore"; } + @Override + protected void tearDown() throws Exception + { + try + { + super.tearDown(); + } + finally + { + TestFileUtils.delete(new File(_messageStorePath), true); + } + } + @Override public void startBroker() throws Exception { @@ -59,38 +74,32 @@ public class SplitStoreTest extends QpidBrokerTestCase public void testJsonConfigurationStoreWithPersistentMessageStore() throws Exception { - Map configurationStoreSettings = new HashMap(); - configurationStoreSettings.put(DurableConfigurationStore.STORE_TYPE, JsonFileConfigStore.TYPE); - configurationStoreSettings.put(DurableConfigurationStore.STORE_PATH, _configStorePath); - doTest(configurationStoreSettings); + doTest(JsonFileConfigStore.TYPE, _configStorePath); } public void testSeparateConfigurationAndMessageStoresOfTheSameType() throws Exception { - Map configurationStoreSettings = new HashMap(); - configurationStoreSettings.put(DurableConfigurationStore.STORE_TYPE, getTestProfileMessageStoreType()); - configurationStoreSettings.put(DurableConfigurationStore.STORE_PATH, _configStorePath); - - doTest(configurationStoreSettings); + doTest(getTestProfileVirtualHostNodeType(), _configStorePath); } - private void configureAndStartBroker(Map configurationStoreSettings) throws Exception + private void configureAndStartBroker(String nodeType, String storePath) throws Exception { + TestBrokerConfiguration config = getBrokerConfiguration(); + config.setObjectAttribute(VirtualHostNode.class, TestBrokerConfiguration.ENTRY_NAME_VIRTUAL_HOST, VirtualHostNode.TYPE, nodeType); + config.setObjectAttribute(VirtualHostNode.class, TestBrokerConfiguration.ENTRY_NAME_VIRTUAL_HOST, DurableConfigurationStore.STORE_PATH, storePath); + config.setObjectAttribute(VirtualHostNode.class, TestBrokerConfiguration.ENTRY_NAME_VIRTUAL_HOST, VirtualHostNode.IS_MESSAGE_STORE_PROVIDER, false); + Map messageStoreSettings = new HashMap(); messageStoreSettings.put(MessageStore.STORE_TYPE, getTestProfileMessageStoreType()); messageStoreSettings.put(MessageStore.STORE_PATH, _messageStorePath); - - TestBrokerConfiguration config = getBrokerConfiguration(); - config.setObjectAttribute(VirtualHost.class, TestBrokerConfiguration.ENTRY_NAME_VIRTUAL_HOST, VirtualHost.MESSAGE_STORE_SETTINGS, messageStoreSettings); - config.setObjectAttribute(VirtualHost.class, TestBrokerConfiguration.ENTRY_NAME_VIRTUAL_HOST, VirtualHost.CONFIGURATION_STORE_SETTINGS, configurationStoreSettings); - + TestUtils.createStoreWithVirtualHostEntry(messageStoreSettings, config, nodeType); super.startBroker(); } - private void doTest(Map configurationStoreSettings) throws Exception + private void doTest(String nodeType, String path) throws Exception { - configureAndStartBroker(configurationStoreSettings); + configureAndStartBroker(nodeType, path); Connection connection = getConnection(); Session session = connection.createSession(true, Session.SESSION_TRANSACTED); 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 25a3571787..67484ce01b 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 @@ -20,6 +20,7 @@ */ package org.apache.qpid.server.store; +import java.io.File; import java.util.HashMap; import java.util.Map; import java.util.concurrent.CountDownLatch; @@ -39,9 +40,9 @@ import org.apache.qpid.client.AMQDestination; import org.apache.qpid.client.AMQQueue; import org.apache.qpid.client.AMQSession; import org.apache.qpid.exchange.ExchangeDefaults; -import org.apache.qpid.server.model.VirtualHost; import org.apache.qpid.test.utils.QpidBrokerTestCase; -import org.apache.qpid.test.utils.TestBrokerConfiguration; +import org.apache.qpid.test.utils.TestUtils; +import org.apache.qpid.util.FileUtils; public class StoreOverfullTest extends QpidBrokerTestCase { @@ -59,9 +60,12 @@ public class StoreOverfullTest extends QpidBrokerTestCase private MessageConsumer _consumer; private Queue _queue; + private String _storePath; + private static final int OVERFULL_SIZE = 400000; private static final int UNDERFULL_SIZE = 350000; + @Override public void setUp() throws Exception { Map messageStoreSettings = new HashMap(); @@ -69,8 +73,7 @@ public class StoreOverfullTest extends QpidBrokerTestCase messageStoreSettings.put(MessageStore.OVERFULL_SIZE, OVERFULL_SIZE); messageStoreSettings.put(MessageStore.UNDERFULL_SIZE, UNDERFULL_SIZE); - TestBrokerConfiguration config = getBrokerConfiguration(); - config.setObjectAttribute(VirtualHost.class, TestBrokerConfiguration.ENTRY_NAME_VIRTUAL_HOST, VirtualHost.MESSAGE_STORE_SETTINGS, messageStoreSettings); + _storePath = TestUtils.createStoreWithVirtualHostEntry(messageStoreSettings, getBrokerConfiguration(), getTestProfileVirtualHostNodeType()); super.setUp(); @@ -93,7 +96,17 @@ public class StoreOverfullTest extends QpidBrokerTestCase } finally { - super.tearDown(); + try + { + super.tearDown(); + } + finally + { + if (_storePath != null) + { + FileUtils.delete(new File(_storePath), true); + } + } } } diff --git a/java/systests/src/main/java/org/apache/qpid/server/store/VirtualHostMessageStoreTest.java b/java/systests/src/main/java/org/apache/qpid/server/store/VirtualHostMessageStoreTest.java index 1b0f44af49..c016cf25c0 100644 --- a/java/systests/src/main/java/org/apache/qpid/server/store/VirtualHostMessageStoreTest.java +++ b/java/systests/src/main/java/org/apache/qpid/server/store/VirtualHostMessageStoreTest.java @@ -20,13 +20,15 @@ */ package org.apache.qpid.server.store; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + import java.io.File; import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; import java.util.Map; - -import org.apache.log4j.Logger; +import java.util.UUID; import org.apache.qpid.common.AMQPFilterTypes; import org.apache.qpid.framing.AMQShortString; @@ -35,16 +37,22 @@ import org.apache.qpid.framing.ContentHeaderBody; import org.apache.qpid.framing.FieldTable; import org.apache.qpid.framing.abstraction.MessagePublishInfo; import org.apache.qpid.framing.amqp_8_0.BasicConsumeBodyImpl; +import org.apache.qpid.server.configuration.updater.TaskExecutor; import org.apache.qpid.server.exchange.DirectExchange; import org.apache.qpid.server.exchange.ExchangeImpl; import org.apache.qpid.server.exchange.TopicExchange; import org.apache.qpid.server.message.InstanceProperties; import org.apache.qpid.server.message.MessageSource; import org.apache.qpid.server.model.Binding; +import org.apache.qpid.server.model.Broker; +import org.apache.qpid.server.model.ConfiguredObject; +import org.apache.qpid.server.model.ConfiguredObjectFactory; import org.apache.qpid.server.model.ExclusivityPolicy; import org.apache.qpid.server.model.LifetimePolicy; import org.apache.qpid.server.model.Queue; +import org.apache.qpid.server.model.State; import org.apache.qpid.server.model.UUIDGenerator; +import org.apache.qpid.server.model.VirtualHostNode; import org.apache.qpid.server.plugin.ExchangeType; import org.apache.qpid.server.protocol.v0_8.AMQMessage; import org.apache.qpid.server.protocol.v0_8.MessageMetaData; @@ -57,9 +65,8 @@ import org.apache.qpid.server.queue.StandardQueueImpl; import org.apache.qpid.server.txn.AutoCommitTransaction; import org.apache.qpid.server.txn.ServerTransaction; import org.apache.qpid.server.util.BrokerTestHelper; -import org.apache.qpid.server.virtualhost.AbstractVirtualHost; -import org.apache.qpid.server.virtualhost.StandardVirtualHost; import org.apache.qpid.server.virtualhost.VirtualHostImpl; +import org.apache.qpid.server.virtualhostnode.FileBasedVirtualHostNode; import org.apache.qpid.test.utils.QpidTestCase; import org.apache.qpid.util.FileUtils; @@ -73,7 +80,6 @@ import org.apache.qpid.util.FileUtils; */ public class VirtualHostMessageStoreTest extends QpidTestCase { - private static final Logger _logger = Logger.getLogger(VirtualHostMessageStoreTest.class); public static final int DEFAULT_PRIORTY_LEVEL = 5; public static final String SELECTOR_VALUE = "Test = 'MST'"; @@ -100,41 +106,36 @@ public class VirtualHostMessageStoreTest extends QpidTestCase private String queueOwner = "MST"; - private AbstractVirtualHost _virtualHost; + private VirtualHostImpl _virtualHost; private String _storePath; - private Map _attributes; + private VirtualHostNode _node; + private TaskExecutor _taskExecutor; public void setUp() throws Exception { super.setUp(); - BrokerTestHelper.setUp(); String hostName = getName(); _storePath = System.getProperty("QPID_WORK", TMP_FOLDER + File.separator + getTestName()) + File.separator + hostName; - - Map messageStoreSettings = new HashMap(); - messageStoreSettings.put(MessageStore.STORE_PATH, _storePath); - messageStoreSettings.put(MessageStore.STORE_TYPE, getTestProfileMessageStoreType()); - - _attributes = new HashMap(); - _attributes.put(org.apache.qpid.server.model.VirtualHost.MESSAGE_STORE_SETTINGS, messageStoreSettings); - _attributes.put(org.apache.qpid.server.model.VirtualHost.TYPE, StandardVirtualHost.TYPE); - _attributes.put(org.apache.qpid.server.model.VirtualHost.NAME, hostName); - - cleanup(new File(_storePath)); - reloadVirtualHost(); - } + Broker broker = BrokerTestHelper.createBrokerMock(); + _taskExecutor = new TaskExecutor(); + _taskExecutor.start(); + when(broker.getTaskExecutor()).thenReturn(_taskExecutor); - protected String getStorePath() - { - return _storePath; - } + ConfiguredObjectFactory factory = broker.getObjectFactory(); + Map nodeAttributes = new HashMap(); + nodeAttributes.put(ConfiguredObject.TYPE, getTestProfileVirtualHostNodeType()); + nodeAttributes.put(FileBasedVirtualHostNode.STORE_PATH, _storePath); + nodeAttributes.put(VirtualHostNode.IS_MESSAGE_STORE_PROVIDER, true); + nodeAttributes.put(VirtualHostNode.NAME, hostName); + nodeAttributes.put(VirtualHostNode.ID, UUID.randomUUID()); + _node = factory.create(VirtualHostNode.class, nodeAttributes, broker); + _node.setDesiredState(_node.getState(), State.ACTIVE); + + _virtualHost = (VirtualHostImpl)_node.getVirtualHost(); - protected org.apache.qpid.server.model.VirtualHost getVirtualHostModel() - { - return _virtualHost; } @Override @@ -144,54 +145,31 @@ public class VirtualHostMessageStoreTest extends QpidTestCase { if (_virtualHost != null) { - _virtualHost.close(); + VirtualHostNode node = _virtualHost.getParent(VirtualHostNode.class); + node.setDesiredState(node.getState(), State.STOPPED); } } finally { - BrokerTestHelper.tearDown(); + _taskExecutor.stopImmediately(); super.tearDown(); } } - public VirtualHostImpl getVirtualHost() - { - return _virtualHost; - } - protected void reloadVirtualHost() { - VirtualHostImpl original = getVirtualHost(); - - if (getVirtualHost() != null) - { - try - { - getVirtualHost().close(); - } - catch (Exception e) - { - _logger.error("Error closing virtual host", e); - fail(e.getMessage()); - } - } - - try - { - _virtualHost = (AbstractVirtualHost) BrokerTestHelper.createVirtualHost(_attributes); - } - catch (Exception e) - { - _logger.error("Error creating virtual host", e); - fail(e.getMessage()); - } + assertEquals("Virtual host node is not active", State.ACTIVE, _virtualHost.getState()); + State currentState = _node.setDesiredState(State.ACTIVE, State.STOPPED); + assertEquals("Virtual host node is not stopped", State.STOPPED, currentState); - assertTrue("Virtualhost has not changed, reload was not successful", original != getVirtualHost()); + currentState = _node.setDesiredState(State.STOPPED, State.ACTIVE); + assertEquals("Virtual host node is not active", State.ACTIVE, currentState); + _virtualHost = (VirtualHostImpl) _node.getVirtualHost(); } public void testQueueExchangeAndBindingCreation() throws Exception { - assertEquals("Should not be any existing queues", 0, getVirtualHost().getQueues().size()); + assertEquals("Should not be any existing queues", 0, _virtualHost.getQueues().size()); createAllQueues(); createAllTopicQueues(); @@ -229,7 +207,7 @@ public class VirtualHostMessageStoreTest extends QpidTestCase validateMessageOnTopics(2, true); assertEquals("Not all queues correctly registered", - 10, getVirtualHost().getQueues().size()); + 10, _virtualHost.getQueues().size()); } public void testMessagePersistence() throws Exception @@ -253,7 +231,7 @@ public class VirtualHostMessageStoreTest extends QpidTestCase testMessagePersistence(); assertEquals("Incorrect number of queues registered after recovery", - 6, getVirtualHost().getQueues().size()); + 6, _virtualHost.getQueues().size()); //clear the queue _virtualHost.getQueue(durableQueueName).clearQueue(); @@ -275,7 +253,7 @@ public class VirtualHostMessageStoreTest extends QpidTestCase public void testQueuePersistence() throws Exception { assertEquals("Should not be any existing queues", - 0, getVirtualHost().getQueues().size()); + 0, _virtualHost.getQueues().size()); //create durable and non durable queues/topics createAllQueues(); @@ -285,17 +263,17 @@ public class VirtualHostMessageStoreTest extends QpidTestCase reloadVirtualHost(); assertEquals("Incorrect number of queues registered after recovery", - 6, getVirtualHost().getQueues().size()); + 6, _virtualHost.getQueues().size()); //Validate the non-Durable Queues were not recovered. assertNull("Non-Durable queue still registered:" + priorityQueueName, - getVirtualHost().getQueue(priorityQueueName)); + _virtualHost.getQueue(priorityQueueName)); assertNull("Non-Durable queue still registered:" + queueName, - getVirtualHost().getQueue(queueName)); + _virtualHost.getQueue(queueName)); assertNull("Non-Durable queue still registered:" + priorityTopicQueueName, - getVirtualHost().getQueue(priorityTopicQueueName)); + _virtualHost.getQueue(priorityTopicQueueName)); assertNull("Non-Durable queue still registered:" + topicQueueName, - getVirtualHost().getQueue(topicQueueName)); + _virtualHost.getQueue(topicQueueName)); //Validate normally expected properties of Queues/Topics validateDurableQueueProperties(); @@ -316,23 +294,24 @@ public class VirtualHostMessageStoreTest extends QpidTestCase createQueue(durableQueueName, false, true, false, false); assertEquals("Incorrect number of queues registered before recovery", - 1, getVirtualHost().getQueues().size()); + 1, _virtualHost.getQueues().size()); reloadVirtualHost(); assertEquals("Incorrect number of queues registered after first recovery", - 1, getVirtualHost().getQueues().size()); + 1, _virtualHost.getQueues().size()); //test that removing the queue means it is not recovered next time - final AMQQueue queue = getVirtualHost().getQueue(durableQueueName); - getVirtualHost().getDurableConfigurationStore().remove(queue.asObjectRecord()); + + final AMQQueue queue = _virtualHost.getQueue(durableQueueName); + _virtualHost.getDurableConfigurationStore().remove(queue.asObjectRecord()); reloadVirtualHost(); assertEquals("Incorrect number of queues registered after second recovery", - 0, getVirtualHost().getQueues().size()); + 0, _virtualHost.getQueues().size()); assertNull("Durable queue was not removed:" + durableQueueName, - getVirtualHost().getQueue(durableQueueName)); + _virtualHost.getQueue(durableQueueName)); } /** @@ -342,12 +321,12 @@ public class VirtualHostMessageStoreTest extends QpidTestCase */ public void testExchangePersistence() throws Exception { - int origExchangeCount = getVirtualHost().getExchanges().size(); + int origExchangeCount = _virtualHost.getExchanges().size(); Map> oldExchanges = createExchanges(); assertEquals("Incorrect number of exchanges registered before recovery", - origExchangeCount + 3, getVirtualHost().getExchanges().size()); + origExchangeCount + 3, _virtualHost.getExchanges().size()); reloadVirtualHost(); @@ -362,28 +341,29 @@ public class VirtualHostMessageStoreTest extends QpidTestCase */ public void testDurableExchangeRemoval() throws Exception { - int origExchangeCount = getVirtualHost().getExchanges().size(); + int origExchangeCount = _virtualHost.getExchanges().size(); createExchange(DirectExchange.TYPE, directExchangeName, true); assertEquals("Incorrect number of exchanges registered before recovery", - origExchangeCount + 1, getVirtualHost().getExchanges().size()); + origExchangeCount + 1, _virtualHost.getExchanges().size()); reloadVirtualHost(); assertEquals("Incorrect number of exchanges registered after first recovery", - origExchangeCount + 1, getVirtualHost().getExchanges().size()); + origExchangeCount + 1, _virtualHost.getExchanges().size()); //test that removing the exchange means it is not recovered next time - final ExchangeImpl exchange = getVirtualHost().getExchange(directExchangeName); - getVirtualHost().getDurableConfigurationStore().remove(exchange.asObjectRecord()); + + final ExchangeImpl exchange = _virtualHost.getExchange(directExchangeName); + _virtualHost.getDurableConfigurationStore().remove(exchange.asObjectRecord()); reloadVirtualHost(); assertEquals("Incorrect number of exchanges registered after second recovery", - origExchangeCount, getVirtualHost().getExchanges().size()); + origExchangeCount, _virtualHost.getExchanges().size()); assertNull("Durable exchange was not removed:" + directExchangeName, - getVirtualHost().getExchange(directExchangeName)); + _virtualHost.getExchange(directExchangeName)); } /** @@ -394,7 +374,7 @@ public class VirtualHostMessageStoreTest extends QpidTestCase */ public void testBindingPersistence() throws Exception { - int origExchangeCount = getVirtualHost().getExchanges().size(); + int origExchangeCount = _virtualHost.getExchanges().size(); createAllQueues(); createAllTopicQueues(); @@ -410,7 +390,7 @@ public class VirtualHostMessageStoreTest extends QpidTestCase bindAllTopicQueuesToExchange(topicExchange, topicRouting); assertEquals("Incorrect number of exchanges registered before recovery", - origExchangeCount + 3, getVirtualHost().getExchanges().size()); + origExchangeCount + 3, _virtualHost.getExchanges().size()); reloadVirtualHost(); @@ -429,27 +409,27 @@ public class VirtualHostMessageStoreTest extends QpidTestCase //create durable queue and exchange, bind them ExchangeImpl exch = createExchange(DirectExchange.TYPE, directExchangeName, true); createQueue(durableQueueName, false, true, false, false); - bindQueueToExchange(exch, directRouting, getVirtualHost().getQueue(durableQueueName), false); + bindQueueToExchange(exch, directRouting, _virtualHost.getQueue(durableQueueName), false); assertEquals("Incorrect number of bindings registered before recovery", - 1, getVirtualHost().getQueue(durableQueueName).getBindings().size()); + 1, _virtualHost.getQueue(durableQueueName).getBindings().size()); //verify binding is actually normally recovered reloadVirtualHost(); assertEquals("Incorrect number of bindings registered after first recovery", - 1, getVirtualHost().getQueue(durableQueueName).getBindings().size()); + 1, _virtualHost.getQueue(durableQueueName).getBindings().size()); - exch = getVirtualHost().getExchange(directExchangeName); + exch = _virtualHost.getExchange(directExchangeName); assertNotNull("Exchange was not recovered", exch); //remove the binding and verify result after recovery - unbindQueueFromExchange(exch, directRouting, getVirtualHost().getQueue(durableQueueName), false); + unbindQueueFromExchange(exch, directRouting, _virtualHost.getQueue(durableQueueName), false); reloadVirtualHost(); assertEquals("Incorrect number of bindings registered after second recovery", - 0, getVirtualHost().getQueue(durableQueueName).getBindings().size()); + 0, _virtualHost.getQueue(durableQueueName).getBindings().size()); } /** @@ -459,7 +439,7 @@ public class VirtualHostMessageStoreTest extends QpidTestCase */ private void validateExchanges(int originalNumExchanges, Map> oldExchanges) { - Collection> exchanges = getVirtualHost().getExchanges(); + Collection> exchanges = (Collection>) _virtualHost.getExchanges(); Collection exchangeNames = new ArrayList(exchanges.size()); for(ExchangeImpl exchange : exchanges) { @@ -474,27 +454,26 @@ public class VirtualHostMessageStoreTest extends QpidTestCase //check the old exchange objects are not the same as the new exchanges assertTrue(directExchangeName + " exchange NOT reloaded", - getVirtualHost().getExchange(directExchangeName) != oldExchanges.get(directExchangeName)); + _virtualHost.getExchange(directExchangeName) != oldExchanges.get(directExchangeName)); assertTrue(topicExchangeName + " exchange NOT reloaded", - getVirtualHost().getExchange(topicExchangeName) != oldExchanges.get(topicExchangeName)); + _virtualHost.getExchange(topicExchangeName) != oldExchanges.get(topicExchangeName)); // There should only be the original exchanges + our 2 recovered durable exchanges assertEquals("Incorrect number of exchanges available", - originalNumExchanges + 2, getVirtualHost().getExchanges().size()); + originalNumExchanges + 2, _virtualHost.getExchanges().size()); } /** Validates the Durable queues and their properties are as expected following recovery */ - @SuppressWarnings("unchecked") private void validateBindingProperties() { - assertEquals("Incorrect number of (durable) queues following recovery", 6, getVirtualHost().getQueues().size()); + assertEquals("Incorrect number of (durable) queues following recovery", 6, _virtualHost.getQueues().size()); - validateBindingProperties(getVirtualHost().getQueue(durablePriorityQueueName).getBindings(), false); - validateBindingProperties(getVirtualHost().getQueue(durablePriorityTopicQueueName).getBindings(), true); - validateBindingProperties(getVirtualHost().getQueue(durableQueueName).getBindings(), false); - validateBindingProperties(getVirtualHost().getQueue(durableTopicQueueName).getBindings(), true); - validateBindingProperties(getVirtualHost().getQueue(durableExclusiveQueueName).getBindings(), false); + validateBindingProperties(_virtualHost.getQueue(durablePriorityQueueName).getBindings(), false); + validateBindingProperties(_virtualHost.getQueue(durablePriorityTopicQueueName).getBindings(), true); + validateBindingProperties(_virtualHost.getQueue(durableQueueName).getBindings(), false); + validateBindingProperties(_virtualHost.getQueue(durableTopicQueueName).getBindings(), true); + validateBindingProperties(_virtualHost.getQueue(durableExclusiveQueueName).getBindings(), false); } /** @@ -522,13 +501,13 @@ public class VirtualHostMessageStoreTest extends QpidTestCase private void setQueueExclusivity(boolean exclusive) throws MessageSource.ExistingConsumerPreventsExclusive { - AMQQueue queue = getVirtualHost().getQueue(durableExclusiveQueueName); + AMQQueue queue = _virtualHost.getQueue(durableExclusiveQueueName); queue.setAttribute(Queue.EXCLUSIVE, queue.getExclusive(), exclusive ? ExclusivityPolicy.CONTAINER : ExclusivityPolicy.NONE); } private void validateQueueExclusivityProperty(boolean expected) { - AMQQueue queue = getVirtualHost().getQueue(durableExclusiveQueueName); + AMQQueue queue = _virtualHost.getQueue(durableExclusiveQueueName); assertEquals("Queue exclusivity was incorrect", queue.isExclusive(), expected); } @@ -536,12 +515,12 @@ public class VirtualHostMessageStoreTest extends QpidTestCase private void validateDurableQueueProperties() { - validateQueueProperties(getVirtualHost().getQueue(durablePriorityQueueName), true, true, false, false); - validateQueueProperties(getVirtualHost().getQueue(durablePriorityTopicQueueName), true, true, false, false); - validateQueueProperties(getVirtualHost().getQueue(durableQueueName), false, true, false, false); - validateQueueProperties(getVirtualHost().getQueue(durableTopicQueueName), false, true, false, false); - validateQueueProperties(getVirtualHost().getQueue(durableExclusiveQueueName), false, true, true, false); - validateQueueProperties(getVirtualHost().getQueue(durableLastValueQueueName), false, true, true, true); + validateQueueProperties(_virtualHost.getQueue(durablePriorityQueueName), true, true, false, false); + validateQueueProperties(_virtualHost.getQueue(durablePriorityTopicQueueName), true, true, false, false); + validateQueueProperties(_virtualHost.getQueue(durableQueueName), false, true, false, false); + validateQueueProperties(_virtualHost.getQueue(durableTopicQueueName), false, true, false, false); + validateQueueProperties(_virtualHost.getQueue(durableExclusiveQueueName), false, true, true, false); + validateQueueProperties(_virtualHost.getQueue(durableLastValueQueueName), false, true, true, true); } private void validateQueueProperties(AMQQueue queue, boolean usePriority, boolean durable, boolean exclusive, boolean lastValueQueue) @@ -600,13 +579,13 @@ public class VirtualHostMessageStoreTest extends QpidTestCase MessageMetaData mmd = new MessageMetaData(messageInfo, headerBody, System.currentTimeMillis()); - final StoredMessage storedMessage = getVirtualHost().getMessageStore().addMessage(mmd); + final StoredMessage storedMessage = _virtualHost.getMessageStore().addMessage(mmd); storedMessage.flushToStore(); final AMQMessage currentMessage = new AMQMessage(storedMessage); - ServerTransaction trans = new AutoCommitTransaction(getVirtualHost().getMessageStore()); + ServerTransaction trans = new AutoCommitTransaction(_virtualHost.getMessageStore()); exchange.send(currentMessage, routingKey, InstanceProperties.EMPTY, trans, null); } @@ -680,7 +659,7 @@ public class VirtualHostMessageStoreTest extends QpidTestCase AMQQueue queue = null; //Ideally we would be able to use the QueueDeclareHandler here. - queue = getVirtualHost().createQueue(queueArguments); + queue = _virtualHost.createQueue(queueArguments); validateQueueProperties(queue, usePriority, durable, exclusive, lastValueQueue); } @@ -711,27 +690,27 @@ public class VirtualHostMessageStoreTest extends QpidTestCase attributes.put(org.apache.qpid.server.model.Exchange.LIFETIME_POLICY, durable ? LifetimePolicy.DELETE_ON_NO_LINKS : LifetimePolicy.PERMANENT); attributes.put(org.apache.qpid.server.model.Exchange.ALTERNATE_EXCHANGE, null); - exchange = getVirtualHost().createExchange(attributes); + exchange = _virtualHost.createExchange(attributes); return exchange; } private void bindAllQueuesToExchange(ExchangeImpl exchange, String routingKey) { - bindQueueToExchange(exchange, routingKey, getVirtualHost().getQueue(durablePriorityQueueName), false); - bindQueueToExchange(exchange, routingKey, getVirtualHost().getQueue(durableQueueName), false); - bindQueueToExchange(exchange, routingKey, getVirtualHost().getQueue(priorityQueueName), false); - bindQueueToExchange(exchange, routingKey, getVirtualHost().getQueue(queueName), false); - bindQueueToExchange(exchange, routingKey, getVirtualHost().getQueue(durableExclusiveQueueName), false); + bindQueueToExchange(exchange, routingKey, _virtualHost.getQueue(durablePriorityQueueName), false); + bindQueueToExchange(exchange, routingKey, _virtualHost.getQueue(durableQueueName), false); + bindQueueToExchange(exchange, routingKey, _virtualHost.getQueue(priorityQueueName), false); + bindQueueToExchange(exchange, routingKey, _virtualHost.getQueue(queueName), false); + bindQueueToExchange(exchange, routingKey, _virtualHost.getQueue(durableExclusiveQueueName), false); } private void bindAllTopicQueuesToExchange(ExchangeImpl exchange, String routingKey) { - bindQueueToExchange(exchange, routingKey, getVirtualHost().getQueue(durablePriorityTopicQueueName), true); - bindQueueToExchange(exchange, routingKey, getVirtualHost().getQueue(durableTopicQueueName), true); - bindQueueToExchange(exchange, routingKey, getVirtualHost().getQueue(priorityTopicQueueName), true); - bindQueueToExchange(exchange, routingKey, getVirtualHost().getQueue(topicQueueName), true); + bindQueueToExchange(exchange, routingKey, _virtualHost.getQueue(durablePriorityTopicQueueName), true); + bindQueueToExchange(exchange, routingKey, _virtualHost.getQueue(durableTopicQueueName), true); + bindQueueToExchange(exchange, routingKey, _virtualHost.getQueue(priorityTopicQueueName), true); + bindQueueToExchange(exchange, routingKey, _virtualHost.getQueue(topicQueueName), true); } @@ -805,7 +784,7 @@ public class VirtualHostMessageStoreTest extends QpidTestCase private void validateMessageOnQueue(String queueName, long messageCount) { - AMQQueue queue = getVirtualHost().getQueue(queueName); + AMQQueue queue = _virtualHost.getQueue(queueName); assertNotNull("Queue(" + queueName + ") not correctly registered:", queue); 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 index 6e4ea13cfc..4ea071f3ac 100644 --- 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 @@ -53,8 +53,8 @@ public class StatisticsTest extends QpidBrokerTestCase @Override public void setUp() throws Exception { - createTestVirtualHost(0, TEST_VIRTUALHOST1); - createTestVirtualHost(0, TEST_VIRTUALHOST2); + createTestVirtualHostNode(0, TEST_VIRTUALHOST1); + createTestVirtualHostNode(0, TEST_VIRTUALHOST2); getBrokerConfiguration().addJmxManagementConfiguration(); 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 index 47a25dbbec..87a060766b 100644 --- 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 @@ -65,7 +65,7 @@ public class Asserts ConfiguredObject.CONTEXT, VirtualHost.SUPPORTED_QUEUE_TYPES, VirtualHost.TYPE, - VirtualHost.CONFIGURATION_STORE_SETTINGS, + VirtualHost.MESSAGE_STORE_SETTINGS, VirtualHost.SECURITY_ACL); assertEquals("Unexpected value of attribute " + VirtualHost.NAME, 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 index 6ba8df075b..ee7abd2424 100644 --- 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 @@ -48,25 +48,9 @@ public class BindingRestTest extends QpidRestTestCase } } - public void testGetVirtualHostBindings() throws Exception - { - List> bindings = getRestTestHelper().getJsonAsList("/rest/binding/test"); - assertNotNull("Bindings cannot be null", bindings); - assertEquals("Unexpected number of bindings", RestTestHelper.EXPECTED_QUEUES.length, bindings.size()); - for (String queueName : RestTestHelper.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); - } - } - public void testGetVirtualHostExchangeBindings() throws Exception { - List> bindings = getRestTestHelper().getJsonAsList("/rest/binding/test/amq.direct"); + List> bindings = getRestTestHelper().getJsonAsList("/rest/binding/test/test/amq.direct"); assertNotNull("Bindings cannot be null", bindings); assertEquals("Unexpected number of bindings", RestTestHelper.EXPECTED_QUEUES.length, bindings.size()); for (String queueName : RestTestHelper.EXPECTED_QUEUES) @@ -78,7 +62,7 @@ public class BindingRestTest extends QpidRestTestCase public void testGetVirtualHostExchangeQueueBindings() throws Exception { - List> bindings = getRestTestHelper().getJsonAsList("/rest/binding/test/amq.direct/queue"); + List> bindings = getRestTestHelper().getJsonAsList("/rest/binding/test/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)); @@ -87,25 +71,24 @@ public class BindingRestTest extends QpidRestTestCase public void testDeleteBinding() throws Exception { - List> bindings = getRestTestHelper().getJsonAsList("/rest/binding/test/amq.direct/queue/queue"); + String bindingUrl = "/rest/binding/test/test/amq.direct/queue/queue"; + List> bindings = getRestTestHelper().getJsonAsList(bindingUrl); 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()); + int responseCode = getRestTestHelper().submitRequest(bindingUrl, "DELETE", null); + assertEquals("Unexpected response code", 200, responseCode); - bindings = getRestTestHelper().getJsonAsList("/rest/binding/test/amq.direct/queue/queue"); + bindings = getRestTestHelper().getJsonAsList(bindingUrl); 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"); + Map binding = getRestTestHelper().getJsonAsSingletonList("/rest/binding/test/test/amq.direct/queue"); + int responseCode = getRestTestHelper().submitRequest("/rest/binding/test/test/amq.direct?id=" + binding.get(Binding.ID), "DELETE", null); + assertEquals("Unexpected response code", 200, responseCode); + List> bindings = getRestTestHelper().getJsonAsList("/rest/binding/test/test/amq.direct/queue"); assertEquals("Binding should be deleted", 0, bindings.size()); } @@ -117,14 +100,12 @@ public class BindingRestTest extends QpidRestTestCase 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(); + String bindingUrl = "/rest/binding/test/test/amq.direct/queue/" + bindingName; + + int responseCode = getRestTestHelper().submitRequest(bindingUrl, "PUT", bindingData); assertEquals("Unexpected response code", 201, responseCode); - Map binding = getRestTestHelper().getJsonAsSingletonList("/rest/binding/test/amq.direct/queue/" + bindingName); + Map binding = getRestTestHelper().getJsonAsSingletonList(bindingUrl); Asserts.assertBinding(bindingName, "queue", "amq.direct", binding); } @@ -136,16 +117,16 @@ public class BindingRestTest extends QpidRestTestCase attributes.put(Binding.QUEUE, "queue"); attributes.put(Binding.EXCHANGE, "amq.direct"); - int responseCode = getRestTestHelper().submitRequest("/rest/binding/test/amq.direct/queue/" + bindingName, "PUT", attributes); + String bindingUrl = "/rest/binding/test/test/amq.direct/queue/" + bindingName; + int responseCode = getRestTestHelper().submitRequest(bindingUrl, "PUT", attributes); assertEquals("Unexpected response code", 201, responseCode); - Map binding = getRestTestHelper().getJsonAsSingletonList("/rest/binding/test/amq.direct/queue/" + bindingName); - + Map binding = getRestTestHelper().getJsonAsSingletonList(bindingUrl); Asserts.assertBinding(bindingName, "queue", "amq.direct", binding); - attributes.put(Binding.ARGUMENTS, null); + attributes.put(Binding.ARGUMENTS, "blah"); - responseCode = getRestTestHelper().submitRequest("/rest/binding/test/amq.direct/queue/" + bindingName, "PUT", attributes); + responseCode = getRestTestHelper().submitRequest(bindingUrl, "PUT", attributes); assertEquals("Update should be unsupported", 409, responseCode); } } 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 index 20005d4f47..b68c53739c 100644 --- 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 @@ -40,6 +40,7 @@ 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.server.model.VirtualHostNode; import org.apache.qpid.server.plugin.MessageStoreFactory; import org.apache.qpid.test.client.UnroutableMessageTestExceptionListener; import org.apache.qpid.test.utils.TestBrokerConfiguration; @@ -49,7 +50,7 @@ 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_VIRTUALHOST_NODES_ATTRIBUTE = "virtualhostnodes"; private static final String BROKER_STATISTICS_ATTRIBUTE = "statistics"; public void testGet() throws Exception @@ -63,12 +64,14 @@ public class BrokerRestTest extends QpidRestTestCase 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()); + List> nodes = (List>) brokerDetails.get(BROKER_VIRTUALHOST_NODES_ATTRIBUTE); + assertEquals("Unexpected number of virtual hosts", 3, nodes.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)); + for (String nodeName: EXPECTED_VIRTUALHOSTS) + { + Map nodeAttributes = getRestTestHelper().find(VirtualHostNode.NAME, nodeName, nodes); + assertNotNull("Node attributes are not found for node with name " + nodeName, nodeAttributes); + } @SuppressWarnings("unchecked") List> ports = (List>) brokerDetails.get(BROKER_PORTS_ATTRIBUTE); @@ -227,7 +230,7 @@ public class BrokerRestTest extends QpidRestTestCase 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 virtual host nodes", brokerDetails.get(BROKER_VIRTUALHOST_NODES_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 index f924dae56e..bf11ff9ae0 100644 --- 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 @@ -98,7 +98,7 @@ public class ConnectionRestTest extends QpidRestTestCase public void testGetVirtualHostConnections() throws Exception { - List> connections = getRestTestHelper().getJsonAsList("/rest/connection/test"); + List> connections = getRestTestHelper().getJsonAsList("/rest/connection/test/test"); assertEquals("Unexpected number of connections", 1, connections.size()); Asserts.assertConnection(connections.get(0), (AMQConnection) _connection); } @@ -108,7 +108,7 @@ public class ConnectionRestTest extends QpidRestTestCase // get connection name String connectionName = getConnectionName(); - Map connectionDetails = getRestTestHelper().getJsonAsSingletonList("/rest/connection/test/" + Map connectionDetails = getRestTestHelper().getJsonAsSingletonList("/rest/connection/test/test/" + URLDecoder.decode(connectionName, "UTF-8")); assertConnection(connectionDetails); } @@ -122,7 +122,7 @@ public class ConnectionRestTest extends QpidRestTestCase public void testGetVirtualHostSessions() throws Exception { - List> sessions = getRestTestHelper().getJsonAsList("/rest/session/test"); + List> sessions = getRestTestHelper().getJsonAsList("/rest/session/test/test"); assertEquals("Unexpected number of sessions", 1, sessions.size()); assertSession(sessions.get(0), (AMQSession) _session); } @@ -132,7 +132,7 @@ public class ConnectionRestTest extends QpidRestTestCase // get connection name String connectionName = getConnectionName(); - List> sessions = getRestTestHelper().getJsonAsList("/rest/session/test/" + List> sessions = getRestTestHelper().getJsonAsList("/rest/session/test/test/" + URLDecoder.decode(connectionName, "UTF-8")); assertEquals("Unexpected number of sessions", 1, sessions.size()); assertSession(sessions.get(0), (AMQSession) _session); @@ -143,7 +143,7 @@ public class ConnectionRestTest extends QpidRestTestCase // get connection name String connectionName = getConnectionName(); - List> sessions = getRestTestHelper().getJsonAsList("/rest/session/test/" + List> sessions = getRestTestHelper().getJsonAsList("/rest/session/test/test/" + URLDecoder.decode(connectionName, "UTF-8") + "/" + ((AMQSession) _session).getChannelId()); assertEquals("Unexpected number of sessions", 1, sessions.size()); assertSession(sessions.get(0), (AMQSession) _session); @@ -210,7 +210,7 @@ public class ConnectionRestTest extends QpidRestTestCase private String getConnectionName() throws IOException { - Map hostDetails = getRestTestHelper().getJsonAsSingletonList("/rest/virtualhost/test"); + Map hostDetails = getRestTestHelper().getJsonAsSingletonList("/rest/virtualhost/test/test"); @SuppressWarnings("unchecked") List> connections = (List>) hostDetails .get(VirtualHostRestTest.VIRTUALHOST_CONNECTIONS_ATTRIBUTE); 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 index 962c71583c..ef674fc95b 100644 --- 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 @@ -64,7 +64,7 @@ public class ExchangeRestTest extends QpidRestTestCase { for (String exchangeName : EXPECTED_EXCHANGES) { - Map exchange = getRestTestHelper().getJsonAsSingletonList("/rest/exchange/test/" + Map exchange = getRestTestHelper().getJsonAsSingletonList("/rest/exchange/test/test/" + URLDecoder.decode(exchangeName, "UTF-8")); assertExchange(exchangeName, exchange); } @@ -73,20 +73,22 @@ public class ExchangeRestTest extends QpidRestTestCase public void testSetExchangeAttributesUnsupported() throws Exception { String exchangeName = getTestName(); + String exchangeUrl = "/rest/exchange/test/test/" + exchangeName; Map attributes = new HashMap(); attributes.put(Exchange.NAME, exchangeName); attributes.put(Exchange.TYPE, "direct"); - int responseCode =getRestTestHelper().submitRequest("/rest/exchange/test/" + exchangeName, "PUT", attributes); + int responseCode = getRestTestHelper().submitRequest(exchangeUrl, "PUT", attributes); + assertEquals("Exchange should be created", 201, responseCode); - Map exchange = getRestTestHelper().getJsonAsSingletonList("/rest/exchange/test/" + exchangeName); + Map exchange = getRestTestHelper().getJsonAsSingletonList(exchangeUrl); assertNotNull("Exchange not found", exchange); attributes = new HashMap(); attributes.put(Exchange.NAME, exchangeName); - attributes.put(Exchange.ALTERNATE_EXCHANGE, "my-alternate-exchange"); + attributes.put(Exchange.ALTERNATE_EXCHANGE, "amq.direct"); - responseCode = getRestTestHelper().submitRequest("/rest/exchange/test/" + exchangeName, "PUT", attributes); + responseCode = getRestTestHelper().submitRequest(exchangeUrl, "PUT", attributes); assertEquals("Exchange update should be unsupported", 409, responseCode); } 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 index c0be10931c..1a8fe9d930 100644 --- 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 @@ -29,6 +29,7 @@ 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.VirtualHost; +import org.apache.qpid.server.model.VirtualHostNode; import org.apache.qpid.server.security.auth.manager.AnonymousAuthenticationManagerFactory; import org.apache.qpid.test.utils.QpidBrokerTestCase; import org.apache.qpid.test.utils.TestBrokerConfiguration; @@ -54,12 +55,12 @@ public class QpidRestTestCase extends QpidBrokerTestCase getRestTestHelper().setUsernameAndPassword("webadmin", "webadmin"); //remove the normal 'test' vhost, we will configure the vhosts below - getBrokerConfiguration(0).removeObjectConfiguration(VirtualHost.class, TestBrokerConfiguration.ENTRY_NAME_VIRTUAL_HOST); + getBrokerConfiguration(0).removeObjectConfiguration(VirtualHostNode.class, TestBrokerConfiguration.ENTRY_NAME_VIRTUAL_HOST); // Set up virtualhost config with queues and bindings to the amq.direct for (String virtualhost : EXPECTED_VIRTUALHOSTS) { - createTestVirtualHost(0, virtualhost); + createTestVirtualHostNode(0, virtualhost); } customizeConfiguration(); 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 index 8c8db3b358..70cc6414cd 100644 --- 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 @@ -104,7 +104,7 @@ public class QueueRestTest extends QpidRestTestCase public void testGetByName() throws Exception { String queueName = getTestQueueName(); - Map queueDetails = getRestTestHelper().getJsonAsSingletonList("/rest/queue/test/" + queueName); + Map queueDetails = getRestTestHelper().getJsonAsSingletonList("/rest/queue/test/test/" + queueName); Asserts.assertQueue(queueName, "standard", queueDetails); assertStatistics(queueDetails); @@ -130,9 +130,11 @@ public class QueueRestTest extends QpidRestTestCase Map attributes = new HashMap(); attributes.put(Queue.NAME, queueName); - int responseCode = getRestTestHelper().submitRequest("/rest/queue/test/" + queueName, "PUT", attributes); + String queueUrl = "/rest/queue/test/test/" + queueName; + int responseCode = getRestTestHelper().submitRequest(queueUrl, "PUT", attributes); + assertEquals("Queue was not created", 201, responseCode); - Map queueDetails = getRestTestHelper().getJsonAsSingletonList("/rest/queue/test/" + queueName); + Map queueDetails = getRestTestHelper().getJsonAsSingletonList(queueUrl); Asserts.assertQueue(queueName, "standard", queueDetails); attributes = new HashMap(); @@ -146,10 +148,10 @@ public class QueueRestTest extends QpidRestTestCase attributes.put(Queue.ALERT_THRESHOLD_QUEUE_DEPTH_MESSAGES, 50000); attributes.put(Queue.MAXIMUM_DELIVERY_ATTEMPTS, 10); - responseCode = getRestTestHelper().submitRequest("/rest/queue/test/" + queueName, "PUT", attributes); + responseCode = getRestTestHelper().submitRequest(queueUrl, "PUT", attributes); assertEquals("Setting of queue attributes should be allowed", 200, responseCode); - Map queueData = getRestTestHelper().getJsonAsSingletonList("/rest/queue/test/" + queueName); + Map queueData = getRestTestHelper().getJsonAsSingletonList(queueUrl); assertEquals("Unexpected " + Queue.QUEUE_FLOW_CONTROL_SIZE_BYTES, 100000, queueData.get(Queue.QUEUE_FLOW_CONTROL_SIZE_BYTES) ); assertEquals("Unexpected " + Queue.QUEUE_FLOW_RESUME_SIZE_BYTES, 80000, queueData.get(Queue.QUEUE_FLOW_RESUME_SIZE_BYTES) ); assertEquals("Unexpected " + Queue.ALERT_REPEAT_GAP, 10000, queueData.get(Queue.ALERT_REPEAT_GAP) ); @@ -170,7 +172,7 @@ public class QueueRestTest extends QpidRestTestCase createBinding(bindingName, exchanges[i], queueName); } - Map queueDetails = getRestTestHelper().getJsonAsSingletonList("/rest/queue/test/" + queueName); + Map queueDetails = getRestTestHelper().getJsonAsSingletonList("/rest/queue/test/test/" + queueName); Asserts.assertQueue(queueName, "standard", queueDetails); @SuppressWarnings("unchecked") @@ -192,7 +194,7 @@ public class QueueRestTest extends QpidRestTestCase 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, + "/rest/binding/test/test/" + URLDecoder.decode(exchangeName, "UTF-8") + "/" + queueName + "/" + bindingName, "PUT"); Map bindingData = new HashMap(); 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 index 4dc4001c4b..9a5d833d01 100644 --- 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 @@ -526,13 +526,15 @@ String dataAsString = new String(data); Map queueData = new HashMap(); queueData.put(Queue.NAME, queueName); queueData.put(Queue.DURABLE, Boolean.FALSE); - submitRequest("/rest/queue/test/" + queueName, "PUT", queueData); + int responseCode = submitRequest("/rest/queue/test/test/" + queueName, "PUT", queueData); + Assert.assertEquals("Unexpected response code creating queue" + queueName, 201, responseCode); Map bindingData = new HashMap(); bindingData.put(Binding.NAME, queueName); bindingData.put(Binding.QUEUE, queueName); bindingData.put(Binding.EXCHANGE, "amq.direct"); - submitRequest("/rest/binding/test/amq.direct/" + queueName + "/" + queueName, "PUT", queueData); + responseCode = submitRequest("/rest/binding/test/test/amq.direct/" + queueName + "/" + queueName, "PUT", queueData); + Assert.assertEquals("Unexpected response code binding queue " + queueName, 201, responseCode); } } } 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 index cf551ae315..adc9790f36 100644 --- 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 @@ -44,8 +44,8 @@ public class StructureRestTest extends QpidRestTestCase assertNode(structure, "Broker"); @SuppressWarnings("unchecked") - List> virtualhosts = (List>) structure.get("virtualhosts"); - assertEquals("Unexpected number of virtual hosts", 3, virtualhosts.size()); + List> virtualhostnodes = (List>) structure.get("virtualhostnodes"); + assertEquals("Unexpected number of virtual hosts", 3, virtualhostnodes.size()); @SuppressWarnings("unchecked") List> ports = (List>) structure.get("ports"); @@ -55,16 +55,20 @@ public class StructureRestTest extends QpidRestTestCase List> providers = (List>) structure.get("authenticationproviders"); assertEquals("Unexpected number of authentication providers", 2, providers.size()); - for (String hostName : EXPECTED_VIRTUALHOSTS) + for (String nodeName : EXPECTED_VIRTUALHOSTS) { - Map host = getRestTestHelper().find("name", hostName, virtualhosts); - assertNotNull("Host " + hostName + " is not found ", host); - assertNode(host, hostName); + Map node = getRestTestHelper().find("name", nodeName, virtualhostnodes); + assertNotNull("Node " + nodeName + " is not found ", node); + assertNode(node, nodeName); } String hostName = "test"; - Map host = getRestTestHelper().find("name", hostName, virtualhosts); + Map node = getRestTestHelper().find("name", hostName, virtualhostnodes); + + @SuppressWarnings("unchecked") + List> virtualhosts = (List>) node.get("virtualhosts"); + Map host = getRestTestHelper().find("name", hostName, virtualhosts); @SuppressWarnings("unchecked") List> queues = (List>) host.get("queues"); assertNotNull("Host " + hostName + " queues are not found ", queues); 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 index f336c7fc77..4bd1a19fe2 100644 --- 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 @@ -30,9 +30,6 @@ import java.util.Map; import javax.jms.Session; import javax.servlet.http.HttpServletResponse; -import org.codehaus.jackson.JsonGenerationException; -import org.codehaus.jackson.map.JsonMappingException; - import org.apache.qpid.client.AMQConnection; import org.apache.qpid.server.model.Exchange; import org.apache.qpid.server.model.Queue; @@ -40,10 +37,13 @@ import org.apache.qpid.server.model.VirtualHost; import org.apache.qpid.server.queue.LastValueQueue; import org.apache.qpid.server.queue.PriorityQueue; import org.apache.qpid.server.queue.SortedQueue; -import org.apache.qpid.server.store.MessageStore; import org.apache.qpid.server.virtualhost.AbstractVirtualHost; -import org.apache.qpid.server.virtualhost.StandardVirtualHost; + +import org.apache.qpid.server.model.VirtualHostNode; +import org.apache.qpid.server.store.DurableConfigurationStore; import org.apache.qpid.util.FileUtils; +import org.codehaus.jackson.JsonGenerationException; +import org.codehaus.jackson.map.JsonMappingException; public class VirtualHostRestTest extends QpidRestTestCase { @@ -55,7 +55,7 @@ public class VirtualHostRestTest extends QpidRestTestCase public void testGet() throws Exception { - List> hosts = getRestTestHelper().getJsonAsList("/rest/virtualhost/"); + 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) @@ -108,7 +108,7 @@ public class VirtualHostRestTest extends QpidRestTestCase public void testPutCreateVirtualHostUsingStoreType() throws Exception { String hostName = getTestName(); - String storeType = getTestProfileMessageStoreType(); + String storeType = getTestProfileVirtualHostNodeType(); String storeLocation = createHost(hostName, storeType, null); try { @@ -117,10 +117,6 @@ public class VirtualHostRestTest extends QpidRestTestCase Map hostDetails = getRestTestHelper().getJsonAsSingletonList("/rest/virtualhost/" + hostName); Asserts.assertVirtualHost(hostName, hostDetails); - @SuppressWarnings("unchecked") - Map messageStoreSettings = (Map) hostDetails.get(VirtualHost.MESSAGE_STORE_SETTINGS); - assertEquals("Unexpected store type", storeType, messageStoreSettings.get(MessageStore.STORE_TYPE)); - assertNewVirtualHost(hostDetails); } finally @@ -135,13 +131,10 @@ public class VirtualHostRestTest extends QpidRestTestCase public void testDeleteHost() throws Exception { String hostToDelete = TEST3_VIRTUALHOST; - HttpURLConnection connection = getRestTestHelper().openManagementConnection("/rest/virtualhost/" + hostToDelete, "DELETE"); + HttpURLConnection connection = getRestTestHelper().openManagementConnection("/rest/virtualhost/" + hostToDelete + "/" + 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()); } @@ -161,32 +154,22 @@ public class VirtualHostRestTest extends QpidRestTestCase public void testUpdateActiveHostFails() throws Exception { String hostToUpdate = TEST3_VIRTUALHOST; - Map hostDetails = getRestTestHelper().getJsonAsSingletonList("/rest/virtualhost/" + hostToUpdate); + String restHostUrl = "/rest/virtualhost/" + hostToUpdate + "/" + hostToUpdate; + Map hostDetails = getRestTestHelper().getJsonAsSingletonList(restHostUrl); Asserts.assertVirtualHost(hostToUpdate, hostDetails); - @SuppressWarnings("unchecked") - Map attributes = (Map)hostDetails.get(VirtualHost.MESSAGE_STORE_SETTINGS); - String configPath = (String) attributes.get(MessageStore.STORE_PATH); - - String storeType = getTestProfileMessageStoreType(); - String storeLocation = getStoreLocation(hostToUpdate); - Map newMessageStoreSettings = new HashMap(); - newMessageStoreSettings.put(MessageStore.STORE_TYPE, storeType); - newMessageStoreSettings.put(MessageStore.STORE_PATH, storeLocation); Map newAttributes = new HashMap(); newAttributes.put(VirtualHost.NAME, hostToUpdate); - newAttributes.put(VirtualHost.MESSAGE_STORE_SETTINGS, newMessageStoreSettings); + newAttributes.put("fakeAttribute", "value"); - int response = getRestTestHelper().submitRequest("/rest/virtualhost/" + hostToUpdate, "PUT", newAttributes); + int response = getRestTestHelper().submitRequest(restHostUrl, "PUT", newAttributes); assertEquals("Unexpected response code", 409, response); restartBroker(); - Map rereadHostDetails = getRestTestHelper().getJsonAsSingletonList("/rest/virtualhost/" + hostToUpdate); + Map rereadHostDetails = getRestTestHelper().getJsonAsSingletonList(restHostUrl); Asserts.assertVirtualHost(hostToUpdate, rereadHostDetails); - @SuppressWarnings("unchecked") - Map rereadMessageStoreSettings = (Map)rereadHostDetails.get(VirtualHost.MESSAGE_STORE_SETTINGS); - assertEquals("Unexpected config path", configPath, rereadMessageStoreSettings.get(MessageStore.STORE_PATH)); + assertFalse(rereadHostDetails.containsKey("fakeAttribute")); } public void testPutCreateQueue() throws Exception @@ -342,10 +325,14 @@ public class VirtualHostRestTest extends QpidRestTestCase String queueName = getTestQueueName(); createQueue(queueName, null, null); - HttpURLConnection connection = getRestTestHelper().openManagementConnection("/rest/queue/test/" + queueName, "DELETE"); + String queueUrl = "/rest/queue/test/test/" + queueName; + List> queues = getRestTestHelper().getJsonAsList(queueUrl); + assertEquals("Queue should exist", 1, queues.size()); + + HttpURLConnection connection = getRestTestHelper().openManagementConnection(queueUrl, "DELETE"); connection.connect(); assertEquals("Unexpected response code", 200, connection.getResponseCode()); - List> queues = getRestTestHelper().getJsonAsList("/rest/queue/test/" + queueName); + queues = getRestTestHelper().getJsonAsList(queueUrl); assertEquals("Queue should be deleted", 0, queues.size()); } @@ -353,12 +340,12 @@ public class VirtualHostRestTest extends QpidRestTestCase { String queueName = getTestQueueName(); createQueue(queueName, null, null); - Map queueDetails = getRestTestHelper().getJsonAsSingletonList("/rest/queue/test/" + queueName); + Map queueDetails = getRestTestHelper().getJsonAsSingletonList("/rest/queue/test/test/" + queueName); - HttpURLConnection connection = getRestTestHelper().openManagementConnection("/rest/queue/test?id=" + queueDetails.get(Queue.ID), "DELETE"); + HttpURLConnection connection = getRestTestHelper().openManagementConnection("/rest/queue/test/test?id=" + queueDetails.get(Queue.ID), "DELETE"); connection.connect(); assertEquals("Unexpected response code", 200, connection.getResponseCode()); - List> queues = getRestTestHelper().getJsonAsList("/rest/queue/test/" + queueName); + List> queues = getRestTestHelper().getJsonAsList("/rest/queue/test/test/" + queueName); assertEquals("Queue should be deleted", 0, queues.size()); } @@ -367,10 +354,10 @@ public class VirtualHostRestTest extends QpidRestTestCase String exchangeName = getTestName(); createExchange(exchangeName, "direct"); - HttpURLConnection connection = getRestTestHelper().openManagementConnection("/rest/exchange/test/" + exchangeName, "DELETE"); + HttpURLConnection connection = getRestTestHelper().openManagementConnection("/rest/exchange/test/test/" + exchangeName, "DELETE"); connection.connect(); assertEquals("Unexpected response code", 200, connection.getResponseCode()); - List> queues = getRestTestHelper().getJsonAsList("/rest/exchange/test/" + exchangeName); + List> queues = getRestTestHelper().getJsonAsList("/rest/exchange/test/test/" + exchangeName); assertEquals("Exchange should be deleted", 0, queues.size()); } @@ -378,12 +365,12 @@ public class VirtualHostRestTest extends QpidRestTestCase { String exchangeName = getTestName(); createExchange(exchangeName, "direct"); - Map echangeDetails = getRestTestHelper().getJsonAsSingletonList("/rest/exchange/test/" + exchangeName); + Map echangeDetails = getRestTestHelper().getJsonAsSingletonList("/rest/exchange/test/test/" + exchangeName); - HttpURLConnection connection = getRestTestHelper().openManagementConnection("/rest/exchange/test?id=" + echangeDetails.get(Exchange.ID), "DELETE"); + HttpURLConnection connection = getRestTestHelper().openManagementConnection("/rest/exchange/test/test?id=" + echangeDetails.get(Exchange.ID), "DELETE"); connection.connect(); assertEquals("Unexpected response code", 200, connection.getResponseCode()); - List> queues = getRestTestHelper().getJsonAsList("/rest/exchange/test/" + exchangeName); + List> queues = getRestTestHelper().getJsonAsList("/rest/exchange/test/test/" + exchangeName); assertEquals("Exchange should be deleted", 0, queues.size()); } @@ -479,7 +466,7 @@ public class VirtualHostRestTest extends QpidRestTestCase private void createExchange(String exchangeName, String exchangeType) throws IOException { - HttpURLConnection connection = getRestTestHelper().openManagementConnection("/rest/exchange/test/" + exchangeName, "PUT"); + HttpURLConnection connection = getRestTestHelper().openManagementConnection("/rest/exchange/test/test/" + exchangeName, "PUT"); Map queueData = new HashMap(); queueData.put(Exchange.NAME, exchangeName); @@ -502,7 +489,7 @@ public class VirtualHostRestTest extends QpidRestTestCase private int tryCreateQueue(String queueName, String queueType, Map attributes) throws IOException, JsonGenerationException, JsonMappingException { - HttpURLConnection connection = getRestTestHelper().openManagementConnection("/rest/queue/test/" + queueName, "PUT"); + HttpURLConnection connection = getRestTestHelper().openManagementConnection("/rest/queue/test/test/" + queueName, "PUT"); Map queueData = new HashMap(); queueData.put(Queue.NAME, queueName); @@ -536,20 +523,17 @@ public class VirtualHostRestTest extends QpidRestTestCase return new File(TMP_FOLDER, "store-" + hostName + "-" + System.currentTimeMillis()).getAbsolutePath(); } - private int tryCreateVirtualHost(String hostName, String storeType, String storePath, String configPath) throws IOException, + private int tryCreateVirtualHost(String hostName, String virtualHostNodeType, String storePath, String configPath) throws IOException, JsonGenerationException, JsonMappingException { - Map messageStoreSettings = new HashMap(); - messageStoreSettings.put(MessageStore.STORE_PATH, storePath); - messageStoreSettings.put(MessageStore.STORE_TYPE, storeType); - Map hostData = new HashMap(); - hostData.put(VirtualHost.NAME, hostName); - hostData.put(VirtualHost.TYPE, StandardVirtualHost.TYPE); - hostData.put(VirtualHost.MESSAGE_STORE_SETTINGS, messageStoreSettings); + hostData.put(VirtualHostNode.NAME, hostName); + hostData.put(VirtualHostNode.TYPE, virtualHostNodeType); + hostData.put(VirtualHostNode.IS_MESSAGE_STORE_PROVIDER, true); + hostData.put(DurableConfigurationStore.STORE_PATH, storePath); - return getRestTestHelper().submitRequest("/rest/virtualhost/" + hostName, "PUT", hostData); + return getRestTestHelper().submitRequest("/rest/virtualhostnode/" + hostName, "PUT", hostData); } private void assertNewVirtualHost(Map hostDetails) diff --git a/java/systests/src/main/java/org/apache/qpid/systest/rest/acl/BrokerACLTest.java b/java/systests/src/main/java/org/apache/qpid/systest/rest/acl/BrokerACLTest.java index 541160cd80..2575fb7e43 100644 --- a/java/systests/src/main/java/org/apache/qpid/systest/rest/acl/BrokerACLTest.java +++ b/java/systests/src/main/java/org/apache/qpid/systest/rest/acl/BrokerACLTest.java @@ -29,7 +29,6 @@ import java.util.Map; import org.codehaus.jackson.JsonGenerationException; import org.codehaus.jackson.map.JsonMappingException; - import org.apache.qpid.server.management.plugin.HttpManagement; import org.apache.qpid.server.model.AccessControlProvider; import org.apache.qpid.server.model.AuthenticationProvider; @@ -40,17 +39,16 @@ import org.apache.qpid.server.model.Plugin; import org.apache.qpid.server.model.Port; import org.apache.qpid.server.model.Protocol; import org.apache.qpid.server.model.TrustStore; -import org.apache.qpid.server.model.VirtualHost; import org.apache.qpid.server.model.adapter.FileBasedGroupProvider; import org.apache.qpid.server.model.adapter.FileBasedGroupProviderImpl; import org.apache.qpid.server.security.FileKeyStore; import org.apache.qpid.server.security.FileTrustStore; +import org.apache.qpid.server.model.VirtualHostNode; import org.apache.qpid.server.security.access.FileAccessControlProviderConstants; import org.apache.qpid.server.security.acl.AbstractACLTestCase; import org.apache.qpid.server.security.auth.manager.AnonymousAuthenticationManagerFactory; import org.apache.qpid.server.security.auth.manager.PlainPasswordFileAuthenticationManagerFactory; -import org.apache.qpid.server.store.MessageStore; -import org.apache.qpid.server.virtualhost.StandardVirtualHost; +import org.apache.qpid.server.store.DurableConfigurationStore; import org.apache.qpid.systest.rest.QpidRestTestCase; import org.apache.qpid.test.utils.TestBrokerConfiguration; import org.apache.qpid.test.utils.TestFileUtils; @@ -192,56 +190,56 @@ public class BrokerACLTest extends QpidRestTestCase provider.get(PlainPasswordFileAuthenticationManagerFactory.ATTRIBUTE_PATH)); } - /* === VirtualHost === */ + /* === VirtualHostNode === */ - public void testCreateVirtualHostAllowed() throws Exception + public void testCreateVirtualHostNodeAllowed() throws Exception { getRestTestHelper().setUsernameAndPassword(ALLOWED_USER, ALLOWED_USER); String hostName = getTestName(); - int responseCode = createHost(hostName); + int responseCode = createVirtualHostNode(hostName); assertEquals("Host creation should be allowed", 201, responseCode); - assertVirtualHostExists(hostName); + assertVirtualHostNodeExists(hostName); } - public void testCreateVirtualHostDenied() throws Exception + public void testCreateVirtualHostNodeDenied() throws Exception { getRestTestHelper().setUsernameAndPassword(DENIED_USER, DENIED_USER); String hostName = getTestName(); - int responseCode = createHost(hostName); - assertEquals("Host creation should be denied", 403, responseCode); + int responseCode = createVirtualHostNode(hostName); + assertEquals("Virtual host node creation should be denied", 403, responseCode); - assertVirtualHostDoesNotExist(hostName); + assertVirtualHostNodeDoesNotExist(hostName); } - public void testDeleteVirtualHostAllowed() throws Exception + public void testDeleteVirtualHostNodeAllowed() throws Exception { getRestTestHelper().setUsernameAndPassword(ALLOWED_USER, ALLOWED_USER); - assertVirtualHostExists(TEST2_VIRTUALHOST); + assertVirtualHostNodeExists(TEST2_VIRTUALHOST); - int responseCode = getRestTestHelper().submitRequest("/rest/virtualhost/" + TEST2_VIRTUALHOST, "DELETE", null); - assertEquals("Host deletion should be allowed", 200, responseCode); + int responseCode = getRestTestHelper().submitRequest("/rest/virtualhostnode/" + TEST2_VIRTUALHOST, "DELETE", null); + assertEquals("Virtual host node deletion should be allowed", 200, responseCode); - assertVirtualHostDoesNotExist(TEST2_VIRTUALHOST); + assertVirtualHostNodeDoesNotExist(TEST2_VIRTUALHOST); } - public void testDeleteVirtualHostDenied() throws Exception + public void testDeleteVirtualHostNodeDenied() throws Exception { getRestTestHelper().setUsernameAndPassword(ALLOWED_USER, ALLOWED_USER); - assertVirtualHostExists(TEST2_VIRTUALHOST); + assertVirtualHostNodeExists(TEST2_VIRTUALHOST); getRestTestHelper().setUsernameAndPassword(DENIED_USER, DENIED_USER); - int responseCode = getRestTestHelper().submitRequest("/rest/virtualhost/" + TEST2_VIRTUALHOST, "DELETE", null); - assertEquals("Host deletion should be denied", 403, responseCode); + int responseCode = getRestTestHelper().submitRequest("/rest/virtualhostnode/" + TEST2_VIRTUALHOST, "DELETE", null); + assertEquals("Virtual host node deletion should be denied", 403, responseCode); - assertVirtualHostExists(TEST2_VIRTUALHOST); + assertVirtualHostNodeExists(TEST2_VIRTUALHOST); } /* === Port === */ @@ -979,34 +977,30 @@ public class BrokerACLTest extends QpidRestTestCase assertEquals("Unexpected result", exists, !trustStores.isEmpty()); } - private int createHost(String hostName) throws Exception + private int createVirtualHostNode(String virtualHostNodeName) throws Exception { - Map messageStoreSettings = new HashMap(); - messageStoreSettings.put(MessageStore.STORE_PATH, getStoreLocation(hostName)); - messageStoreSettings.put(MessageStore.STORE_TYPE, getTestProfileMessageStoreType()); - - Map hostData = new HashMap(); - hostData.put(VirtualHost.NAME, hostName); - hostData.put(VirtualHost.MESSAGE_STORE_SETTINGS, messageStoreSettings); - hostData.put(VirtualHost.TYPE, StandardVirtualHost.TYPE); + Map data = new HashMap(); + data.put(VirtualHostNode.NAME, virtualHostNodeName); + data.put(VirtualHostNode.TYPE, getTestProfileVirtualHostNodeType()); + data.put(DurableConfigurationStore.STORE_PATH, getStoreLocation(virtualHostNodeName)); - return getRestTestHelper().submitRequest("/rest/virtualhost/" + hostName, "PUT", hostData); + return getRestTestHelper().submitRequest("/rest/virtualhostnode/" + virtualHostNodeName, "PUT", data); } - private void assertVirtualHostDoesNotExist(String hostName) throws Exception + private void assertVirtualHostNodeDoesNotExist(String name) throws Exception { - assertVirtualHostExistence(hostName, false); + assertVirtualHostNodeExistence(name, false); } - private void assertVirtualHostExists(String hostName) throws Exception + private void assertVirtualHostNodeExists(String name) throws Exception { - assertVirtualHostExistence(hostName, true); + assertVirtualHostNodeExistence(name, true); } - private void assertVirtualHostExistence(String hostName, boolean exists) throws Exception + private void assertVirtualHostNodeExistence(String name, boolean exists) throws Exception { - List> hosts = getRestTestHelper().getJsonAsList("/rest/virtualhost/" + hostName); - assertEquals("Unexpected result", exists, !hosts.isEmpty()); + List> hosts = getRestTestHelper().getJsonAsList("/rest/virtualhostnode/" + name); + assertEquals("Node " + name + (exists ? " does not exist" : " exists" ), exists, !hosts.isEmpty()); } private String getStoreLocation(String hostName) diff --git a/java/systests/src/main/java/org/apache/qpid/systest/rest/acl/ExchangeRestACLTest.java b/java/systests/src/main/java/org/apache/qpid/systest/rest/acl/ExchangeRestACLTest.java index 2eaaf7d988..0854befc0a 100644 --- a/java/systests/src/main/java/org/apache/qpid/systest/rest/acl/ExchangeRestACLTest.java +++ b/java/systests/src/main/java/org/apache/qpid/systest/rest/acl/ExchangeRestACLTest.java @@ -41,6 +41,8 @@ public class ExchangeRestACLTest extends QpidRestTestCase private static final String ALLOWED_USER = "user1"; private static final String DENIED_USER = "user2"; private String _queueName; + private String _exchangeName; + private String _exchangeUrl; @Override protected void customizeConfiguration() throws IOException @@ -75,85 +77,78 @@ public class ExchangeRestACLTest extends QpidRestTestCase Map queueData = new HashMap(); queueData.put(Queue.NAME, _queueName); queueData.put(Queue.DURABLE, Boolean.TRUE); - int status = getRestTestHelper().submitRequest("/rest/queue/test/" + _queueName, "PUT", queueData); + int status = getRestTestHelper().submitRequest("/rest/queue/test/test/" + _queueName, "PUT", queueData); assertEquals("Unexpected status", 201, status); + _exchangeName = getTestName(); + _exchangeUrl = "/rest/exchange/test/test/" + _exchangeName; } public void testCreateExchangeAllowed() throws Exception { getRestTestHelper().setUsernameAndPassword(ALLOWED_USER, ALLOWED_USER); - String exchangeName = getTestName(); - - int responseCode = createExchange(exchangeName); + int responseCode = createExchange(); assertEquals("Exchange creation should be allowed", 201, responseCode); - assertExchangeExists(exchangeName); + assertExchangeExists(); } public void testCreateExchangeDenied() throws Exception { getRestTestHelper().setUsernameAndPassword(DENIED_USER, DENIED_USER); - String exchangeName = getTestName(); - - int responseCode = createExchange(exchangeName); + int responseCode = createExchange(); assertEquals("Exchange creation should be denied", 403, responseCode); - assertExchangeDoesNotExist(exchangeName); + assertExchangeDoesNotExist(); } public void testDeleteExchangeAllowed() throws Exception { getRestTestHelper().setUsernameAndPassword(ALLOWED_USER, ALLOWED_USER); - String exchangeName = getTestName(); - - int responseCode = createExchange(exchangeName); + int responseCode = createExchange(); assertEquals("Exchange creation should be allowed", 201, responseCode); - assertExchangeExists(exchangeName); + assertExchangeExists(); + - responseCode = getRestTestHelper().submitRequest("/rest/exchange/test/" + exchangeName, "DELETE", null); + responseCode = getRestTestHelper().submitRequest(_exchangeUrl, "DELETE", null); assertEquals("Exchange deletion should be allowed", 200, responseCode); - assertExchangeDoesNotExist(TEST2_VIRTUALHOST); + assertExchangeDoesNotExist(); } public void testDeleteExchangeDenied() throws Exception { getRestTestHelper().setUsernameAndPassword(ALLOWED_USER, ALLOWED_USER); - String exchangeName = getTestName(); - - int responseCode = createExchange(exchangeName); + int responseCode = createExchange(); assertEquals("Exchange creation should be allowed", 201, responseCode); - assertExchangeExists(exchangeName); + assertExchangeExists(); getRestTestHelper().setUsernameAndPassword(DENIED_USER, DENIED_USER); - responseCode = getRestTestHelper().submitRequest("/rest/exchange/test/" + exchangeName, "DELETE", null); + responseCode = getRestTestHelper().submitRequest(_exchangeUrl, "DELETE", null); assertEquals("Exchange deletion should be denied", 403, responseCode); - assertExchangeExists(exchangeName); + assertExchangeExists(); } public void testSetExchangeAttributesAllowed() throws Exception { getRestTestHelper().setUsernameAndPassword(ALLOWED_USER, ALLOWED_USER); - String exchangeName = getTestName(); - - int responseCode = createExchange(exchangeName); + int responseCode = createExchange(); - assertExchangeExists(exchangeName); + assertExchangeExists(); Map attributes = new HashMap(); - attributes.put(Exchange.NAME, exchangeName); + attributes.put(Exchange.NAME, _exchangeName); attributes.put(Exchange.ALTERNATE_EXCHANGE, "my-alternate-exchange"); - responseCode = getRestTestHelper().submitRequest("/rest/exchange/test/" + exchangeName, "PUT", attributes); + responseCode = getRestTestHelper().submitRequest(_exchangeUrl, "PUT", attributes); assertEquals("Setting of exchange attribites should be allowed but it is currently unsupported", 409, responseCode); } @@ -161,18 +156,16 @@ public class ExchangeRestACLTest extends QpidRestTestCase { getRestTestHelper().setUsernameAndPassword(ALLOWED_USER, ALLOWED_USER); - String exchangeName = getTestName(); - - int responseCode = createExchange(exchangeName); - assertExchangeExists(exchangeName); + int responseCode = createExchange(); + assertExchangeExists(); getRestTestHelper().setUsernameAndPassword(DENIED_USER, DENIED_USER); Map attributes = new HashMap(); - attributes.put(Exchange.NAME, exchangeName); + attributes.put(Exchange.NAME, _exchangeName); attributes.put(Exchange.ALTERNATE_EXCHANGE, "my-alternate-exchange"); - responseCode = getRestTestHelper().submitRequest("/rest/exchange/test/" + exchangeName, "PUT", attributes); + responseCode = getRestTestHelper().submitRequest(_exchangeUrl, "PUT", attributes); assertEquals("Setting of exchange attribites should be allowed", 403, responseCode); } @@ -198,27 +191,27 @@ public class ExchangeRestACLTest extends QpidRestTestCase assertBindingDoesNotExist(bindingName); } - private int createExchange(String exchangeName) throws Exception + private int createExchange() throws Exception { Map attributes = new HashMap(); - attributes.put(Exchange.NAME, exchangeName); + attributes.put(Exchange.NAME, _exchangeName); attributes.put(Exchange.TYPE, "direct"); - return getRestTestHelper().submitRequest("/rest/exchange/test/" + exchangeName, "PUT", attributes); + return getRestTestHelper().submitRequest(_exchangeUrl, "PUT", attributes); } - private void assertExchangeDoesNotExist(String exchangeName) throws Exception + private void assertExchangeDoesNotExist() throws Exception { - assertExchangeExistence(exchangeName, false); + assertExchangeExistence(false); } - private void assertExchangeExists(String exchangeName) throws Exception + private void assertExchangeExists() throws Exception { - assertExchangeExistence(exchangeName, true); + assertExchangeExistence(true); } - private void assertExchangeExistence(String exchangeName, boolean exists) throws Exception + private void assertExchangeExistence(boolean exists) throws Exception { - List> exchanges = getRestTestHelper().getJsonAsList("/rest/exchange/test/" + exchangeName); + List> exchanges = getRestTestHelper().getJsonAsList(_exchangeUrl); assertEquals("Unexpected result", exists, !exchanges.isEmpty()); } @@ -229,7 +222,7 @@ public class ExchangeRestACLTest extends QpidRestTestCase attributes.put(Binding.QUEUE, _queueName); attributes.put(Binding.EXCHANGE, "amq.direct"); - int responseCode = getRestTestHelper().submitRequest("/rest/binding/test/amq.direct/" + _queueName + "/" + bindingName, "PUT", attributes); + int responseCode = getRestTestHelper().submitRequest("/rest/binding/test/test/amq.direct/" + _queueName + "/" + bindingName, "PUT", attributes); return responseCode; } @@ -245,7 +238,7 @@ public class ExchangeRestACLTest extends QpidRestTestCase private void assertBindingExistence(String bindingName, boolean exists) throws Exception { - List> bindings = getRestTestHelper().getJsonAsList("/rest/binding/test/amq.direct/" + _queueName + "/" + bindingName); + List> bindings = getRestTestHelper().getJsonAsList("/rest/binding/test/test/amq.direct/" + _queueName + "/" + bindingName); assertEquals("Unexpected result", exists, !bindings.isEmpty()); } } diff --git a/java/systests/src/main/java/org/apache/qpid/systest/rest/acl/QueueRestACLTest.java b/java/systests/src/main/java/org/apache/qpid/systest/rest/acl/QueueRestACLTest.java index dced81277e..8acf4ee762 100644 --- a/java/systests/src/main/java/org/apache/qpid/systest/rest/acl/QueueRestACLTest.java +++ b/java/systests/src/main/java/org/apache/qpid/systest/rest/acl/QueueRestACLTest.java @@ -36,6 +36,16 @@ public class QueueRestACLTest extends QpidRestTestCase { private static final String ALLOWED_USER = "user1"; private static final String DENIED_USER = "user2"; + private String _queueUrl; + private String _queueName; + + @Override + public void setUp() throws Exception + { + super.setUp(); + _queueName = getTestName(); + _queueUrl = "/rest/queue/test/test/" + _queueName; + } @Override protected void customizeConfiguration() throws IOException @@ -60,80 +70,72 @@ public class QueueRestACLTest extends QpidRestTestCase { getRestTestHelper().setUsernameAndPassword(ALLOWED_USER, ALLOWED_USER); - String queueName = getTestName(); - - int responseCode = createQueue(queueName); + int responseCode = createQueue(); assertEquals("Queue creation should be allowed", 201, responseCode); - assertQueueExists(queueName); + assertQueueExists(); } public void testCreateQueueDenied() throws Exception { getRestTestHelper().setUsernameAndPassword(DENIED_USER, DENIED_USER); - String queueName = getTestName(); - - int responseCode = createQueue(queueName); + int responseCode = createQueue(); assertEquals("Queue creation should be denied", 403, responseCode); - assertQueueDoesNotExist(queueName); + assertQueueDoesNotExist(); } public void testDeleteQueueAllowed() throws Exception { getRestTestHelper().setUsernameAndPassword(ALLOWED_USER, ALLOWED_USER); - String queueName = getTestName(); - - int responseCode = createQueue(queueName); + int responseCode = createQueue(); assertEquals("Queue creation should be allowed", 201, responseCode); - assertQueueExists(queueName); + assertQueueExists(); - responseCode = getRestTestHelper().submitRequest("/rest/queue/test/" + queueName, "DELETE", null); + responseCode = getRestTestHelper().submitRequest(_queueUrl, "DELETE", null); assertEquals("Queue deletion should be allowed", 200, responseCode); - assertQueueDoesNotExist(TEST2_VIRTUALHOST); + assertQueueDoesNotExist(); } public void testDeleteQueueDenied() throws Exception { getRestTestHelper().setUsernameAndPassword(ALLOWED_USER, ALLOWED_USER); - String queueName = getTestName(); - - int responseCode = createQueue(queueName); + int responseCode = createQueue(); assertEquals("Queue creation should be allowed", 201, responseCode); - assertQueueExists(queueName); + assertQueueExists(); getRestTestHelper().setUsernameAndPassword(DENIED_USER, DENIED_USER); - responseCode = getRestTestHelper().submitRequest("/rest/queue/test/" + queueName, "DELETE", null); + responseCode = getRestTestHelper().submitRequest(_queueUrl, "DELETE", null); assertEquals("Queue deletion should be denied", 403, responseCode); - assertQueueExists(queueName); + assertQueueExists(); } + + public void testSetQueueAttributesAllowed() throws Exception { getRestTestHelper().setUsernameAndPassword(ALLOWED_USER, ALLOWED_USER); - String queueName = getTestName(); - - int responseCode = createQueue(queueName); + int responseCode = createQueue(); - assertQueueExists(queueName); + assertQueueExists(); Map attributes = new HashMap(); - attributes.put(Queue.NAME, queueName); + attributes.put(Queue.NAME, _queueName); attributes.put(Queue.QUEUE_FLOW_CONTROL_SIZE_BYTES, 100000); attributes.put(Queue.QUEUE_FLOW_RESUME_SIZE_BYTES, 80000); - responseCode = getRestTestHelper().submitRequest("/rest/queue/test/" + queueName, "PUT", attributes); + responseCode = getRestTestHelper().submitRequest(_queueUrl, "PUT", attributes); assertEquals("Setting of queue attribites should be allowed", 200, responseCode); - Map queueData = getRestTestHelper().getJsonAsSingletonList("/rest/queue/test/" + queueName); + Map queueData = getRestTestHelper().getJsonAsSingletonList(_queueUrl); assertEquals("Unexpected " + Queue.QUEUE_FLOW_CONTROL_SIZE_BYTES, 100000, queueData.get(Queue.QUEUE_FLOW_CONTROL_SIZE_BYTES) ); assertEquals("Unexpected " + Queue.QUEUE_FLOW_RESUME_SIZE_BYTES, 80000, queueData.get(Queue.QUEUE_FLOW_RESUME_SIZE_BYTES) ); } @@ -142,47 +144,45 @@ public class QueueRestACLTest extends QpidRestTestCase { getRestTestHelper().setUsernameAndPassword(ALLOWED_USER, ALLOWED_USER); - String queueName = getTestName(); - - int responseCode = createQueue(queueName); - assertQueueExists(queueName); + int responseCode = createQueue(); + assertQueueExists(); getRestTestHelper().setUsernameAndPassword(DENIED_USER, DENIED_USER); Map attributes = new HashMap(); - attributes.put(Queue.NAME, queueName); + attributes.put(Queue.NAME, _queueName); attributes.put(Queue.QUEUE_FLOW_CONTROL_SIZE_BYTES, 100000); attributes.put(Queue.QUEUE_FLOW_RESUME_SIZE_BYTES, 80000); - responseCode = getRestTestHelper().submitRequest("/rest/queue/test/" + queueName, "PUT", attributes); + responseCode = getRestTestHelper().submitRequest(_queueUrl, "PUT", attributes); assertEquals("Setting of queue attribites should be allowed", 403, responseCode); - Map queueData = getRestTestHelper().getJsonAsSingletonList("/rest/queue/test/" + queueName); + Map queueData = getRestTestHelper().getJsonAsSingletonList(_queueUrl); assertEquals("Unexpected " + Queue.QUEUE_FLOW_CONTROL_SIZE_BYTES, 0, queueData.get(Queue.QUEUE_FLOW_CONTROL_SIZE_BYTES) ); assertEquals("Unexpected " + Queue.QUEUE_FLOW_RESUME_SIZE_BYTES, 0, queueData.get(Queue.QUEUE_FLOW_RESUME_SIZE_BYTES) ); } - private int createQueue(String queueName) throws Exception + private int createQueue() throws Exception { Map attributes = new HashMap(); - attributes.put(Queue.NAME, queueName); + attributes.put(Queue.NAME, _queueName); - return getRestTestHelper().submitRequest("/rest/queue/test/" + queueName, "PUT", attributes); + return getRestTestHelper().submitRequest(_queueUrl, "PUT", attributes); } - private void assertQueueDoesNotExist(String queueName) throws Exception + private void assertQueueDoesNotExist() throws Exception { - assertQueueExistence(queueName, false); + assertQueueExistence(false); } - private void assertQueueExists(String queueName) throws Exception + private void assertQueueExists() throws Exception { - assertQueueExistence(queueName, true); + assertQueueExistence(true); } - private void assertQueueExistence(String queueName, boolean exists) throws Exception + private void assertQueueExistence(boolean exists) throws Exception { - List> queues = getRestTestHelper().getJsonAsList("/rest/queue/test/" + queueName); + List> queues = getRestTestHelper().getJsonAsList(_queueUrl); assertEquals("Unexpected result", exists, !queues.isEmpty()); } } 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 8802ccac58..3436b06db0 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 @@ -48,7 +48,6 @@ import javax.naming.InitialContext; import org.slf4j.Logger; import org.slf4j.LoggerFactory; - import org.apache.qpid.client.AMQAnyDestination; import org.apache.qpid.client.AMQConnection; import org.apache.qpid.client.AMQDestination; @@ -57,9 +56,7 @@ import org.apache.qpid.client.AMQSession_0_10; import org.apache.qpid.client.message.QpidMessageProperties; import org.apache.qpid.jndi.PropertiesFileInitialContextFactory; import org.apache.qpid.messaging.Address; -import org.apache.qpid.server.model.VirtualHost; import org.apache.qpid.test.utils.QpidBrokerTestCase; -import org.apache.qpid.test.utils.TestBrokerConfiguration; import org.apache.qpid.transport.ExecutionErrorCode; public class AddressBasedDestinationTest extends QpidBrokerTestCase @@ -70,10 +67,6 @@ public class AddressBasedDestinationTest extends QpidBrokerTestCase @Override public void setUp() throws Exception { - TestBrokerConfiguration config = getBrokerConfiguration(); - config.setObjectAttribute(VirtualHost.class, TestBrokerConfiguration.ENTRY_NAME_VIRTUAL_HOST, VirtualHost.CONTEXT, - Collections.singletonMap("queue.maximumDeliveryAttempts","0")); - super.setUp(); _connection = getConnection() ; _connection.start(); 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 17485c5445..67c3f51d46 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 @@ -31,14 +31,12 @@ import javax.jms.MessageProducer; import javax.jms.Queue; import javax.jms.Session; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import org.apache.qpid.server.model.VirtualHost; import org.apache.qpid.server.store.MessageStore; import org.apache.qpid.server.store.SlowMessageStore; import org.apache.qpid.test.utils.QpidBrokerTestCase; -import org.apache.qpid.test.utils.TestBrokerConfiguration; +import org.apache.qpid.test.utils.TestUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * This tests that when the commit takes a long time(due to POST_COMMIT_DELAY) that the commit does not timeout @@ -66,8 +64,7 @@ public class SyncWaitDelayTest extends QpidBrokerTestCase messageStoreSettings.put(MessageStore.STORE_TYPE, SlowMessageStore.TYPE); messageStoreSettings.put(SlowMessageStore.DELAYS, slowMessageStoreDelays); - TestBrokerConfiguration config = getBrokerConfiguration(); - config.setObjectAttribute(VirtualHost.class, TestBrokerConfiguration.ENTRY_NAME_VIRTUAL_HOST, VirtualHost.MESSAGE_STORE_SETTINGS, messageStoreSettings); + TestUtils.createStoreWithVirtualHostEntry(messageStoreSettings, getBrokerConfiguration(), getTestProfileVirtualHostNodeType()); super.setUp(); 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 index 0e9256e1c6..60877b0cde 100755 --- 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 @@ -49,7 +49,6 @@ import javax.naming.NamingException; 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; @@ -66,6 +65,8 @@ import org.apache.qpid.server.configuration.updater.TaskExecutor; import org.apache.qpid.server.model.Port; import org.apache.qpid.server.model.Protocol; import org.apache.qpid.server.model.VirtualHost; +import org.apache.qpid.server.model.VirtualHostNode; +import org.apache.qpid.server.store.DurableConfigurationStore; import org.apache.qpid.server.store.MemoryMessageStore; import org.apache.qpid.server.store.MessageStore; import org.apache.qpid.server.virtualhost.StandardVirtualHost; @@ -246,12 +247,7 @@ public class QpidBrokerTestCase extends QpidTestCase configuration.setObjectAttribute(Port.class, TestBrokerConfiguration.ENTRY_NAME_JMX_PORT, Port.PORT, getManagementPort(actualPort) + JMXPORT_CONNECTORSERVER_OFFSET); String workDir = System.getProperty("QPID_WORK") + File.separator + TestBrokerConfiguration.ENTRY_NAME_VIRTUAL_HOST + File.separator + actualPort; - Map virtualHostSettings = configuration.getObjectAttributes(VirtualHost.class, TestBrokerConfiguration.ENTRY_NAME_VIRTUAL_HOST); - - @SuppressWarnings("unchecked") - Map storeSettings = (Map)virtualHostSettings.get(VirtualHost.MESSAGE_STORE_SETTINGS); - storeSettings.put(MessageStore.STORE_PATH, workDir); - configuration.setObjectAttribute(VirtualHost.class, TestBrokerConfiguration.ENTRY_NAME_VIRTUAL_HOST, VirtualHost.MESSAGE_STORE_SETTINGS, storeSettings); + configuration.setObjectAttribute(VirtualHostNode.class, TestBrokerConfiguration.ENTRY_NAME_VIRTUAL_HOST, DurableConfigurationStore.STORE_PATH, workDir); } return configuration; @@ -844,13 +840,13 @@ public class QpidBrokerTestCase extends QpidTestCase } /** - * Creates a new virtual host within the test virtualhost file. + * Creates a new virtual host node in broker configuration for given broker port * @param brokerPort broker port - * @param virtualHostName virtual host name + * @param virtualHostNodeName virtual host node name */ - protected void createTestVirtualHost(int brokerPort, String virtualHostName) + protected void createTestVirtualHostNode(int brokerPort, String virtualHostNodeName) { - String storeType = getTestProfileMessageStoreType(); + String storeType = getTestProfileVirtualHostNodeType(); String storeDir = null; if (System.getProperty("profile", "").startsWith("java-dby-mem")) @@ -859,19 +855,20 @@ public class QpidBrokerTestCase extends QpidTestCase } else if (!MemoryMessageStore.TYPE.equals(storeType)) { - storeDir = "${QPID_WORK}" + File.separator + virtualHostName + File.separator + brokerPort; + storeDir = "${QPID_WORK}" + File.separator + virtualHostNodeName + File.separator + brokerPort; } // add new virtual host configuration to the broker store Map attributes = new HashMap(); - attributes.put(VirtualHost.NAME, virtualHostName); - attributes.put(VirtualHost.TYPE, StandardVirtualHost.TYPE); - Map messageStoreSettings = new HashMap(); - messageStoreSettings.put(MessageStore.STORE_TYPE, storeType); - messageStoreSettings.put(MessageStore.STORE_PATH, storeDir); - attributes.put(VirtualHost.MESSAGE_STORE_SETTINGS, messageStoreSettings ); + attributes.put(VirtualHostNode.NAME, virtualHostNodeName); + attributes.put(VirtualHostNode.TYPE, storeType); + attributes.put(VirtualHostNode.IS_MESSAGE_STORE_PROVIDER, true); + if (storeDir != null) + { + attributes.put(DurableConfigurationStore.STORE_PATH, storeDir); + } int port = getPort(brokerPort); - getBrokerConfiguration(port).addObjectConfiguration(VirtualHost.class, attributes); + getBrokerConfiguration(port).addObjectConfiguration(VirtualHostNode.class, attributes); } /** 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 index c93a4c6556..8e3d1262e7 100644 --- 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 @@ -50,6 +50,7 @@ import org.apache.qpid.server.security.access.FileAccessControlProviderConstants import org.apache.qpid.server.store.ConfiguredObjectRecord; import org.apache.qpid.server.store.ConfiguredObjectRecordImpl; import org.apache.qpid.server.store.handler.ConfiguredObjectRecordHandler; +import org.apache.qpid.util.Strings; public class TestBrokerConfiguration { @@ -85,6 +86,34 @@ public class TestBrokerConfiguration intialStoreLocation, null, Collections.emptyMap()); + _store.visitConfiguredObjectRecords(new ConfiguredObjectRecordHandler() + { + @Override + public boolean handle(ConfiguredObjectRecord record) + { + Map attributes = record.getAttributes(); + String rawType = (String)attributes.get("type"); + if (rawType != null) + { + String interpolatedType = Strings.expand(rawType, false, Strings.ENV_VARS_RESOLVER, Strings.JAVA_SYS_PROPS_RESOLVER); + if (!interpolatedType.equals(rawType)) + { + setObjectAttribute(record, "type", interpolatedType); + } + } + return true; + } + + @Override + public void end() + { + } + + @Override + public void begin() + { + } + }); } public boolean setBrokerAttribute(String name, Object value) 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 index c651d3ec7f..16f3c3d82c 100644 --- 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 @@ -20,9 +20,27 @@ */ package org.apache.qpid.test.utils; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + import java.lang.management.ManagementFactory; import java.lang.management.ThreadInfo; import java.lang.management.ThreadMXBean; +import java.util.HashMap; +import java.util.Map; +import java.util.UUID; + +import org.apache.qpid.server.model.BrokerModel; +import org.apache.qpid.server.model.Model; +import org.apache.qpid.server.model.VirtualHost; +import org.apache.qpid.server.model.VirtualHostNode; +import org.apache.qpid.server.plugin.DurableConfigurationStoreFactory; +import org.apache.qpid.server.store.ConfiguredObjectRecordImpl; +import org.apache.qpid.server.store.DurableConfigurationStore; +import org.apache.qpid.server.store.JsonFileConfigStore; +import org.apache.qpid.server.store.MemoryMessageStore; +import org.apache.qpid.server.virtualhost.StandardVirtualHost; +import org.apache.qpid.util.Strings; public class TestUtils { @@ -51,4 +69,48 @@ public class TestUtils } return dump.toString(); } + + public static String createStoreWithVirtualHostEntry(Map messageStoreSettings, TestBrokerConfiguration config, String configStoreType) + { + UUID virtualHostId = UUID.randomUUID(); + Map virtualHostAttributes = new HashMap(); + virtualHostAttributes.put(VirtualHost.NAME, TestBrokerConfiguration.ENTRY_NAME_VIRTUAL_HOST); + virtualHostAttributes.put(VirtualHost.ID, virtualHostId); + virtualHostAttributes.put(VirtualHost.TYPE, StandardVirtualHost.TYPE); + virtualHostAttributes.put(VirtualHost.MESSAGE_STORE_SETTINGS, messageStoreSettings); + virtualHostAttributes.put(VirtualHost.MODEL_VERSION, BrokerModel.MODEL_VERSION); + + config.setObjectAttribute(VirtualHostNode.class, TestBrokerConfiguration.ENTRY_NAME_VIRTUAL_HOST, VirtualHostNode.IS_MESSAGE_STORE_PROVIDER, false); + // If using MMS, switch to split store with JSON config store. + if (MemoryMessageStore.TYPE.equals(configStoreType)) + { + configStoreType = JsonFileConfigStore.TYPE; + } + DurableConfigurationStoreFactory storeFactory = DurableConfigurationStoreFactory.FACTORY_LOADER.get(configStoreType); + DurableConfigurationStore store = storeFactory.createDurableConfigurationStore(); + + config.setObjectAttribute(VirtualHostNode.class, TestBrokerConfiguration.ENTRY_NAME_VIRTUAL_HOST, VirtualHostNode.TYPE, configStoreType); + + Map nodeAttributes = config.getObjectAttributes(VirtualHostNode.class, TestBrokerConfiguration.ENTRY_NAME_VIRTUAL_HOST); + String storePath = (String)nodeAttributes.get(DurableConfigurationStore.STORE_PATH); + String path = Strings.expand(storePath, false, Strings.JAVA_SYS_PROPS_RESOLVER, Strings.ENV_VARS_RESOLVER); + + Map attributes = new HashMap(nodeAttributes); + attributes.put(DurableConfigurationStore.STORE_PATH, path); + + VirtualHostNode virtualHostNode = mock(VirtualHostNode.class); + when(virtualHostNode.getModel()).thenReturn(BrokerModel.getInstance()); + when(virtualHostNode.getName()).thenReturn(TestBrokerConfiguration.ENTRY_NAME_VIRTUAL_HOST); + + try + { + store.openConfigurationStore(virtualHostNode, attributes); + store.create(new ConfiguredObjectRecordImpl(virtualHostId, VirtualHost.class.getSimpleName(), virtualHostAttributes)); + } + finally + { + store.closeConfigurationStore(); + } + return path; + } } -- cgit v1.2.1