diff options
8 files changed, 253 insertions, 163 deletions
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 91e73324bc..3eabaf1c73 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 @@ -1034,8 +1034,7 @@ public class ReplicatedEnvironmentFacade implements EnvironmentFacade, StateChan return new DbPing(repNode, (String)_configuration.getGroupName(), DB_PING_SOCKET_TIMEOUT).getNodeState(); } - // For testing only - int getNumberOfElectableGroupMembers() + public int getNumberOfElectableGroupMembers() { if (_state.get() != State.OPEN) { @@ -1044,6 +1043,11 @@ public class ReplicatedEnvironmentFacade implements EnvironmentFacade, StateChan return _environment.getGroup().getElectableNodes().size(); } + public boolean isMaster() + { + return ReplicatedEnvironment.State.MASTER.name().equals(getNodeState()); + } + public void setReplicationGroupListener(ReplicationGroupListener replicationGroupListener) { if (_replicationGroupListener.compareAndSet(null, replicationGroupListener)) @@ -1308,5 +1312,4 @@ public class ReplicatedEnvironmentFacade implements EnvironmentFacade, StateChan } } - } 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 index d23ccd1510..e978ab6c0b 100644 --- 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 @@ -347,6 +347,21 @@ public class BDBHAVirtualHostNodeImpl extends AbstractVirtualHostNode<BDBHAVirtu } } + @Override + protected void deleteVirtualHostIfExists() + { + ReplicatedEnvironmentFacade replicatedEnvironmentFacade = getReplicatedEnvironmentFacade(); + if (replicatedEnvironmentFacade != null && replicatedEnvironmentFacade.isMaster() + && replicatedEnvironmentFacade.getNumberOfElectableGroupMembers() == 1) + { + super.deleteVirtualHostIfExists(); + } + else + { + closeVirtualHostIfExist(); + } + } + private Set<InetSocketAddress> getRemoteNodeAddresses() { Set<InetSocketAddress> helpers = new HashSet<InetSocketAddress>(); @@ -381,7 +396,7 @@ public class BDBHAVirtualHostNodeImpl extends AbstractVirtualHostNode<BDBHAVirtu { try { - destroyVirtualHostIfExist(); + closeVirtualHostIfExist(); getConfigurationStore().getEnvironmentFacade().getEnvironment().flushLog(true); getEventLogger().message(getConfigurationStoreLogSubject(), ConfigStoreMessages.RECOVERY_START()); @@ -434,7 +449,7 @@ public class BDBHAVirtualHostNodeImpl extends AbstractVirtualHostNode<BDBHAVirtu { try { - destroyVirtualHostIfExist(); + closeVirtualHostIfExist(); Map<String, Object> hostAttributes = new HashMap<String, Object>(); hostAttributes.put(VirtualHost.MODEL_VERSION, BrokerModel.MODEL_VERSION); @@ -450,10 +465,10 @@ public class BDBHAVirtualHostNodeImpl extends AbstractVirtualHostNode<BDBHAVirtu private void onDetached() { - destroyVirtualHostIfExist(); + closeVirtualHostIfExist(); } - protected void destroyVirtualHostIfExist() + protected void closeVirtualHostIfExist() { VirtualHost<?,?,?> virtualHost = getVirtualHost(); if (virtualHost!= null) 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 index fb8d972fb3..347c91a18b 100644 --- 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 @@ -23,6 +23,7 @@ package org.apache.qpid.server.store.berkeleydb; import static org.mockito.Mockito.when; import java.io.File; +import java.util.Arrays; import java.util.Collection; import java.util.Collections; import java.util.HashMap; @@ -32,6 +33,7 @@ import java.util.Set; import java.util.UUID; import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicReference; import com.sleepycat.je.rep.ReplicatedEnvironment; import com.sleepycat.je.rep.ReplicationConfig; @@ -140,23 +142,13 @@ public class BDBHAVirtualHostNodeTest extends QpidTestCase attributes.put(BDBHAVirtualHostNode.REPLICATED_ENVIRONMENT_CONFIGURATION, Collections.singletonMap(ReplicationConfig.REP_STREAM_TIMEOUT, repStreamTimeout)); - VirtualHostNode<?> node = createHaVHN(attributes); + BDBHAVirtualHostNode<?> node = createHaVHN(attributes); final CountDownLatch virtualHostAddedLatch = new CountDownLatch(1); - node.addChangeListener(new ConfigurationChangeListener() + node.addChangeListener(new NoopConfigurationChangeListener() { @Override - public void stateChanged(ConfiguredObject object, State oldState, State newState) - { - } - - @Override - public void childRemoved(ConfiguredObject object, ConfiguredObject child) - { - } - - @Override - public void childAdded(ConfiguredObject object, ConfiguredObject child) + public void childAdded(ConfiguredObject<?> object, ConfiguredObject<?> child) { if (child instanceof VirtualHost) { @@ -164,15 +156,11 @@ public class BDBHAVirtualHostNodeTest extends QpidTestCase virtualHostAddedLatch.countDown(); } } - - @Override - public void attributeSet(ConfiguredObject object, String attributeName, Object oldAttributeValue, Object newAttributeValue) - { - } }); node.start(); - assertEquals(State.ACTIVE, node.getState()); + assertNodeRole(node, "MASTER", "REPLICA"); + assertEquals("Unexpected node state", State.ACTIVE, node.getState()); DurableConfigurationStore store = node.getConfigurationStore(); assertNotNull(store); @@ -222,10 +210,7 @@ public class BDBHAVirtualHostNodeTest extends QpidTestCase attributes.put(BDBHAVirtualHostNode.HELPER_ADDRESS, address); attributes.put(BDBHAVirtualHostNode.STORE_PATH, _bdbStorePath); - BDBHAVirtualHostNode<?> node = createHaVHN(attributes); - - node.start(); - assertEquals("Failed to activate node", State.ACTIVE, node.getState()); + BDBHAVirtualHostNode<?> node = createAndStartHaVHN(attributes); BDBMessageStore bdbMessageStore = (BDBMessageStore) node.getConfigurationStore(); ReplicatedEnvironment environment = (ReplicatedEnvironment) bdbMessageStore.getEnvironmentFacade().getEnvironment(); @@ -260,10 +245,7 @@ public class BDBHAVirtualHostNodeTest extends QpidTestCase node1Attributes.put(BDBHAVirtualHostNode.ADDRESS, helperAddress); node1Attributes.put(BDBHAVirtualHostNode.HELPER_ADDRESS, helperAddress); node1Attributes.put(BDBHAVirtualHostNode.STORE_PATH, _bdbStorePath + File.separator + "1"); - - BDBHAVirtualHostNode<?> node1 = createHaVHN(node1Attributes); - node1.start(); - assertEquals("Failed to activate node", State.ACTIVE, node1.getState()); + createAndStartHaVHN(node1Attributes); int node2PortNumber = getNextAvailable(node1PortNumber+1); @@ -275,10 +257,7 @@ public class BDBHAVirtualHostNodeTest extends QpidTestCase node2Attributes.put(BDBHAVirtualHostNode.ADDRESS, "localhost:" + node2PortNumber); node2Attributes.put(BDBHAVirtualHostNode.HELPER_ADDRESS, helperAddress); node2Attributes.put(BDBHAVirtualHostNode.STORE_PATH, _bdbStorePath + File.separator + "2"); - - BDBHAVirtualHostNode<?> node2 = createHaVHN(node2Attributes); - node2.start(); - assertEquals("Failed to activate node2", State.ACTIVE, node2.getState()); + createAndStartHaVHN(node2Attributes); int node3PortNumber = getNextAvailable(node2PortNumber+1); Map<String, Object> node3Attributes = new HashMap<String, Object>(); @@ -289,30 +268,9 @@ public class BDBHAVirtualHostNodeTest extends QpidTestCase node3Attributes.put(BDBHAVirtualHostNode.ADDRESS, "localhost:" + node3PortNumber); node3Attributes.put(BDBHAVirtualHostNode.HELPER_ADDRESS, helperAddress); node3Attributes.put(BDBHAVirtualHostNode.STORE_PATH, _bdbStorePath + File.separator + "3"); - BDBHAVirtualHostNode<?> node3 = createHaVHN(node3Attributes); - node3.start(); - assertEquals("Failed to activate node3", State.ACTIVE, node3.getState()); - - BDBHAVirtualHostNode<?> replica = null; - int findReplicaCount = 0; - while(replica == null) - { - for (BDBHAVirtualHostNode<?> node : _nodes) - { - if ("REPLICA".equals(node.getRole())) - { - replica = node; - break; - } - } + createAndStartHaVHN(node3Attributes); - Thread.sleep(100); - if (findReplicaCount > 20) - { - fail("Could not find a node is replica role"); - } - findReplicaCount++; - } + BDBHAVirtualHostNode<?> replica = awaitAndFindNodeInRole("REPLICA"); replica.setAttribute(BDBHAVirtualHostNode.ROLE, "REPLICA", "MASTER"); @@ -334,37 +292,21 @@ public class BDBHAVirtualHostNodeTest extends QpidTestCase node1Attributes.put(BDBHAVirtualHostNode.HELPER_ADDRESS, helperAddress); node1Attributes.put(BDBHAVirtualHostNode.STORE_PATH, _bdbStorePath + File.separator + "1"); - BDBHAVirtualHostNode<?> node1 = createHaVHN(node1Attributes); - node1.start(); - assertEquals("Failed to activate node", State.ACTIVE, node1.getState()); + BDBHAVirtualHostNode<?> node1 = createAndStartHaVHN(node1Attributes); + final AtomicReference<RemoteReplicationNode<?>> lastSeenReplica = new AtomicReference<>(); final CountDownLatch remoteNodeLatch = new CountDownLatch(2); - node1.addChangeListener(new ConfigurationChangeListener() + node1.addChangeListener(new NoopConfigurationChangeListener() { @Override - public void stateChanged(ConfiguredObject object, State oldState, State newState) - { - } - - @Override - public void childRemoved(ConfiguredObject object, ConfiguredObject child) - { - } - - @Override - public void childAdded(ConfiguredObject object, ConfiguredObject child) + public void childAdded(ConfiguredObject<?> object, ConfiguredObject<?> child) { if (child instanceof RemoteReplicationNode) { remoteNodeLatch.countDown(); + lastSeenReplica.set((RemoteReplicationNode<?>)child); } } - - @Override - public void attributeSet(ConfiguredObject object, String attributeName, Object oldAttributeValue, - Object newAttributeValue) - { - } }); int node2PortNumber = getNextAvailable(node1PortNumber+1); @@ -378,9 +320,7 @@ public class BDBHAVirtualHostNodeTest extends QpidTestCase node2Attributes.put(BDBHAVirtualHostNode.HELPER_ADDRESS, helperAddress); node2Attributes.put(BDBHAVirtualHostNode.STORE_PATH, _bdbStorePath + File.separator + "2"); - BDBHAVirtualHostNode<?> node2 = createHaVHN(node2Attributes); - node2.start(); - assertEquals("Failed to activate node2", State.ACTIVE, node2.getState()); + BDBHAVirtualHostNode<?> node2 = createAndStartHaVHN(node2Attributes); int node3PortNumber = getNextAvailable(node2PortNumber+1); Map<String, Object> node3Attributes = new HashMap<String, Object>(); @@ -391,41 +331,11 @@ public class BDBHAVirtualHostNodeTest extends QpidTestCase node3Attributes.put(BDBHAVirtualHostNode.ADDRESS, "localhost:" + node3PortNumber); node3Attributes.put(BDBHAVirtualHostNode.HELPER_ADDRESS, helperAddress); node3Attributes.put(BDBHAVirtualHostNode.STORE_PATH, _bdbStorePath + File.separator + "3"); - BDBHAVirtualHostNode<?> node3 = createHaVHN(node3Attributes); - node3.start(); - assertEquals("Failed to activate node3", State.ACTIVE, node3.getState()); + BDBHAVirtualHostNode<?> node3 = createAndStartHaVHN(node3Attributes); assertTrue("Replication nodes have not been seen during 5s", remoteNodeLatch.await(5, TimeUnit.SECONDS)); - BDBHARemoteReplicationNodeImpl replicaRemoteNode = null; - - long awaitReplicaRoleCount = 0; - while(replicaRemoteNode == null) - { - Collection<? extends RemoteReplicationNode> remoteNodes = node1.getRemoteReplicationNodes(); - if (remoteNodes != null) - { - for (RemoteReplicationNode node : remoteNodes) - { - BDBHARemoteReplicationNodeImpl bdbNode = (BDBHARemoteReplicationNodeImpl)node; - if ("REPLICA".equals(bdbNode.getRole())) - { - replicaRemoteNode = bdbNode; - break; - } - } - if (replicaRemoteNode != null) - { - break; - } - } - Thread.sleep(100); - if (awaitReplicaRoleCount > 50) - { - fail("Remote replication node is not in a REPLICA role: " + remoteNodes); - } - awaitReplicaRoleCount++; - } + BDBHARemoteReplicationNodeImpl replicaRemoteNode = (BDBHARemoteReplicationNodeImpl)lastSeenReplica.get(); replicaRemoteNode.setAttributes(Collections.<String,Object>singletonMap(BDBHARemoteReplicationNode.ROLE, "MASTER")); BDBHAVirtualHostNode<?> replica = replicaRemoteNode.getName().equals(node2.getName())? node2 : node3; @@ -447,10 +357,7 @@ public class BDBHAVirtualHostNodeTest extends QpidTestCase node1Attributes.put(BDBHAVirtualHostNode.HELPER_ADDRESS, helperAddress); node1Attributes.put(BDBHAVirtualHostNode.STORE_PATH, _bdbStorePath + File.separator + "1"); - BDBHAVirtualHostNode<?> node = createHaVHN(node1Attributes); - node.start(); - assertEquals("Failed to activate node", State.ACTIVE, node.getState()); - + BDBHAVirtualHostNode<?> node = createAndStartHaVHN(node1Attributes); assertNodeRole(node, "MASTER"); try @@ -479,10 +386,7 @@ public class BDBHAVirtualHostNodeTest extends QpidTestCase node1Attributes.put(BDBHAVirtualHostNode.ADDRESS, helperAddress); node1Attributes.put(BDBHAVirtualHostNode.HELPER_ADDRESS, helperAddress); node1Attributes.put(BDBHAVirtualHostNode.STORE_PATH, _bdbStorePath + File.separator + "1"); - - BDBHAVirtualHostNode<?> node1 = createHaVHN(node1Attributes); - node1.start(); - assertEquals("Failed to activate node", State.ACTIVE, node1.getState()); + createAndStartHaVHN(node1Attributes); int node2PortNumber = getNextAvailable(node1PortNumber+1); @@ -494,10 +398,7 @@ public class BDBHAVirtualHostNodeTest extends QpidTestCase node2Attributes.put(BDBHAVirtualHostNode.ADDRESS, "localhost:" + node2PortNumber); node2Attributes.put(BDBHAVirtualHostNode.HELPER_ADDRESS, helperAddress); node2Attributes.put(BDBHAVirtualHostNode.STORE_PATH, _bdbStorePath + File.separator + "2"); - - BDBHAVirtualHostNode<?> node2 = createHaVHN(node2Attributes); - node2.start(); - assertEquals("Failed to activate node2", State.ACTIVE, node2.getState()); + createAndStartHaVHN(node2Attributes); int node3PortNumber = getNextAvailable(node2PortNumber+1); Map<String, Object> node3Attributes = new HashMap<String, Object>(); @@ -508,9 +409,7 @@ public class BDBHAVirtualHostNodeTest extends QpidTestCase node3Attributes.put(BDBHAVirtualHostNode.ADDRESS, "localhost:" + node3PortNumber); node3Attributes.put(BDBHAVirtualHostNode.HELPER_ADDRESS, helperAddress); node3Attributes.put(BDBHAVirtualHostNode.STORE_PATH, _bdbStorePath + File.separator + "3"); - BDBHAVirtualHostNode<?> node3 = createHaVHN(node3Attributes); - node3.start(); - assertEquals("Failed to activate node3", State.ACTIVE, node3.getState()); + createAndStartHaVHN(node3Attributes); BDBHAVirtualHostNode<?> master = awaitAndFindNodeInRole("MASTER"); awaitRemoteNodes(master, 2); @@ -552,7 +451,7 @@ public class BDBHAVirtualHostNodeTest extends QpidTestCase } counter++; } - while(remoteNodes.size() != expectedNodeNumber && counter<50); + while(remoteNodes.size() != expectedNodeNumber && counter<100); assertEquals("Unexpected node number", expectedNodeNumber, node.getRemoteReplicationNodes().size()); } @@ -590,22 +489,67 @@ public class BDBHAVirtualHostNodeTest extends QpidTestCase private BDBHAVirtualHostNode<?> createHaVHN(Map<String, Object> attributes) { + @SuppressWarnings("unchecked") BDBHAVirtualHostNode<?> node = (BDBHAVirtualHostNode<?>) _objectFactory.create(VirtualHostNode.class, attributes, _broker); _nodes.add(node); return node; } - private void assertNodeRole(BDBHAVirtualHostNode<?> node, String roleName) throws InterruptedException + private void assertNodeRole(BDBHAVirtualHostNode<?> node, String... roleName) throws InterruptedException { - int awaitMastershipCount = 0; - while(!roleName.equals(node.getRole())) + int iterationCounter = 0; + boolean inRole =false; + do { - Thread.sleep(100); - if (awaitMastershipCount > 50) + for (String role : roleName) { - fail("Node " + node.getName() + " did not transit into role " + roleName); + if (role.equals(node.getRole())) + { + inRole = true; + break; + } } - awaitMastershipCount++; + if (!inRole) + { + Thread.sleep(100); + } + iterationCounter++; + } + while(!inRole && iterationCounter<50); + assertTrue("Node " + node.getName() + " did not transit into role " + Arrays.toString(roleName), inRole); + } + + private BDBHAVirtualHostNode<?> createAndStartHaVHN(Map<String, Object> attributes) throws InterruptedException + { + BDBHAVirtualHostNode<?> node = createHaVHN(attributes); + node.start(); + assertNodeRole(node, "MASTER", "REPLICA"); + assertEquals("Unexpected node state", State.ACTIVE, node.getState()); + return node; + } + + class NoopConfigurationChangeListener implements ConfigurationChangeListener + { + + @Override + public void stateChanged(ConfiguredObject<?> object, State oldState, State newState) + { + } + + @Override + public void childAdded(ConfiguredObject<?> object, ConfiguredObject<?> child) + { + } + + @Override + public void childRemoved(ConfiguredObject<?> object, ConfiguredObject<?> child) + { + } + + @Override + public void attributeSet(ConfiguredObject<?> object, String attributeName, Object oldAttributeValue, + Object newAttributeValue) + { } } } diff --git a/java/broker-core/src/main/java/org/apache/qpid/server/model/AbstractConfiguredObject.java b/java/broker-core/src/main/java/org/apache/qpid/server/model/AbstractConfiguredObject.java index e67191b744..812ffc618d 100644 --- a/java/broker-core/src/main/java/org/apache/qpid/server/model/AbstractConfiguredObject.java +++ b/java/broker-core/src/main/java/org/apache/qpid/server/model/AbstractConfiguredObject.java @@ -1324,6 +1324,16 @@ public abstract class AbstractConfiguredObject<X extends ConfiguredObject<X>> im return _attributeResolver; } + protected boolean isAttributePersisted(String name) + { + ConfiguredObjectAttribute<X,?> attr = (ConfiguredObjectAttribute<X, ?>) _attributeTypes.get(name); + if(attr != null) + { + return attr.isPersisted(); + } + return false; + } + //========================================================================================= static String interpolate(ConfiguredObject<?> object, String value) 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 dcacb1ae7f..afdd3a9136 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 @@ -378,7 +378,11 @@ public class JsonFileConfigStore implements DurableConfigurationStore List<UUID> ids = _idsByType.get(_rootClass.getSimpleName()); if (ids == null) { - throw new IllegalStateException("Root entry of type " + _rootClass.getSimpleName() + " does not exist in the store."); + return null; + } + if (ids.size() == 0) + { + return null; } return ids.get(0); } @@ -386,7 +390,16 @@ public class JsonFileConfigStore implements DurableConfigurationStore private void save() { UUID rootId = getRootId(); - Map<String, Object> data = build(_rootClass, rootId); + Map<String, Object> data = null; + + if (rootId == null) + { + data = Collections.emptyMap(); + } + else + { + data = build(_rootClass, rootId); + } try { 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 86c19941f8..26da911e1f 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 @@ -695,16 +695,6 @@ public abstract class AbstractVirtualHost<X extends AbstractVirtualHost<X>> exte _eventLogger.message(VirtualHostMessages.CLOSED(getName())); } - @Override - protected void changeAttributes(final Map<String, Object> attributes) - { - super.changeAttributes(attributes); - if (isDurable() && getState() != State.DELETED) - { - getDurableConfigurationStore().update(false, asObjectRecord()); - } - } - private void closeMessageStore() { if (getMessageStore() != null) @@ -1447,7 +1437,7 @@ public abstract class AbstractVirtualHost<X extends AbstractVirtualHost<X>> exte @Override public void stateChanged(final ConfiguredObject<?> object, final State oldState, final State newState) { - if (newState == State.DELETED) + if (object == AbstractVirtualHost.this && isDurable() && newState == State.DELETED) { getDurableConfigurationStore().remove(asObjectRecord()); object.removeChangeListener(this); @@ -1472,7 +1462,11 @@ public abstract class AbstractVirtualHost<X extends AbstractVirtualHost<X>> exte final Object oldAttributeValue, final Object newAttributeValue) { - getDurableConfigurationStore().update(false, asObjectRecord()); + if (object == AbstractVirtualHost.this && isDurable() && getState() != State.DELETED && isAttributePersisted(attributeName) + && !(attributeName.equals(VirtualHost.DESIRED_STATE) && newAttributeValue.equals(State.DELETED))) + { + getDurableConfigurationStore().update(false, asObjectRecord()); + } } } diff --git a/java/broker-core/src/main/java/org/apache/qpid/server/virtualhostnode/AbstractVirtualHostNode.java b/java/broker-core/src/main/java/org/apache/qpid/server/virtualhostnode/AbstractVirtualHostNode.java index 2f8860a3a0..f52558e298 100644 --- a/java/broker-core/src/main/java/org/apache/qpid/server/virtualhostnode/AbstractVirtualHostNode.java +++ b/java/broker-core/src/main/java/org/apache/qpid/server/virtualhostnode/AbstractVirtualHostNode.java @@ -194,23 +194,25 @@ public abstract class AbstractVirtualHostNode<X extends AbstractVirtualHostNode< @StateTransition( currentState = { State.ACTIVE, State.STOPPED, State.ERRORED}, desiredState = State.DELETED ) protected void doDelete() { - - close(); _state.set(State.DELETED); - VirtualHost<?, ?, ?> virtualHost = getVirtualHost(); - if (virtualHost != null) - { - virtualHost.delete(); - } - + deleteVirtualHostIfExists(); + close(); deleted(); - if (getConfigurationStore() instanceof MessageStore) { ((MessageStore)getConfigurationStore()).onDelete(); } } + protected void deleteVirtualHostIfExists() + { + VirtualHost<?, ?, ?> virtualHost = getVirtualHost(); + if (virtualHost != null) + { + virtualHost.delete(); + } + } + @StateTransition( currentState = { State.ACTIVE, State.ERRORED, State.UNINITIALIZED }, desiredState = State.STOPPED ) protected void doStop() { diff --git a/java/systests/src/main/java/org/apache/qpid/systest/management/jmx/MBeanLifeCycleTest.java b/java/systests/src/main/java/org/apache/qpid/systest/management/jmx/MBeanLifeCycleTest.java new file mode 100644 index 0000000000..629101b8db --- /dev/null +++ b/java/systests/src/main/java/org/apache/qpid/systest/management/jmx/MBeanLifeCycleTest.java @@ -0,0 +1,109 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.systest.management.jmx; + +import java.io.IOException; +import java.util.HashMap; +import java.util.Map; + +import javax.management.ObjectName; + +import org.apache.qpid.management.common.mbeans.ManagedBroker; +import org.apache.qpid.server.management.plugin.HttpManagement; +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.VirtualHostNode; +import org.apache.qpid.server.security.auth.manager.AnonymousAuthenticationManager; +import org.apache.qpid.systest.rest.QpidRestTestCase; +import org.apache.qpid.test.utils.JMXTestUtils; +import org.apache.qpid.test.utils.TestBrokerConfiguration; + +public class MBeanLifeCycleTest extends QpidRestTestCase +{ + + private JMXTestUtils _jmxUtils; + + @Override + public void setUp() throws Exception + { + super.setUp(); + _jmxUtils = new JMXTestUtils(this); + _jmxUtils.open(); + } + + @Override + protected void customizeConfiguration() throws IOException + { + TestBrokerConfiguration config = getBrokerConfiguration(); + config.addHttpManagementConfiguration(); + config.setObjectAttribute(Port.class, TestBrokerConfiguration.ENTRY_NAME_HTTP_PORT, Port.PORT, getRestTestHelper().getHttpPort()); + + Map<String, Object> anonymousProviderAttributes = new HashMap<String, Object>(); + anonymousProviderAttributes.put(AuthenticationProvider.TYPE, AnonymousAuthenticationManager.PROVIDER_TYPE); + anonymousProviderAttributes.put(AuthenticationProvider.NAME, ANONYMOUS_AUTHENTICATION_PROVIDER); + config.addObjectConfiguration(AuthenticationProvider.class, anonymousProviderAttributes); + + // set password authentication provider on http port for the tests + config.setObjectAttribute(Port.class, TestBrokerConfiguration.ENTRY_NAME_HTTP_PORT, Port.AUTHENTICATION_PROVIDER, + TestBrokerConfiguration.ENTRY_NAME_AUTHENTICATION_PROVIDER); + config.setObjectAttribute(Plugin.class, TestBrokerConfiguration.ENTRY_NAME_HTTP_MANAGEMENT, HttpManagement.HTTP_BASIC_AUTHENTICATION_ENABLED, true); + getBrokerConfiguration().addJmxManagementConfiguration(); + } + + @Override + public void tearDown() throws Exception + { + if (_jmxUtils != null) + { + _jmxUtils.close(); + } + super.tearDown(); + } + + public void testVirtualHostMBeanIsRegisteredOnVirtualHostCreation() throws Exception + { + String nodeName = "tmp"; + Map<String, Object> nodeData = new HashMap<String, Object>(); + nodeData.put(VirtualHostNode.NAME, nodeName); + nodeData.put(VirtualHostNode.TYPE, "Memory"); + nodeData.put(VirtualHostNode.IS_MESSAGE_STORE_PROVIDER, true); + int status = getRestTestHelper().submitRequest("virtualhostnode/" + nodeName, "PUT", nodeData); + assertEquals("Unexpected code", 201, status); + + ManagedBroker managedBroker = _jmxUtils.getManagedBroker(nodeName); + assertNotNull("Host mBean is not created", managedBroker); + } + + public void testVirtualHostMBeanIsUnregisteredOnVirtualHostDeletion() throws Exception + { + String query = "org.apache.qpid:type=VirtualHost.VirtualHostManager,VirtualHost=" + + ObjectName.quote(TEST2_VIRTUALHOST) + ",*"; + boolean mBeanExists =_jmxUtils.doesManagedObjectExist(query); + assertTrue("Host mBean is not registered", mBeanExists); + + int status = getRestTestHelper().submitRequest("virtualhostnode/" + TEST2_VIRTUALHOST, "DELETE"); + assertEquals("Unexpected code", 200, status); + + mBeanExists =_jmxUtils.doesManagedObjectExist(query); + assertFalse("Host mBean is not unregistered", mBeanExists); + } +} |