You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@qpid.apache.org by or...@apache.org on 2014/05/24 21:39:57 UTC

svn commit: r1597340 - in /qpid/trunk/qpid/java: bdbstore/src/main/java/org/apache/qpid/server/store/berkeleydb/replication/ bdbstore/src/main/java/org/apache/qpid/server/virtualhostnode/berkeleydb/ bdbstore/src/test/java/org/apache/qpid/server/store/b...

Author: orudyy
Date: Sat May 24 19:39:56 2014
New Revision: 1597340

URL: http://svn.apache.org/r1597340
Log:
QPID-5715: On virtual host node deletion delete virtual host first, in order to allow listeners to hear virtual host deletion. JMX Management needs to unregister virtual host MBean on host deletion

Added:
    qpid/trunk/qpid/java/systests/src/main/java/org/apache/qpid/systest/management/jmx/MBeanLifeCycleTest.java
Modified:
    qpid/trunk/qpid/java/bdbstore/src/main/java/org/apache/qpid/server/store/berkeleydb/replication/ReplicatedEnvironmentFacade.java
    qpid/trunk/qpid/java/bdbstore/src/main/java/org/apache/qpid/server/virtualhostnode/berkeleydb/BDBHAVirtualHostNodeImpl.java
    qpid/trunk/qpid/java/bdbstore/src/test/java/org/apache/qpid/server/store/berkeleydb/BDBHAVirtualHostNodeTest.java
    qpid/trunk/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/AbstractConfiguredObject.java
    qpid/trunk/qpid/java/broker-core/src/main/java/org/apache/qpid/server/store/JsonFileConfigStore.java
    qpid/trunk/qpid/java/broker-core/src/main/java/org/apache/qpid/server/virtualhost/AbstractVirtualHost.java
    qpid/trunk/qpid/java/broker-core/src/main/java/org/apache/qpid/server/virtualhostnode/AbstractVirtualHostNode.java

Modified: qpid/trunk/qpid/java/bdbstore/src/main/java/org/apache/qpid/server/store/berkeleydb/replication/ReplicatedEnvironmentFacade.java
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/java/bdbstore/src/main/java/org/apache/qpid/server/store/berkeleydb/replication/ReplicatedEnvironmentFacade.java?rev=1597340&r1=1597339&r2=1597340&view=diff
==============================================================================
--- qpid/trunk/qpid/java/bdbstore/src/main/java/org/apache/qpid/server/store/berkeleydb/replication/ReplicatedEnvironmentFacade.java (original)
+++ qpid/trunk/qpid/java/bdbstore/src/main/java/org/apache/qpid/server/store/berkeleydb/replication/ReplicatedEnvironmentFacade.java Sat May 24 19:39:56 2014
@@ -1034,8 +1034,7 @@ public class ReplicatedEnvironmentFacade
         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
         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
         }
 
     }
-
 }

Modified: qpid/trunk/qpid/java/bdbstore/src/main/java/org/apache/qpid/server/virtualhostnode/berkeleydb/BDBHAVirtualHostNodeImpl.java
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/java/bdbstore/src/main/java/org/apache/qpid/server/virtualhostnode/berkeleydb/BDBHAVirtualHostNodeImpl.java?rev=1597340&r1=1597339&r2=1597340&view=diff
==============================================================================
--- qpid/trunk/qpid/java/bdbstore/src/main/java/org/apache/qpid/server/virtualhostnode/berkeleydb/BDBHAVirtualHostNodeImpl.java (original)
+++ qpid/trunk/qpid/java/bdbstore/src/main/java/org/apache/qpid/server/virtualhostnode/berkeleydb/BDBHAVirtualHostNodeImpl.java Sat May 24 19:39:56 2014
@@ -347,6 +347,21 @@ public class BDBHAVirtualHostNodeImpl ex
         }
     }
 
+    @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 ex
     {
         try
         {
-            destroyVirtualHostIfExist();
+            closeVirtualHostIfExist();
             getConfigurationStore().getEnvironmentFacade().getEnvironment().flushLog(true);
 
             getEventLogger().message(getConfigurationStoreLogSubject(), ConfigStoreMessages.RECOVERY_START());
@@ -434,7 +449,7 @@ public class BDBHAVirtualHostNodeImpl ex
     {
         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 ex
 
     private void onDetached()
     {
-        destroyVirtualHostIfExist();
+        closeVirtualHostIfExist();
     }
 
-    protected void destroyVirtualHostIfExist()
+    protected void closeVirtualHostIfExist()
     {
         VirtualHost<?,?,?> virtualHost = getVirtualHost();
         if (virtualHost!= null)

Modified: qpid/trunk/qpid/java/bdbstore/src/test/java/org/apache/qpid/server/store/berkeleydb/BDBHAVirtualHostNodeTest.java
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/java/bdbstore/src/test/java/org/apache/qpid/server/store/berkeleydb/BDBHAVirtualHostNodeTest.java?rev=1597340&r1=1597339&r2=1597340&view=diff
==============================================================================
--- qpid/trunk/qpid/java/bdbstore/src/test/java/org/apache/qpid/server/store/berkeleydb/BDBHAVirtualHostNodeTest.java (original)
+++ qpid/trunk/qpid/java/bdbstore/src/test/java/org/apache/qpid/server/store/berkeleydb/BDBHAVirtualHostNodeTest.java Sat May 24 19:39:56 2014
@@ -23,6 +23,7 @@ package org.apache.qpid.server.store.ber
 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 ex
         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 ex
                     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 ex
         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 ex
         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 ex
         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 ex
         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 ex
         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 ex
         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 ex
         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 ex
         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 ex
         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 ex
         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 ex
         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 ex
             }
             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 ex
 
     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)
+        {
         }
     }
 }

Modified: qpid/trunk/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/AbstractConfiguredObject.java
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/AbstractConfiguredObject.java?rev=1597340&r1=1597339&r2=1597340&view=diff
==============================================================================
--- qpid/trunk/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/AbstractConfiguredObject.java (original)
+++ qpid/trunk/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/AbstractConfiguredObject.java Sat May 24 19:39:56 2014
@@ -1324,6 +1324,16 @@ public abstract class AbstractConfigured
         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)

Modified: qpid/trunk/qpid/java/broker-core/src/main/java/org/apache/qpid/server/store/JsonFileConfigStore.java
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/java/broker-core/src/main/java/org/apache/qpid/server/store/JsonFileConfigStore.java?rev=1597340&r1=1597339&r2=1597340&view=diff
==============================================================================
--- qpid/trunk/qpid/java/broker-core/src/main/java/org/apache/qpid/server/store/JsonFileConfigStore.java (original)
+++ qpid/trunk/qpid/java/broker-core/src/main/java/org/apache/qpid/server/store/JsonFileConfigStore.java Sat May 24 19:39:56 2014
@@ -378,7 +378,11 @@ public class JsonFileConfigStore impleme
         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 impleme
     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
         {

Modified: qpid/trunk/qpid/java/broker-core/src/main/java/org/apache/qpid/server/virtualhost/AbstractVirtualHost.java
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/java/broker-core/src/main/java/org/apache/qpid/server/virtualhost/AbstractVirtualHost.java?rev=1597340&r1=1597339&r2=1597340&view=diff
==============================================================================
--- qpid/trunk/qpid/java/broker-core/src/main/java/org/apache/qpid/server/virtualhost/AbstractVirtualHost.java (original)
+++ qpid/trunk/qpid/java/broker-core/src/main/java/org/apache/qpid/server/virtualhost/AbstractVirtualHost.java Sat May 24 19:39:56 2014
@@ -695,16 +695,6 @@ public abstract class AbstractVirtualHos
         _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 AbstractVirtualHos
         @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 AbstractVirtualHos
                                  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());
+            }
         }
     }
 

Modified: qpid/trunk/qpid/java/broker-core/src/main/java/org/apache/qpid/server/virtualhostnode/AbstractVirtualHostNode.java
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/java/broker-core/src/main/java/org/apache/qpid/server/virtualhostnode/AbstractVirtualHostNode.java?rev=1597340&r1=1597339&r2=1597340&view=diff
==============================================================================
--- qpid/trunk/qpid/java/broker-core/src/main/java/org/apache/qpid/server/virtualhostnode/AbstractVirtualHostNode.java (original)
+++ qpid/trunk/qpid/java/broker-core/src/main/java/org/apache/qpid/server/virtualhostnode/AbstractVirtualHostNode.java Sat May 24 19:39:56 2014
@@ -194,23 +194,25 @@ public abstract class AbstractVirtualHos
     @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()
     {

Added: qpid/trunk/qpid/java/systests/src/main/java/org/apache/qpid/systest/management/jmx/MBeanLifeCycleTest.java
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/java/systests/src/main/java/org/apache/qpid/systest/management/jmx/MBeanLifeCycleTest.java?rev=1597340&view=auto
==============================================================================
--- qpid/trunk/qpid/java/systests/src/main/java/org/apache/qpid/systest/management/jmx/MBeanLifeCycleTest.java (added)
+++ qpid/trunk/qpid/java/systests/src/main/java/org/apache/qpid/systest/management/jmx/MBeanLifeCycleTest.java Sat May 24 19:39:56 2014
@@ -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);
+    }
+}



---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@qpid.apache.org
For additional commands, e-mail: commits-help@qpid.apache.org