Author: rgodfrey
Date: Sat Jul 23 19:30:45 2016
New Revision: 1753882

URL: http://svn.apache.org/viewvc?rev=1753882&view=rev
Log:
QPID-7279 : Differentiate "recovering" for the first time from an initial 
config, from real recovery... and in the former case assume any secure fields 
are unencrypted and thus need to be encrypted and saved after recovery

Removed:
    
qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/store/ResolvedObject.java
Modified:
    
qpid/java/trunk/bdbstore/src/main/java/org/apache/qpid/server/store/berkeleydb/BDBConfigurationStore.java
    
qpid/java/trunk/bdbstore/src/main/java/org/apache/qpid/server/virtualhost/berkeleydb/BDBHAReplicaVirtualHostImpl.java
    
qpid/java/trunk/bdbstore/src/main/java/org/apache/qpid/server/virtualhostnode/berkeleydb/BDBHAVirtualHostNodeImpl.java
    
qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/configuration/store/ManagementModeStoreHandler.java
    
qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/model/AbstractConfiguredObject.java
    
qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/model/AbstractSystemConfig.java
    
qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/model/ConfiguredObject.java
    
qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/model/VirtualHost.java
    
qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/store/AbstractJDBCConfigurationStore.java
    
qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/store/AbstractMemoryStore.java
    
qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/store/BrokerStoreUpgraderAndRecoverer.java
    
qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/store/DurableConfigurationStore.java
    
qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/store/GenericRecoverer.java
    
qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/store/GenericStoreUpgrader.java
    
qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/store/JsonFileConfigStore.java
    
qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/store/NullMessageStore.java
    
qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/store/VirtualHostStoreUpgraderAndRecoverer.java
    
qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/store/handler/ConfiguredObjectRecordHandler.java
    
qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/virtualhost/AbstractVirtualHost.java
    
qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/virtualhostnode/AbstractStandardVirtualHostNode.java
    
qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/virtualhostnode/RedirectingVirtualHostImpl.java
    
qpid/java/trunk/broker-core/src/test/java/org/apache/qpid/server/configuration/store/ManagementModeStoreHandlerTest.java
    
qpid/java/trunk/broker-core/src/test/java/org/apache/qpid/server/logging/BrokerMemoryLoggerTest.java
    
qpid/java/trunk/broker-core/src/test/java/org/apache/qpid/server/model/VirtualHostTest.java
    
qpid/java/trunk/broker-core/src/test/java/org/apache/qpid/server/store/AbstractDurableConfigurationStoreTestCase.java
    
qpid/java/trunk/broker-core/src/test/java/org/apache/qpid/server/store/BrokerRecovererTest.java
    
qpid/java/trunk/broker-core/src/test/java/org/apache/qpid/server/store/BrokerStoreUpgraderAndRecovererTest.java
    
qpid/java/trunk/broker-core/src/test/java/org/apache/qpid/server/store/JsonFileConfigStoreTest.java
    
qpid/java/trunk/broker-core/src/test/java/org/apache/qpid/server/store/VirtualHostStoreUpgraderAndRecovererTest.java
    
qpid/java/trunk/broker-core/src/test/java/org/apache/qpid/server/virtualhostnode/AbstractStandardVirtualHostNodeTest.java
    
qpid/java/trunk/broker-plugins/derby-store/src/main/java/org/apache/qpid/server/store/derby/DerbyConfigurationStore.java
    
qpid/java/trunk/broker-plugins/jdbc-store/src/main/java/org/apache/qpid/server/store/jdbc/GenericJDBCConfigurationStore.java
    
qpid/java/trunk/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/filter/ExceptionHandlingFilter.java
    
qpid/java/trunk/systests/src/main/java/org/apache/qpid/test/utils/AbstractBrokerHolder.java
    
qpid/java/trunk/systests/src/main/java/org/apache/qpid/test/utils/TestBrokerConfiguration.java

Modified: 
qpid/java/trunk/bdbstore/src/main/java/org/apache/qpid/server/store/berkeleydb/BDBConfigurationStore.java
URL: 
http://svn.apache.org/viewvc/qpid/java/trunk/bdbstore/src/main/java/org/apache/qpid/server/store/berkeleydb/BDBConfigurationStore.java?rev=1753882&r1=1753881&r2=1753882&view=diff
==============================================================================
--- 
qpid/java/trunk/bdbstore/src/main/java/org/apache/qpid/server/store/berkeleydb/BDBConfigurationStore.java
 (original)
+++ 
qpid/java/trunk/bdbstore/src/main/java/org/apache/qpid/server/store/berkeleydb/BDBConfigurationStore.java
 Sat Jul 23 19:30:45 2016
@@ -20,12 +20,16 @@
  */
 package org.apache.qpid.server.store.berkeleydb;
 
+import static 
org.apache.qpid.server.store.berkeleydb.BDBConfigurationStore.State.CLOSED;
+import static 
org.apache.qpid.server.store.berkeleydb.BDBConfigurationStore.State.CONFIGURED;
+import static 
org.apache.qpid.server.store.berkeleydb.BDBConfigurationStore.State.OPEN;
 import static 
org.apache.qpid.server.store.berkeleydb.BDBUtils.DEFAULT_DATABASE_CONFIG;
 import static 
org.apache.qpid.server.store.berkeleydb.BDBUtils.abortTransactionSafely;
 import static 
org.apache.qpid.server.store.berkeleydb.BDBUtils.closeCursorSafely;
 
 import java.io.File;
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.Collection;
 import java.util.HashMap;
 import java.util.Map;
@@ -71,7 +75,9 @@ public class BDBConfigurationStore imple
     private static final String CONFIGURED_OBJECTS_DB_NAME = 
"CONFIGURED_OBJECTS";
     private static final String CONFIGURED_OBJECT_HIERARCHY_DB_NAME = 
"CONFIGURED_OBJECT_HIERARCHY";
 
-    private final AtomicBoolean _configurationStoreOpen = new AtomicBoolean();
+    enum State { CLOSED, CONFIGURED, OPEN };
+    private State _state = State.CLOSED;
+    private final Object _lock = new Object();
 
     private final EnvironmentFacadeFactory _environmentFacadeFactory;
 
@@ -82,8 +88,6 @@ public class BDBConfigurationStore imple
 
     private ConfiguredObject<?> _parent;
     private final Class<? extends ConfiguredObject> _rootClass;
-    private boolean _overwrite;
-    private ConfiguredObjectRecord[] _initialRecords;
 
     public BDBConfigurationStore(final Class<? extends ConfiguredObject> 
rootClass)
     {
@@ -97,67 +101,123 @@ public class BDBConfigurationStore imple
     }
 
     @Override
-    public void openConfigurationStore(ConfiguredObject<?> parent,
-                                       final boolean overwrite,
-                                       final ConfiguredObjectRecord... 
initialRecords)
+    public void init(ConfiguredObject<?> parent)
     {
-        if (_configurationStoreOpen.compareAndSet(false,  true))
+        synchronized (_lock)
         {
-            _parent = parent;
-
-            if (_environmentFacade == null)
+            if(_state == OPEN && _parent == parent)
+            {
+                _state = CONFIGURED;
+            }
+            else if(_state == CONFIGURED && _parent == parent)
             {
-                _environmentFacade = 
_environmentFacadeFactory.createEnvironmentFacade(parent);
-                _overwrite = overwrite;
-                _initialRecords = initialRecords;
+                _state = CONFIGURED;
             }
             else
             {
-                throw new IllegalStateException("The database have been 
already opened as message store");
+                changeState(CLOSED, CONFIGURED);
+                _parent = parent;
+
+                if (_environmentFacade == null)
+                {
+                    _environmentFacade = 
_environmentFacadeFactory.createEnvironmentFacade(parent);
+                }
+                else
+                {
+                    throw new IllegalStateException("The database have been 
already opened as message store");
+                }
             }
         }
+
     }
 
-    private void clearConfigurationRecords()
+    public String getState()
     {
-        checkConfigurationStoreOpen();
-
-        _environmentFacade.clearDatabase(CONFIGURED_OBJECTS_DB_NAME, 
DEFAULT_DATABASE_CONFIG);
-        _environmentFacade.clearDatabase(CONFIGURED_OBJECT_HIERARCHY_DB_NAME, 
DEFAULT_DATABASE_CONFIG);
+        return _state.toString();
     }
 
+
+
     @Override
     public void upgradeStoreStructure() throws StoreException
     {
         try
         {
             _environmentFacade.upgradeIfNecessary(_parent);
-            if(_overwrite)
+        }
+        catch (RuntimeException e)
+        {
+            throw _environmentFacade.handleDatabaseException("Cannot upgrade 
store", e);
+        }
+    }
+
+    @Override
+    public boolean openConfigurationStore(ConfiguredObjectRecordHandler 
handler,
+                                          final ConfiguredObjectRecord... 
initialRecords)
+    {
+        changeState(CONFIGURED, OPEN);
+        try
+        {
+            Collection<? extends ConfiguredObjectRecord> records = 
doVisitAllConfiguredObjectRecords();
+
+            boolean empty = records.isEmpty();
+
+            if(empty)
             {
-                clearConfigurationRecords();
-                _overwrite = false;
+                records = Arrays.asList(initialRecords);
+
+                com.sleepycat.je.Transaction txn = null;
+                try
+                {
+                    txn = _environmentFacade.beginTransaction(null);
+                    for(ConfiguredObjectRecord record : records)
+                    {
+                        update(true, record, txn);
+                    }
+                    txn.commit();
+                    txn = null;
+                }
+                catch (RuntimeException e)
+                {
+                    throw _environmentFacade.handleDatabaseException("Error 
updating configuration details within the store: " + e,e);
+                }
+                finally
+                {
+                    if (txn != null)
+                    {
+                        abortTransactionSafely(txn, _environmentFacade);
+                    }
+                }
+
+
             }
-            if(getConfiguredObjectsDb().count() == 0l)
+
+            for (ConfiguredObjectRecord record : records)
             {
-                update(true, _initialRecords);
+                handler.handle(record);
             }
-            _initialRecords = new ConfiguredObjectRecord[0];
+            return empty;
         }
         catch (RuntimeException e)
         {
-            throw _environmentFacade.handleDatabaseException("Cannot upgrade 
store", e);
+            throw _environmentFacade.handleDatabaseException("Cannot visit 
configured object records", e);
         }
     }
+
     @Override
-    public void visitConfiguredObjectRecords(ConfiguredObjectRecordHandler 
handler)
+    public void reload(ConfiguredObjectRecordHandler handler)
     {
-        checkConfigurationStoreOpen();
+        assertState(OPEN);
 
         try
         {
-            handler.begin();
-            doVisitAllConfiguredObjectRecords(handler);
-            handler.end();
+            Collection<? extends ConfiguredObjectRecord> records = 
doVisitAllConfiguredObjectRecords();
+
+            for (ConfiguredObjectRecord record : records)
+            {
+                handler.handle(record);
+
+            }
         }
         catch (RuntimeException e)
         {
@@ -165,7 +225,8 @@ public class BDBConfigurationStore imple
         }
     }
 
-    private void 
doVisitAllConfiguredObjectRecords(ConfiguredObjectRecordHandler handler)
+
+    private Collection<? extends ConfiguredObjectRecord> 
doVisitAllConfiguredObjectRecords()
     {
         Map<UUID, BDBConfiguredObjectRecord> configuredObjects = new 
HashMap<UUID, BDBConfiguredObjectRecord>();
         Cursor objectsCursor = null;
@@ -208,15 +269,7 @@ public class BDBConfigurationStore imple
             closeCursorSafely(objectsCursor, _environmentFacade);
             closeCursorSafely(hierarchyCursor, _environmentFacade);
         }
-
-        for (ConfiguredObjectRecord record : configuredObjects.values())
-        {
-            boolean shouldContinue = handler.handle(record);
-            if (!shouldContinue)
-            {
-                break;
-            }
-        }
+        return configuredObjects.values();
 
     }
 
@@ -228,13 +281,16 @@ public class BDBConfigurationStore imple
     @Override
     public void closeConfigurationStore() throws StoreException
     {
-        if (_configurationStoreOpen.compareAndSet(true, false))
+        synchronized (_lock)
         {
-            if (!_providedMessageStore.isMessageStoreOpen())
-            {
-                closeEnvironment();
-            }
+            _state = CLOSED;
         }
+
+        if (!_providedMessageStore.isMessageStoreOpen())
+        {
+            closeEnvironment();
+        }
+
     }
 
     private void closeEnvironment()
@@ -256,7 +312,7 @@ public class BDBConfigurationStore imple
     @Override
     public void create(ConfiguredObjectRecord configuredObject) throws 
StoreException
     {
-        checkConfigurationStoreOpen();
+        assertState(OPEN);
 
         if (LOGGER.isDebugEnabled())
         {
@@ -288,7 +344,7 @@ public class BDBConfigurationStore imple
     @Override
     public UUID[] remove(final ConfiguredObjectRecord... objects) throws 
StoreException
     {
-        checkConfigurationStoreOpen();
+        assertState(OPEN);
 
         com.sleepycat.je.Transaction txn = null;
         try
@@ -324,7 +380,7 @@ public class BDBConfigurationStore imple
     @Override
     public void update(boolean createIfNecessary, ConfiguredObjectRecord... 
records) throws StoreException
     {
-        checkConfigurationStoreOpen();
+        assertState(OPEN);
 
         com.sleepycat.je.Transaction txn = null;
         try
@@ -477,14 +533,6 @@ public class BDBConfigurationStore imple
         return _providedPreferenceStore;
     }
 
-    private void checkConfigurationStoreOpen()
-    {
-        if (!isConfigurationStoreOpen())
-        {
-            throw new IllegalStateException("Configuration store is not open");
-        }
-    }
-
     @Override
     public void onDelete(ConfiguredObject<?> parent)
     {
@@ -506,11 +554,6 @@ public class BDBConfigurationStore imple
         }
     }
 
-    private boolean isConfigurationStoreOpen()
-    {
-        return _configurationStoreOpen.get();
-    }
-
     private Database getConfiguredObjectsDb()
     {
         return _environmentFacade.openDatabase(CONFIGURED_OBJECTS_DB_NAME, 
DEFAULT_DATABASE_CONFIG);
@@ -649,4 +692,35 @@ public class BDBConfigurationStore imple
             return LOGGER;
         }
     }
+
+    private void assertState(State state)
+    {
+        synchronized (_lock)
+        {
+            if(_state != state)
+            {
+                throw new IllegalStateException("The store must be in state " 
+ state + " to perform this operation, but it is in state " + _state + " 
instead");
+            }
+        }
+    }
+
+    private void changeState(State oldState, State newState)
+    {
+        synchronized (_lock)
+        {
+            assertState(oldState);
+            _state = newState;
+        }
+    }
+
+
+    public boolean isOpen()
+    {
+        synchronized (_lock)
+        {
+            return _state == OPEN;
+        }
+    }
+
+
 }

Modified: 
qpid/java/trunk/bdbstore/src/main/java/org/apache/qpid/server/virtualhost/berkeleydb/BDBHAReplicaVirtualHostImpl.java
URL: 
http://svn.apache.org/viewvc/qpid/java/trunk/bdbstore/src/main/java/org/apache/qpid/server/virtualhost/berkeleydb/BDBHAReplicaVirtualHostImpl.java?rev=1753882&r1=1753881&r2=1753882&view=diff
==============================================================================
--- 
qpid/java/trunk/bdbstore/src/main/java/org/apache/qpid/server/virtualhost/berkeleydb/BDBHAReplicaVirtualHostImpl.java
 (original)
+++ 
qpid/java/trunk/bdbstore/src/main/java/org/apache/qpid/server/virtualhost/berkeleydb/BDBHAReplicaVirtualHostImpl.java
 Sat Jul 23 19:30:45 2016
@@ -502,4 +502,9 @@ public class BDBHAReplicaVirtualHostImpl
                                         + " does not permit this operation.");
     }
 
+    @Override
+    public void setFirstOpening(final boolean firstOpening)
+    {
+
+    }
 }

Modified: 
qpid/java/trunk/bdbstore/src/main/java/org/apache/qpid/server/virtualhostnode/berkeleydb/BDBHAVirtualHostNodeImpl.java
URL: 
http://svn.apache.org/viewvc/qpid/java/trunk/bdbstore/src/main/java/org/apache/qpid/server/virtualhostnode/berkeleydb/BDBHAVirtualHostNodeImpl.java?rev=1753882&r1=1753881&r2=1753882&view=diff
==============================================================================
--- 
qpid/java/trunk/bdbstore/src/main/java/org/apache/qpid/server/virtualhostnode/berkeleydb/BDBHAVirtualHostNodeImpl.java
 (original)
+++ 
qpid/java/trunk/bdbstore/src/main/java/org/apache/qpid/server/virtualhostnode/berkeleydb/BDBHAVirtualHostNodeImpl.java
 Sat Jul 23 19:30:45 2016
@@ -67,6 +67,7 @@ import org.apache.qpid.server.logging.me
 import org.apache.qpid.server.logging.messages.HighAvailabilityMessages;
 import org.apache.qpid.server.logging.subjects.BDBHAVirtualHostNodeLogSubject;
 import org.apache.qpid.server.logging.subjects.GroupLogSubject;
+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;
@@ -78,7 +79,6 @@ import org.apache.qpid.server.model.Stat
 import org.apache.qpid.server.model.StateTransition;
 import org.apache.qpid.server.model.SystemConfig;
 import org.apache.qpid.server.model.VirtualHost;
-import org.apache.qpid.server.security.access.Operation;
 import org.apache.qpid.server.store.ConfiguredObjectRecord;
 import org.apache.qpid.server.store.ConfiguredObjectRecordImpl;
 import org.apache.qpid.server.store.DurableConfigurationStore;
@@ -347,7 +347,7 @@ public class BDBHAVirtualHostNodeImpl ex
         _lastRole.set(NodeRole.WAITING);
         attributeSet(ROLE, _role, NodeRole.WAITING);
 
-        getConfigurationStore().openConfigurationStore(this, false);
+        getConfigurationStore().init(this);
 
         getEventLogger().message(getConfigurationStoreLogSubject(), 
ConfigStoreMessages.CREATED());
         getEventLogger().message(getConfigurationStoreLogSubject(), 
ConfigStoreMessages.STORE_LOCATION(getStorePath()));
@@ -624,56 +624,42 @@ public class BDBHAVirtualHostNodeImpl ex
     {
         try
         {
+            boolean createDefaultExchanges = false;
             closeVirtualHostIfExist().get();
-
-            getConfigurationStore().upgradeStoreStructure();
-
             getEventLogger().message(getConfigurationStoreLogSubject(), 
ConfigStoreMessages.RECOVERY_START());
             VirtualHostStoreUpgraderAndRecoverer upgraderAndRecoverer = new 
VirtualHostStoreUpgraderAndRecoverer(this);
-            upgraderAndRecoverer.perform(getConfigurationStore());
+            if(getConfigurationStore().isOpen())
+            {
+                upgraderAndRecoverer.reloadAndRecover(getConfigurationStore());
+            }
+            else
+            {
+                ConfiguredObjectRecord[] initialRecords = getInitialRecords();
+                
if(upgraderAndRecoverer.upgradeAndRecover(getConfigurationStore(), 
initialRecords))
+                {
+                    setAttributes(Collections.<String, 
Object>singletonMap(VIRTUALHOST_INITIAL_CONFIGURATION, "{}"));
+                    createDefaultExchanges = initialRecords == null || 
initialRecords.length == 0;
+                }
+
+            }
+
             getEventLogger().message(getConfigurationStoreLogSubject(), 
ConfigStoreMessages.RECOVERY_COMPLETE());
 
             VirtualHost<?>  host = getVirtualHost();
 
+
             if (host == null)
             {
                 if (LOGGER.isDebugEnabled())
                 {
                     LOGGER.debug("Creating new virtualhost with name : " + 
getGroupName());
                 }
-                ConfiguredObjectRecord[] initialRecords = getInitialRecords();
-                if(initialRecords != null && initialRecords.length > 0)
-                {
-                    getConfigurationStore().update(true, initialRecords);
-                    
getEventLogger().message(getConfigurationStoreLogSubject(), 
ConfigStoreMessages.RECOVERY_START());
-                    upgraderAndRecoverer = new 
VirtualHostStoreUpgraderAndRecoverer(this);
-                    upgraderAndRecoverer.perform(getConfigurationStore());
-                    
getEventLogger().message(getConfigurationStoreLogSubject(), 
ConfigStoreMessages.RECOVERY_COMPLETE());
-                    setAttributes(Collections.<String, 
Object>singletonMap(VIRTUALHOST_INITIAL_CONFIGURATION, "{}"));
-                    host = getVirtualHost();
-                    if(host != null)
-                    {
-                        final VirtualHost<?> recoveredHost = host;
-                        Subject.doAs(getSubjectWithAddedSystemRights(), new 
PrivilegedAction<Object>()
-                        {
-                            @Override
-                            public Object run()
-                            {
-                                recoveredHost.open();
-                                return null;
-                            }
-                        });
-                    }
-                }
-                else
-                {
-                    Map<String, Object> hostAttributes = new HashMap<>();
+                Map<String, Object> hostAttributes = new HashMap<>();
 
-                    hostAttributes.put(VirtualHost.MODEL_VERSION, 
BrokerModel.MODEL_VERSION);
-                    hostAttributes.put(VirtualHost.NAME, getGroupName());
-                    hostAttributes.put(VirtualHost.TYPE, 
BDBHAVirtualHostImpl.VIRTUAL_HOST_TYPE);
-                    host = createChild(VirtualHost.class, hostAttributes);
-                }
+                hostAttributes.put(VirtualHost.MODEL_VERSION, 
BrokerModel.MODEL_VERSION);
+                hostAttributes.put(VirtualHost.NAME, getGroupName());
+                hostAttributes.put(VirtualHost.TYPE, 
BDBHAVirtualHostImpl.VIRTUAL_HOST_TYPE);
+                host = createChild(VirtualHost.class, hostAttributes);
 
             }
             else
@@ -684,6 +670,7 @@ public class BDBHAVirtualHostNodeImpl ex
                 }
 
                 final VirtualHost<?> recoveredHost = host;
+                recoveredHost.setFirstOpening(createDefaultExchanges);
                 Subject.doAs(getSubjectWithAddedSystemRights(), new 
PrivilegedAction<Object>()
                 {
                     @Override

Modified: 
qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/configuration/store/ManagementModeStoreHandler.java
URL: 
http://svn.apache.org/viewvc/qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/configuration/store/ManagementModeStoreHandler.java?rev=1753882&r1=1753881&r2=1753882&view=diff
==============================================================================
--- 
qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/configuration/store/ManagementModeStoreHandler.java
 (original)
+++ 
qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/configuration/store/ManagementModeStoreHandler.java
 Sat Jul 23 19:30:45 2016
@@ -24,6 +24,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.Set;
 import java.util.UUID;
@@ -60,6 +61,10 @@ public class ManagementModeStoreHandler
     private static final String ATTRIBUTE_STATE = VirtualHost.STATE;
     private static final Object MANAGEMENT_MODE_AUTH_PROVIDER = "mm-auth";
 
+    private enum StoreState { CLOSED, CONFIGURED, OPEN };
+    private StoreState _state = StoreState.CLOSED;
+    private final Object _lock = new Object();
+
 
     private final DurableConfigurationStore _store;
     private Map<UUID, ConfiguredObjectRecord> _cliEntries;
@@ -76,94 +81,38 @@ public class ManagementModeStoreHandler
     }
 
     @Override
-    public void openConfigurationStore(final ConfiguredObject<?> parent,
-                                       final boolean overwrite,
-                                       final ConfiguredObjectRecord... 
initialRecords)
+    public void init(final ConfiguredObject<?> parent)
             throws StoreException
     {
+        changeState(StoreState.CLOSED, StoreState.CONFIGURED);
         _parent = parent;
-        _store.openConfigurationStore(parent, overwrite, initialRecords);
-
-        _quiescedEntriesOriginalState = quiesceEntries(_systemConfig);
-
-
-        _records = new HashMap<UUID, ConfiguredObjectRecord>();
-        final ConfiguredObjectRecordHandler localRecoveryHandler = new 
ConfiguredObjectRecordHandler()
-        {
-            private int _version;
-            private boolean _quiesceHttpPort = 
_systemConfig.getManagementModeHttpPortOverride() > 0;
+        _store.init(parent);
 
-            @Override
-            public void begin()
-            {
-            }
 
-            @Override
-            public boolean handle(final ConfiguredObjectRecord object)
-            {
-                String entryType = object.getType();
-                Map<String, Object> attributes = object.getAttributes();
-                boolean quiesce = false;
-                if (VIRTUAL_HOST_TYPE.equals(entryType) && 
_systemConfig.isManagementModeQuiesceVirtualHosts())
-                {
-                    quiesce = true;
-                }
-                else if (PORT_TYPE.equals(entryType))
-                {
-                    if (attributes == null)
-                    {
-                        throw new IllegalConfigurationException("Port 
attributes are not set in " + object);
-                    }
-                    Set<Protocol> protocols = 
getPortProtocolsAttribute(attributes);
-                    if (protocols == null)
-                    {
-                        quiesce = true;
-                    }
-                    else
-                    {
-                        for (Protocol protocol : protocols)
-                        {
-                            switch (protocol)
-                            {
-                                case HTTP:
-                                    quiesce = _quiesceHttpPort;
-                                    break;
-                                default:
-                                    quiesce = true;
-                            }
-                        }
-                    }
-                }
-                if (quiesce)
-                {
-                    LOGGER.debug("Management mode quiescing entry {}", object);
 
-                    // save original state
-                    _quiescedEntriesOriginalState.put(object.getId(), 
attributes.get(ATTRIBUTE_STATE));
-                    Map<String,Object> modifiedAttributes = new 
HashMap<String, Object>(attributes);
-                    modifiedAttributes.put(ATTRIBUTE_STATE, State.QUIESCED);
-                    ConfiguredObjectRecord record = new 
ConfiguredObjectRecordImpl(object.getId(), object.getType(), 
modifiedAttributes, object.getParents());
-                    _records.put(record.getId(), record);
 
-                }
-                else
-                {
-                    _records.put(object.getId(), object);
-                }
-                return true;
-            }
+    }
 
+    @Override
+    public void upgradeStoreStructure() throws StoreException
+    {
+        _store.upgradeStoreStructure();
+    }
 
-            @Override
-            public void end()
-            {
-            }
-        };
+    @Override
+    public boolean openConfigurationStore(final ConfiguredObjectRecordHandler 
recoveryHandler,
+                                          final ConfiguredObjectRecord... 
initialRecords) throws StoreException
+    {
 
+        changeState(StoreState.CONFIGURED, StoreState.OPEN);
+        _records = new HashMap<UUID, ConfiguredObjectRecord>();
+        UnderlyingStoreRecoveringObjectRecordHandler underlyingHandler = new 
UnderlyingStoreRecoveringObjectRecordHandler();
+        boolean isNew = _store.openConfigurationStore(underlyingHandler, 
initialRecords);
 
 
+        _quiescedEntriesOriginalState = quiesceEntries(_systemConfig, 
underlyingHandler.getRecoveredRecords());
+        recoverRecords(underlyingHandler.getRecoveredRecords());
 
-        _store.visitConfiguredObjectRecords(localRecoveryHandler);
 
         _cliEntries = createPortsFromCommandLineOptions(_systemConfig);
 
@@ -172,36 +121,23 @@ public class ManagementModeStoreHandler
             _records.put(entry.getId(),entry);
         }
 
-
-    }
-
-    @Override
-    public void upgradeStoreStructure() throws StoreException
-    {
-        _store.upgradeStoreStructure();
-    }
-
-    @Override
-    public void visitConfiguredObjectRecords(final 
ConfiguredObjectRecordHandler recoveryHandler) throws StoreException
-    {
-
-
-        recoveryHandler.begin();
-
         for(ConfiguredObjectRecord record : _records.values())
         {
-            if(!recoveryHandler.handle(record))
-            {
-                break;
-            }
+            recoveryHandler.handle(record);
         }
-        recoveryHandler.end();
+        return isNew;
     }
 
+    @Override
+    public void reload(final ConfiguredObjectRecordHandler handle) throws 
StoreException
+    {
+        throw new UnsupportedOperationException();
+    }
 
     @Override
     public void create(final ConfiguredObjectRecord object)
     {
+        assertState(StoreState.OPEN);
         synchronized (_store)
         {
             _store.create(object);
@@ -212,6 +148,7 @@ public class ManagementModeStoreHandler
     @Override
     public void update(final boolean createIfNecessary, final 
ConfiguredObjectRecord... records) throws StoreException
     {
+        assertState(StoreState.OPEN);
         synchronized (_store)
         {
 
@@ -242,6 +179,8 @@ public class ManagementModeStoreHandler
     @Override
     public void closeConfigurationStore() throws StoreException
     {
+        changeState(StoreState.OPEN, StoreState.CLOSED);
+        _store.closeConfigurationStore();
     }
 
     @Override
@@ -252,6 +191,7 @@ public class ManagementModeStoreHandler
     @Override
     public synchronized UUID[] remove(final ConfiguredObjectRecord... records)
     {
+        assertState(StoreState.OPEN);
         synchronized (_store)
         {
             UUID[] idsToRemove = new UUID[records.length];
@@ -332,71 +272,54 @@ public class ManagementModeStoreHandler
     }
 
 
-    private Map<UUID, Object> quiesceEntries(final SystemConfig<?> options)
+    private Map<UUID, Object> quiesceEntries(final SystemConfig<?> options, 
List<ConfiguredObjectRecord> records)
     {
         final Map<UUID, Object> quiescedEntries = new HashMap<UUID, Object>();
         final int managementModeHttpPortOverride = 
options.getManagementModeHttpPortOverride();
 
-        _store.visitConfiguredObjectRecords(new ConfiguredObjectRecordHandler()
+        for(ConfiguredObjectRecord entry : records)
         {
-            @Override
-            public void begin()
+            String entryType = entry.getType();
+            Map<String, Object> attributes = entry.getAttributes();
+            boolean quiesce = false;
+            if (VIRTUAL_HOST_TYPE.equals(entryType) && 
options.isManagementModeQuiesceVirtualHosts())
             {
-
+                quiesce = true;
             }
-
-            @Override
-            public boolean handle(final ConfiguredObjectRecord entry)
+            else if (PORT_TYPE.equals(entryType))
             {
-                String entryType = entry.getType();
-                Map<String, Object> attributes = entry.getAttributes();
-                boolean quiesce = false;
-                if (VIRTUAL_HOST_TYPE.equals(entryType) && 
options.isManagementModeQuiesceVirtualHosts())
+                if (attributes == null)
+                {
+                    throw new IllegalConfigurationException("Port attributes 
are not set in " + entry);
+                }
+                Set<Protocol> protocols = 
getPortProtocolsAttribute(attributes);
+                if (protocols == null)
                 {
                     quiesce = true;
                 }
-                else if (PORT_TYPE.equals(entryType))
+                else
                 {
-                    if (attributes == null)
+                    for (Protocol protocol : protocols)
                     {
-                        throw new IllegalConfigurationException("Port 
attributes are not set in " + entry);
-                    }
-                    Set<Protocol> protocols = 
getPortProtocolsAttribute(attributes);
-                    if (protocols == null)
-                    {
-                        quiesce = true;
-                    }
-                    else
-                    {
-                        for (Protocol protocol : protocols)
+                        switch (protocol)
                         {
-                            switch (protocol)
-                            {
-                                case HTTP:
-                                    quiesce = managementModeHttpPortOverride > 
0;
-                                    break;
-                                default:
-                                    quiesce = true;
-                            }
+                            case HTTP:
+                                quiesce = managementModeHttpPortOverride > 0;
+                                break;
+                            default:
+                                quiesce = true;
                         }
                     }
                 }
-                if (quiesce)
-                {
-                    LOGGER.debug("Management mode quiescing entry {}", entry);
-
-                    // save original state
-                    quiescedEntries.put(entry.getId(), 
attributes.get(ATTRIBUTE_STATE));
-                }
-                return true;
             }
-
-
-            @Override
-            public void end()
+            if (quiesce)
             {
+                LOGGER.debug("Management mode quiescing entry {}", entry);
+
+                // save original state
+                quiescedEntries.put(entry.getId(), 
attributes.get(ATTRIBUTE_STATE));
             }
-        });
+        }
 
 
         return quiescedEntries;
@@ -433,4 +356,104 @@ public class ManagementModeStoreHandler
         return new ConfiguredObjectRecordImpl(entry.getId(), entry.getType(), 
attributes, entry.getParents());
     }
 
+    private static class UnderlyingStoreRecoveringObjectRecordHandler 
implements ConfiguredObjectRecordHandler
+    {
+        private List<ConfiguredObjectRecord> _recoveredRecords = new 
ArrayList<>();
+
+        @Override
+        public void handle(final ConfiguredObjectRecord record)
+        {
+            _recoveredRecords.add(record);
+        }
+
+        public List<ConfiguredObjectRecord> getRecoveredRecords()
+        {
+            return _recoveredRecords;
+        }
+
+    }
+
+
+    public void recoverRecords(final List<ConfiguredObjectRecord> records)
+    {
+        boolean b = _systemConfig.getManagementModeHttpPortOverride() > 0;
+        for (ConfiguredObjectRecord object : records)
+        {
+            String entryType = object.getType();
+            Map<String, Object> attributes = object.getAttributes();
+            boolean quiesce = false;
+            if (VIRTUAL_HOST_TYPE.equals(entryType) && 
_systemConfig.isManagementModeQuiesceVirtualHosts())
+            {
+                quiesce = true;
+            }
+            else if (PORT_TYPE.equals(entryType))
+            {
+                if (attributes == null)
+                {
+                    throw new IllegalConfigurationException("Port attributes 
are not set in " + object);
+                }
+                Set<Protocol> protocols = 
getPortProtocolsAttribute(attributes);
+                if (protocols == null)
+                {
+                    quiesce = true;
+                }
+                else
+                {
+                    for (Protocol protocol : protocols)
+                    {
+                        switch (protocol)
+                        {
+                            case HTTP:
+                                quiesce = b;
+                                break;
+                            default:
+                                quiesce = true;
+                        }
+                    }
+                }
+            }
+            if (quiesce)
+            {
+                LOGGER.debug("Management mode quiescing entry {}", object);
+
+                // save original state
+                _quiescedEntriesOriginalState.put(object.getId(), 
attributes.get(ATTRIBUTE_STATE));
+                Map<String, Object> modifiedAttributes = new HashMap<String, 
Object>(attributes);
+                modifiedAttributes.put(ATTRIBUTE_STATE, State.QUIESCED);
+                ConfiguredObjectRecord record = new 
ConfiguredObjectRecordImpl(object.getId(),
+                                                                               
object.getType(),
+                                                                               
modifiedAttributes,
+                                                                               
object.getParents());
+                _records.put(record.getId(), record);
+
+            }
+            else
+            {
+                _records.put(object.getId(), object);
+            }
+        }
+    }
+
+
+    private void assertState(StoreState state)
+    {
+        synchronized (_lock)
+        {
+            if(_state != state)
+            {
+                throw new IllegalStateException("The store must be in state " 
+ state + " to perform this operation, but it is in state " + _state + " 
instead");
+            }
+        }
+    }
+
+    private void changeState(StoreState oldState, StoreState newState)
+    {
+        synchronized (_lock)
+        {
+            assertState(oldState);
+            _state = newState;
+        }
+    }
+
+
 }

Modified: 
qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/model/AbstractConfiguredObject.java
URL: 
http://svn.apache.org/viewvc/qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/model/AbstractConfiguredObject.java?rev=1753882&r1=1753881&r2=1753882&view=diff
==============================================================================
--- 
qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/model/AbstractConfiguredObject.java
 (original)
+++ 
qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/model/AbstractConfiguredObject.java
 Sat Jul 23 19:30:45 2016
@@ -2603,7 +2603,7 @@ public abstract class AbstractConfigured
         }
     }
 
-    protected void forceUpdateAllSecureAttributes()
+    public void forceUpdateAllSecureAttributes()
     {
         applyToChildren(new Action<ConfiguredObject<?>>()
         {
@@ -3103,6 +3103,12 @@ public abstract class AbstractConfigured
     }
 
     @Override
+    public boolean hasEncrypter()
+    {
+        return _encrypter != null;
+    }
+
+    @Override
     public void decryptSecrets()
     {
         if(_encrypter != null)

Modified: 
qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/model/AbstractSystemConfig.java
URL: 
http://svn.apache.org/viewvc/qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/model/AbstractSystemConfig.java?rev=1753882&r1=1753881&r2=1753882&view=diff
==============================================================================
--- 
qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/model/AbstractSystemConfig.java
 (original)
+++ 
qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/model/AbstractSystemConfig.java
 Sat Jul 23 19:30:45 2016
@@ -209,18 +209,8 @@ public abstract class AbstractSystemConf
             _configurationStore = new 
ManagementModeStoreHandler(_configurationStore, this);
         }
 
-        try
-        {
-            _configurationStore.openConfigurationStore(this,
-                                                       false,
-                                                       
convertToConfigurationRecords(getInitialConfigurationLocation(),
-                                                                               
      this));
-            _configurationStore.upgradeStoreStructure();
-        }
-        catch (IOException e)
-        {
-            throw new IllegalArgumentException(e);
-        }
+        _configurationStore.init(this);
+        _configurationStore.upgradeStoreStructure();
     }
 
     @StateTransition(currentState = State.UNINITIALIZED, desiredState = 
State.ACTIVE)
@@ -244,7 +234,15 @@ public abstract class AbstractSystemConf
 
 
         BrokerStoreUpgraderAndRecoverer upgrader = new 
BrokerStoreUpgraderAndRecoverer(this);
-        upgrader.perform();
+        try
+        {
+            
upgrader.perform(convertToConfigurationRecords(getInitialConfigurationLocation(),
+                                                           this));
+        }
+        catch (IOException e)
+        {
+            throw new IllegalArgumentException(e);
+        }
 
         final Broker broker = getBroker();
 

Modified: 
qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/model/ConfiguredObject.java
URL: 
http://svn.apache.org/viewvc/qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/model/ConfiguredObject.java?rev=1753882&r1=1753881&r2=1753882&view=diff
==============================================================================
--- 
qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/model/ConfiguredObject.java
 (original)
+++ 
qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/model/ConfiguredObject.java
 Sat Jul 23 19:30:45 2016
@@ -268,6 +268,7 @@ public interface ConfiguredObject<X exte
 
     void delete();
 
+    boolean hasEncrypter();
     void decryptSecrets();
 
     UserPreferences getUserPreferences();

Modified: 
qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/model/VirtualHost.java
URL: 
http://svn.apache.org/viewvc/qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/model/VirtualHost.java?rev=1753882&r1=1753881&r2=1753882&view=diff
==============================================================================
--- 
qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/model/VirtualHost.java
 (original)
+++ 
qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/model/VirtualHost.java
 Sat Jul 23 19:30:45 2016
@@ -218,6 +218,8 @@ public interface VirtualHost<X extends V
 
     String getLocalAddress(String routingAddress);
 
+    void setFirstOpening(boolean firstOpening);
+
     interface Transaction
     {
         void dequeue(QueueEntry entry);

Modified: 
qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/store/AbstractJDBCConfigurationStore.java
URL: 
http://svn.apache.org/viewvc/qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/store/AbstractJDBCConfigurationStore.java?rev=1753882&r1=1753881&r2=1753882&view=diff
==============================================================================
--- 
qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/store/AbstractJDBCConfigurationStore.java
 (original)
+++ 
qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/store/AbstractJDBCConfigurationStore.java
 Sat Jul 23 19:30:45 2016
@@ -20,6 +20,9 @@
 */
 package org.apache.qpid.server.store;
 
+import static 
org.apache.qpid.server.store.AbstractJDBCConfigurationStore.State.CONFIGURED;
+import static 
org.apache.qpid.server.store.AbstractJDBCConfigurationStore.State.OPEN;
+
 import java.io.ByteArrayInputStream;
 import java.io.IOException;
 import java.sql.Connection;
@@ -39,9 +42,6 @@ import java.util.Map;
 import java.util.Set;
 import java.util.UUID;
 
-import com.fasterxml.jackson.core.JsonGenerationException;
-import com.fasterxml.jackson.core.JsonParseException;
-import com.fasterxml.jackson.databind.JsonMappingException;
 import com.fasterxml.jackson.databind.ObjectMapper;
 import org.slf4j.Logger;
 
@@ -82,16 +82,66 @@ public abstract class AbstractJDBCConfig
                                                                           + " 
where child_id = ?";
     private static final String SELECT_FROM_CONFIGURED_OBJECT_HIERARCHY = 
"SELECT child_id, parent_type, parent_id FROM " + 
CONFIGURED_OBJECT_HIERARCHY_TABLE_NAME;
 
+    public enum State { CLOSED, CONFIGURED, OPEN };
+    private State _state = State.CLOSED;
+    private final Object _lock = new Object();
+
+
+
     @Override
-    public void visitConfiguredObjectRecords(ConfiguredObjectRecordHandler 
handler)
+    public boolean openConfigurationStore(ConfiguredObjectRecordHandler 
handler,
+                                          final ConfiguredObjectRecord... 
initialRecords)
     {
-        checkConfigurationStoreOpen();
+        changeState(CONFIGURED, OPEN);
+        try
+        {
+            Collection<? extends ConfiguredObjectRecord> records = 
doVisitAllConfiguredObjectRecords(handler);
+            boolean isNew = records.isEmpty();
+
+            if(isNew)
+            {
+                records = Arrays.asList(initialRecords);
+                try
+                {
+                    try (Connection conn = newConnection())
+                    {
+                        for (ConfiguredObjectRecord record : records)
+                        {
+                            updateConfiguredObject(record, true, conn);
+                        }
+                        conn.commit();
+                    }
+                }
+                catch (SQLException e)
+                {
+                    throw new StoreException("Error updating configured 
objects in database: " + e.getMessage(), e);
+                }
+            }
+
+            for(ConfiguredObjectRecord record : records)
+            {
+                handler.handle(record);
+            }
+            return isNew;
+        }
+        catch (SQLException e)
+        {
+            throw new StoreException("Cannot visit configured object records", 
e);
+        }
+    }
 
+    @Override
+    public void reload(final ConfiguredObjectRecordHandler handler) throws 
StoreException
+    {
+        assertState(State.OPEN);
         try
         {
-            handler.begin();
-            doVisitAllConfiguredObjectRecords(handler);
-            handler.end();
+            Collection<? extends ConfiguredObjectRecord> records = 
doVisitAllConfiguredObjectRecords(handler);
+
+            for(ConfiguredObjectRecord record : records)
+            {
+                handler.handle(record);
+            }
         }
         catch (SQLException e)
         {
@@ -99,12 +149,11 @@ public abstract class AbstractJDBCConfig
         }
     }
 
-    private void 
doVisitAllConfiguredObjectRecords(ConfiguredObjectRecordHandler handler) throws 
SQLException
+    private Collection<ConfiguredObjectRecordImpl> 
doVisitAllConfiguredObjectRecords(ConfiguredObjectRecordHandler handler) throws 
SQLException
     {
-        Connection conn = newAutoCommitConnection();
         Map<UUID, ConfiguredObjectRecordImpl> configuredObjects = new 
HashMap<UUID, ConfiguredObjectRecordImpl>();
         final ObjectMapper objectMapper = new ObjectMapper();
-        try
+        try (Connection conn = newAutoCommitConnection())
         {
             PreparedStatement stmt = 
conn.prepareStatement(SELECT_FROM_CONFIGURED_OBJECTS);
             try
@@ -120,18 +169,10 @@ public abstract class AbstractJDBCConfig
                         final ConfiguredObjectRecordImpl 
configuredObjectRecord =
                                 new 
ConfiguredObjectRecordImpl(UUID.fromString(id), objectType,
                                                                
objectMapper.readValue(attributes, Map.class));
-                        
configuredObjects.put(configuredObjectRecord.getId(),configuredObjectRecord);
+                        configuredObjects.put(configuredObjectRecord.getId(), 
configuredObjectRecord);
 
                     }
                 }
-                catch (JsonMappingException e)
-                {
-                    throw new StoreException("Error recovering persistent 
state: " + e.getMessage(), e);
-                }
-                catch (JsonParseException e)
-                {
-                    throw new StoreException("Error recovering persistent 
state: " + e.getMessage(), e);
-                }
                 catch (IOException e)
                 {
                     throw new StoreException("Error recovering persistent 
state: " + e.getMessage(), e);
@@ -148,8 +189,7 @@ public abstract class AbstractJDBCConfig
             stmt = 
conn.prepareStatement(SELECT_FROM_CONFIGURED_OBJECT_HIERARCHY);
             try
             {
-                ResultSet rs = stmt.executeQuery();
-                try
+                try (ResultSet rs = stmt.executeQuery())
                 {
                     while (rs.next())
                     {
@@ -160,16 +200,12 @@ public abstract class AbstractJDBCConfig
                         ConfiguredObjectRecordImpl child = 
configuredObjects.get(childId);
                         ConfiguredObjectRecordImpl parent = 
configuredObjects.get(parentId);
 
-                        if(child != null && parent != null)
+                        if (child != null && parent != null)
                         {
                             child.addParent(parentType, parent);
                         }
                     }
                 }
-                finally
-                {
-                    rs.close();
-                }
             }
             finally
             {
@@ -177,23 +213,10 @@ public abstract class AbstractJDBCConfig
             }
 
         }
-        finally
-        {
-            conn.close();
-        }
+        return configuredObjects.values();
 
-        for(ConfiguredObjectRecord record : configuredObjects.values())
-        {
-            boolean shouldContinue = handler.handle(record);
-            if (!shouldContinue)
-            {
-                break;
-            }
-        }
     }
 
-    protected abstract void checkConfigurationStoreOpen();
-
     protected void upgradeIfNecessary(ConfiguredObject<?> parent) throws 
StoreException
     {
         Connection connection = null;
@@ -408,15 +431,15 @@ public abstract class AbstractJDBCConfig
     protected abstract String getSqlBigIntType();
 
 
-    protected void createOrOpenConfigurationStoreDatabase(final boolean clear) 
throws StoreException
+    protected void createOrOpenConfigurationStoreDatabase() throws 
StoreException
     {
         Connection conn = null;
         try
         {
             conn = newAutoCommitConnection();
 
-            createConfiguredObjectsTable(conn, clear);
-            createConfiguredObjectHierarchyTable(conn, clear);
+            createConfiguredObjectsTable(conn);
+            createConfiguredObjectHierarchyTable(conn);
         }
         catch (SQLException e)
         {
@@ -444,7 +467,7 @@ public abstract class AbstractJDBCConfig
         }
     }
 
-    private void createConfiguredObjectsTable(final Connection conn, final 
boolean clear) throws SQLException
+    private void createConfiguredObjectsTable(final Connection conn) throws 
SQLException
     {
         if(!tableExists(CONFIGURED_OBJECTS_TABLE_NAME, conn))
         {
@@ -457,16 +480,9 @@ public abstract class AbstractJDBCConfig
                              + ",  PRIMARY KEY (id))");
             }
         }
-        else if(clear)
-        {
-            try (Statement stmt = conn.createStatement())
-            {
-                stmt.execute("DELETE FROM " + CONFIGURED_OBJECTS_TABLE_NAME);
-            }
-        }
     }
 
-    private void createConfiguredObjectHierarchyTable(final Connection conn, 
final boolean clear) throws SQLException
+    private void createConfiguredObjectHierarchyTable(final Connection conn) 
throws SQLException
     {
         if(!tableExists(CONFIGURED_OBJECT_HIERARCHY_TABLE_NAME, conn))
         {
@@ -476,13 +492,6 @@ public abstract class AbstractJDBCConfig
                              + " ( child_id VARCHAR(36) not null, parent_type 
varchar(255), parent_id VARCHAR(36),  PRIMARY KEY (child_id, parent_type))");
             }
         }
-        else if(clear)
-        {
-            try (Statement stmt = conn.createStatement())
-            {
-                stmt.execute("DELETE FROM " + 
CONFIGURED_OBJECT_HIERARCHY_TABLE_NAME);
-            }
-        }
     }
 
     protected boolean tableExists(final String tableName, final Connection 
conn) throws SQLException
@@ -521,7 +530,7 @@ public abstract class AbstractJDBCConfig
     @Override
     public void create(ConfiguredObjectRecord object) throws StoreException
     {
-        checkConfigurationStoreOpen();
+        assertState(OPEN);
         try
         {
             Connection conn = newConnection();
@@ -594,44 +603,29 @@ public abstract class AbstractJDBCConfig
         return connection;
     }
 
-    protected boolean hasNoConfigurationEntries()
-    {
-        ConfiguredObjectRecordPresenceDetector recordPresenceDetector = new 
ConfiguredObjectRecordPresenceDetector();
-        visitConfiguredObjectRecords(recordPresenceDetector);
-
-        return !recordPresenceDetector.isRecordsPresent();
-    }
-
     protected abstract Connection getConnection() throws SQLException;
 
     private void insertConfiguredObject(ConfiguredObjectRecord 
configuredObject, final Connection conn) throws StoreException
     {
         try
         {
-            PreparedStatement stmt = 
conn.prepareStatement(FIND_CONFIGURED_OBJECT);
-            try
+            try (PreparedStatement stmt = 
conn.prepareStatement(FIND_CONFIGURED_OBJECT))
             {
                 stmt.setString(1, configuredObject.getId().toString());
-                ResultSet rs = stmt.executeQuery();
                 boolean exists;
-                try
+                try (ResultSet rs = stmt.executeQuery())
                 {
                     exists = rs.next();
 
                 }
-                finally
-                {
-                    rs.close();
-                }
                 // If we don't have any data in the result set then we can add 
this configured object
                 if (!exists)
                 {
-                    PreparedStatement insertStmt = 
conn.prepareStatement(INSERT_INTO_CONFIGURED_OBJECTS);
-                    try
+                    try (PreparedStatement insertStmt = 
conn.prepareStatement(INSERT_INTO_CONFIGURED_OBJECTS))
                     {
                         insertStmt.setString(1, 
configuredObject.getId().toString());
                         insertStmt.setString(2, configuredObject.getType());
-                        if(configuredObject.getAttributes() == null)
+                        if (configuredObject.getAttributes() == null)
                         {
                             insertStmt.setNull(3, Types.BLOB);
                         }
@@ -646,34 +640,14 @@ public abstract class AbstractJDBCConfig
                         }
                         insertStmt.execute();
                     }
-                    finally
-                    {
-                        insertStmt.close();
-                    }
 
                     writeHierarchy(configuredObject, conn);
                 }
 
             }
-            finally
-            {
-                stmt.close();
-            }
 
         }
-        catch (JsonMappingException e)
-        {
-            throw new StoreException("Error inserting of configured object " + 
configuredObject + " into database: " + e.getMessage(), e);
-        }
-        catch (JsonGenerationException e)
-        {
-            throw new StoreException("Error inserting of configured object " + 
configuredObject + " into database: " + e.getMessage(), e);
-        }
-        catch (IOException e)
-        {
-            throw new StoreException("Error inserting of configured object " + 
configuredObject + " into database: " + e.getMessage(), e);
-        }
-        catch (SQLException e)
+        catch (IOException | SQLException e)
         {
             throw new StoreException("Error inserting of configured object " + 
configuredObject + " into database: " + e.getMessage(), e);
         }
@@ -682,27 +656,22 @@ public abstract class AbstractJDBCConfig
     @Override
     public UUID[] remove(ConfiguredObjectRecord... objects) throws 
StoreException
     {
-        checkConfigurationStoreOpen();
+        assertState(OPEN);
 
         Collection<UUID> removed = new ArrayList<UUID>(objects.length);
         try
         {
 
-            Connection conn = newAutoCommitConnection();
-            try
+            try (Connection conn = newAutoCommitConnection())
             {
-                for(ConfiguredObjectRecord record : objects)
+                for (ConfiguredObjectRecord record : objects)
                 {
-                    if(removeConfiguredObject(record.getId(), conn) != 0)
+                    if (removeConfiguredObject(record.getId(), conn) != 0)
                     {
                         removed.add(record.getId());
                     }
                 }
             }
-            finally
-            {
-                conn.close();
-            }
         }
         catch (SQLException e)
         {
@@ -741,22 +710,17 @@ public abstract class AbstractJDBCConfig
     @Override
     public void update(boolean createIfNecessary, ConfiguredObjectRecord... 
records) throws StoreException
     {
-        checkConfigurationStoreOpen();
+        assertState(OPEN);
         try
         {
-            Connection conn = newConnection();
-            try
+            try (Connection conn = newConnection())
             {
-                for(ConfiguredObjectRecord record : records)
+                for (ConfiguredObjectRecord record : records)
                 {
                     updateConfiguredObject(record, createIfNecessary, conn);
                 }
                 conn.commit();
             }
-            finally
-            {
-                conn.close();
-            }
         }
         catch (SQLException e)
         {
@@ -769,19 +733,16 @@ public abstract class AbstractJDBCConfig
                                         Connection conn)
             throws SQLException, StoreException
     {
-        PreparedStatement stmt = conn.prepareStatement(FIND_CONFIGURED_OBJECT);
-        try
+        try (PreparedStatement stmt = 
conn.prepareStatement(FIND_CONFIGURED_OBJECT))
         {
             stmt.setString(1, configuredObject.getId().toString());
-            ResultSet rs = stmt.executeQuery();
-            try
+            try (ResultSet rs = stmt.executeQuery())
             {
 
                 final ObjectMapper objectMapper = 
ConfiguredObjectJacksonModule.newObjectMapper();
                 if (rs.next())
                 {
-                    PreparedStatement stmt2 = 
conn.prepareStatement(UPDATE_CONFIGURED_OBJECTS);
-                    try
+                    try (PreparedStatement stmt2 = 
conn.prepareStatement(UPDATE_CONFIGURED_OBJECTS))
                     {
                         stmt2.setString(1, configuredObject.getType());
                         if (configuredObject.getAttributes() != null)
@@ -798,19 +759,14 @@ public abstract class AbstractJDBCConfig
                         stmt2.setString(3, 
configuredObject.getId().toString());
                         stmt2.execute();
                     }
-                    finally
-                    {
-                        stmt2.close();
-                    }
                 }
-                else if(createIfNecessary)
+                else if (createIfNecessary)
                 {
-                    PreparedStatement insertStmt = 
conn.prepareStatement(INSERT_INTO_CONFIGURED_OBJECTS);
-                    try
+                    try (PreparedStatement insertStmt = 
conn.prepareStatement(INSERT_INTO_CONFIGURED_OBJECTS))
                     {
                         insertStmt.setString(1, 
configuredObject.getId().toString());
                         insertStmt.setString(2, configuredObject.getType());
-                        if(configuredObject.getAttributes() == null)
+                        if (configuredObject.getAttributes() == null)
                         {
                             insertStmt.setNull(3, Types.BLOB);
                         }
@@ -823,42 +779,24 @@ public abstract class AbstractJDBCConfig
                         }
                         insertStmt.execute();
                     }
-                    finally
-                    {
-                        insertStmt.close();
-                    }
                     writeHierarchy(configuredObject, conn);
                 }
             }
-            finally
-            {
-                rs.close();
-            }
-        }
-        catch (JsonMappingException e)
-        {
-            throw new StoreException("Error updating configured object " + 
configuredObject + " in database: " + e.getMessage(), e);
-        }
-        catch (JsonGenerationException e)
-        {
-            throw new StoreException("Error updating configured object " + 
configuredObject + " in database: " + e.getMessage(), e);
         }
         catch (IOException e)
         {
-            throw new StoreException("Error updating configured object " + 
configuredObject + " in database: " + e.getMessage(), e);
-        }
-        finally
-        {
-            stmt.close();
+            throw new StoreException("Error updating configured object "
+                                     + configuredObject
+                                     + " in database: "
+                                     + e.getMessage(), e);
         }
     }
 
     private void writeHierarchy(final ConfiguredObjectRecord configuredObject, 
final Connection conn) throws SQLException, StoreException
     {
-        PreparedStatement insertStmt = 
conn.prepareStatement(INSERT_INTO_CONFIGURED_OBJECT_HIERARCHY);
-        try
+        try (PreparedStatement insertStmt = 
conn.prepareStatement(INSERT_INTO_CONFIGURED_OBJECT_HIERARCHY))
         {
-            for(Map.Entry<String,UUID> parentEntry : 
configuredObject.getParents().entrySet())
+            for (Map.Entry<String, UUID> parentEntry : 
configuredObject.getParents().entrySet())
             {
                 insertStmt.setString(1, configuredObject.getId().toString());
                 insertStmt.setString(2, parentEntry.getKey());
@@ -867,10 +805,6 @@ public abstract class AbstractJDBCConfig
                 insertStmt.execute();
             }
         }
-        finally
-        {
-            insertStmt.close();
-        }
     }
 
     protected abstract String getBlobAsString(ResultSet rs, int col) throws 
SQLException;
@@ -969,32 +903,33 @@ public abstract class AbstractJDBCConfig
         }
     }
 
-    private static class ConfiguredObjectRecordPresenceDetector implements 
ConfiguredObjectRecordHandler
+    private final void assertState(State state)
     {
-        private boolean _recordsPresent;
-
-        @Override
-        public void begin()
+        synchronized (_lock)
         {
-
-        }
-
-        @Override
-        public boolean handle(final ConfiguredObjectRecord record)
-        {
-            _recordsPresent = true;
-            return false;
+            if(_state != state)
+            {
+                throw new IllegalStateException("The store must be in state " 
+ state + " to perform this operation, but it is in state " + _state + " 
instead");
+            }
         }
+    }
 
-        @Override
-        public void end()
+    protected final void changeState(State oldState, State newState)
+    {
+        synchronized (_lock)
         {
-
+            assertState(oldState);
+            _state = newState;
         }
+    }
 
-        public boolean isRecordsPresent()
+    protected final void setState(State newState)
+    {
+        synchronized (_lock)
         {
-            return _recordsPresent;
+            _state = newState;
         }
     }
+
+
 }

Modified: 
qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/store/AbstractMemoryStore.java
URL: 
http://svn.apache.org/viewvc/qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/store/AbstractMemoryStore.java?rev=1753882&r1=1753881&r2=1753882&view=diff
==============================================================================
--- 
qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/store/AbstractMemoryStore.java
 (original)
+++ 
qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/store/AbstractMemoryStore.java
 Sat Jul 23 19:30:45 2016
@@ -34,6 +34,10 @@ public abstract class AbstractMemoryStor
     private final MessageStore _messageStore = new MemoryMessageStore();
     private final Class<? extends ConfiguredObject> _rootClass;
 
+    enum State { CLOSED, CONFIGURED, OPEN };
+
+    private State _state = State.CLOSED;
+    private final Object _lock = new Object();
 
     private final ConcurrentMap<UUID, ConfiguredObjectRecord> 
_configuredObjectRecords = new ConcurrentHashMap<UUID, 
ConfiguredObjectRecord>();
 
@@ -45,6 +49,7 @@ public abstract class AbstractMemoryStor
     @Override
     public void create(ConfiguredObjectRecord record)
     {
+        assertState(State.OPEN);
         if (_configuredObjectRecords.putIfAbsent(record.getId(), record) != 
null)
         {
             throw new StoreException("Record with id " + record.getId() + " is 
already present");
@@ -54,6 +59,7 @@ public abstract class AbstractMemoryStor
     @Override
     public void update(boolean createIfNecessary, ConfiguredObjectRecord... 
records)
     {
+        assertState(State.OPEN);
         for (ConfiguredObjectRecord record : records)
         {
             if(createIfNecessary)
@@ -74,6 +80,7 @@ public abstract class AbstractMemoryStor
     @Override
     public UUID[] remove(final ConfiguredObjectRecord... objects)
     {
+        assertState(State.OPEN);
         List<UUID> removed = new ArrayList<UUID>();
         for (ConfiguredObjectRecord record : objects)
         {
@@ -86,14 +93,9 @@ public abstract class AbstractMemoryStor
     }
 
     @Override
-    public void openConfigurationStore(ConfiguredObject<?> parent,
-                                       final boolean overwrite,
-                                       final ConfiguredObjectRecord... 
initialRecords)
+    public void init(ConfiguredObject<?> parent)
     {
-        for(ConfiguredObjectRecord record : initialRecords)
-        {
-            _configuredObjectRecords.put(record.getId(), record);
-        }
+        changeState(State.CLOSED, State.CONFIGURED);
     }
 
     @Override
@@ -105,24 +107,45 @@ public abstract class AbstractMemoryStor
     @Override
     public void closeConfigurationStore()
     {
+        synchronized (_lock)
+        {
+            _state = State.CLOSED;
+        }
         _configuredObjectRecords.clear();
     }
 
 
     @Override
-    public void visitConfiguredObjectRecords(ConfiguredObjectRecordHandler 
handler) throws StoreException
+    public boolean openConfigurationStore(ConfiguredObjectRecordHandler 
handler,
+                                          final ConfiguredObjectRecord... 
initialRecords) throws StoreException
     {
-        handler.begin();
-        for (ConfiguredObjectRecord record : _configuredObjectRecords.values())
+        changeState(State.CONFIGURED, State.OPEN);
+        boolean isNew = _configuredObjectRecords.isEmpty();
+        if(isNew)
         {
-            if (!handler.handle(record))
+            for(ConfiguredObjectRecord record : initialRecords)
             {
-                break;
+                _configuredObjectRecords.put(record.getId(), record);
             }
         }
-        handler.end();
+        for (ConfiguredObjectRecord record : _configuredObjectRecords.values())
+        {
+            handler.handle(record);
+        }
+        return isNew;
+    }
+
+    @Override
+    public void reload(ConfiguredObjectRecordHandler handler) throws 
StoreException
+    {
+        assertState(State.OPEN);
+        for (ConfiguredObjectRecord record : _configuredObjectRecords.values())
+        {
+            handler.handle(record);
+        }
     }
 
+
     @Override
     public MessageStore getMessageStore()
     {
@@ -134,4 +157,30 @@ public abstract class AbstractMemoryStor
     {
     }
 
+    private void assertState(State state)
+    {
+        synchronized (_lock)
+        {
+            if(_state != state)
+            {
+                throw new IllegalStateException("The store must be in state " 
+ state + " to perform this operation, but it is in state " + _state + " 
instead");
+            }
+        }
+    }
+
+    private void changeState(State oldState, State newState)
+    {
+        synchronized (_lock)
+        {
+            assertState(oldState);
+            _state = newState;
+        }
+    }
+
+
+    public List<ConfiguredObjectRecord> getConfiguredObjectRecords()
+    {
+        return new ArrayList<>(_configuredObjectRecords.values());
+    }
+
 }

Modified: 
qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/store/BrokerStoreUpgraderAndRecoverer.java
URL: 
http://svn.apache.org/viewvc/qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/store/BrokerStoreUpgraderAndRecoverer.java?rev=1753882&r1=1753881&r2=1753882&view=diff
==============================================================================
--- 
qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/store/BrokerStoreUpgraderAndRecoverer.java
 (original)
+++ 
qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/store/BrokerStoreUpgraderAndRecoverer.java
 Sat Jul 23 19:30:45 2016
@@ -896,11 +896,11 @@ public class BrokerStoreUpgraderAndRecov
         return brokerRecord;
     }
 
-    public Broker<?> perform()
+    public Broker<?> perform(final ConfiguredObjectRecord... initialRecords)
     {
         final DurableConfigurationStore store = 
_systemConfig.getConfigurationStore();
-        List<ConfiguredObjectRecord> upgradedRecords = upgrade(store);
-        new GenericRecoverer(_systemConfig).recover(upgradedRecords);
+        List<ConfiguredObjectRecord> upgradedRecords = upgrade(store, 
initialRecords);
+        new GenericRecoverer(_systemConfig).recover(upgradedRecords, false);
 
         final StoreConfigurationChangeListener configChangeListener = new 
StoreConfigurationChangeListener(store);
         applyRecursively(_systemConfig.getBroker(), new 
RecursiveAction<ConfiguredObject<?>>()
@@ -921,10 +921,11 @@ public class BrokerStoreUpgraderAndRecov
         return _systemConfig.getBroker();
     }
 
-    List<ConfiguredObjectRecord> upgrade(final DurableConfigurationStore store)
+    List<ConfiguredObjectRecord> upgrade(final DurableConfigurationStore store,
+                                         final ConfiguredObjectRecord... 
initialRecords)
     {
         GenericStoreUpgrader upgrader = new 
GenericStoreUpgrader(Broker.class.getSimpleName(), Broker.MODEL_VERSION, store, 
_upgraders);
-        upgrader.upgrade();
+        boolean isNew = upgrader.upgrade(initialRecords);
         return upgrader.getRecords();
     }
 

Modified: 
qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/store/DurableConfigurationStore.java
URL: 
http://svn.apache.org/viewvc/qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/store/DurableConfigurationStore.java?rev=1753882&r1=1753881&r2=1753882&view=diff
==============================================================================
--- 
qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/store/DurableConfigurationStore.java
 (original)
+++ 
qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/store/DurableConfigurationStore.java
 Sat Jul 23 19:30:45 2016
@@ -30,13 +30,10 @@ public interface DurableConfigurationSto
     /**
      * Initializes and opens the configuration store.
      * @param parent
-     * @param overwrite
-     * @param initialRecords
+     *
      *
      */
-    void openConfigurationStore(ConfiguredObject<?> parent,
-                                final boolean overwrite,
-                                final ConfiguredObjectRecord... 
initialRecords) throws StoreException;
+    void init(ConfiguredObject<?> parent) throws StoreException;
 
     /**
      * Requests that the store performs any upgrade work on the store's 
structure. If there is no
@@ -52,9 +49,12 @@ public interface DurableConfigurationSto
      * Visit all configured object records with given handler.
      *
      * @param handler a handler to invoke on each configured object record
+     * @param initialRecords
      * @throws StoreException
      */
-    void visitConfiguredObjectRecords(ConfiguredObjectRecordHandler handler) 
throws StoreException;
+    boolean openConfigurationStore(ConfiguredObjectRecordHandler handler, 
final ConfiguredObjectRecord... initialRecords) throws StoreException;
+
+    void reload(ConfiguredObjectRecordHandler handler) throws StoreException;
 
     /**
      * Makes the specified object persistent.

Modified: 
qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/store/GenericRecoverer.java
URL: 
http://svn.apache.org/viewvc/qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/store/GenericRecoverer.java?rev=1753882&r1=1753881&r2=1753882&view=diff
==============================================================================
--- 
qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/store/GenericRecoverer.java
 (original)
+++ 
qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/store/GenericRecoverer.java
 Sat Jul 23 19:30:45 2016
@@ -34,6 +34,7 @@ import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 import org.apache.qpid.server.configuration.updater.Task;
+import org.apache.qpid.server.model.AbstractConfiguredObject;
 import org.apache.qpid.server.model.ConfiguredObject;
 import org.apache.qpid.server.model.ConfiguredObjectFactory;
 import org.apache.qpid.server.util.ServerScopedRuntimeException;
@@ -49,14 +50,14 @@ public class GenericRecoverer
         _root = root;
     }
 
-    public void recover(final List<ConfiguredObjectRecord> records)
+    public void recover(final List<ConfiguredObjectRecord> records, final 
boolean isNew)
     {
         _root.getTaskExecutor().run(new Task<Void, RuntimeException>()
         {
             @Override
             public Void execute()
             {
-                performRecover(records);
+                performRecover(records, isNew);
                 return null;
             }
 
@@ -80,7 +81,7 @@ public class GenericRecoverer
         });
     }
 
-    private void performRecover(List<ConfiguredObjectRecord> records)
+    private void performRecover(List<ConfiguredObjectRecord> records, final 
boolean isNew)
     {
         if (LOGGER.isDebugEnabled())
         {
@@ -88,7 +89,7 @@ public class GenericRecoverer
         }
 
         records = resolveDiscontinuity(records);
-        resolveObjects(_root, records);
+        resolveObjects(_root, records, isNew);
     }
 
     private List<ConfiguredObjectRecord> resolveDiscontinuity(final 
List<ConfiguredObjectRecord> records)
@@ -141,7 +142,9 @@ public class GenericRecoverer
         return false;
     }
 
-    private void resolveObjects(ConfiguredObject<?> parentObject, 
List<ConfiguredObjectRecord> records)
+    private void resolveObjects(ConfiguredObject<?> parentObject,
+                                List<ConfiguredObjectRecord> records,
+                                final boolean isNew)
     {
         ConfiguredObjectFactory factory = parentObject.getObjectFactory();
         Map<UUID, ConfiguredObject<?>> resolvedObjects = new HashMap<UUID, 
ConfiguredObject<?>>();
@@ -184,7 +187,10 @@ public class GenericRecoverer
                     {
                         updatesMade = true;
                         ConfiguredObject<?> resolved = recovered.resolve();
-                        resolved.decryptSecrets();
+                        if(!isNew)
+                        {
+                            resolved.decryptSecrets();
+                        }
                         resolvedObjects.put(resolved.getId(), resolved);
                     }
                     else

Modified: 
qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/store/GenericStoreUpgrader.java
URL: 
http://svn.apache.org/viewvc/qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/store/GenericStoreUpgrader.java?rev=1753882&r1=1753881&r2=1753882&view=diff
==============================================================================
--- 
qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/store/GenericStoreUpgrader.java
 (original)
+++ 
qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/store/GenericStoreUpgrader.java
 Sat Jul 23 19:30:45 2016
@@ -58,30 +58,15 @@ public class GenericStoreUpgrader
         return new ArrayList<ConfiguredObjectRecord>(_records.values());
     }
 
-    public void upgrade()
+    public boolean upgrade(final ConfiguredObjectRecord... initialRecords)
     {
-        ConfiguredObjectRecordHandler handler = new 
ConfiguredObjectRecordHandler()
-        {
-            @Override
-            public void begin()
-            {
-            }
+        RecordCollectionHandler handler = new RecordCollectionHandler();
 
-            @Override
-            public boolean handle(final ConfiguredObjectRecord record)
-            {
-                _records.put(record.getId(), record);
-                return true;
-            }
+        boolean isNewStore = _store.openConfigurationStore(handler, 
initialRecords);
 
-            @Override
-            public void end()
-            {
-                performUpgrade();
-            }
-        };
+        performUpgrade();
 
-        _store.visitConfiguredObjectRecords(handler);
+        return isNewStore;
     }
 
     private void performUpgrade()
@@ -169,4 +154,15 @@ public class GenericStoreUpgrader
         }
         return BrokerModel.MODEL_VERSION;
     }
+
+    private class RecordCollectionHandler implements 
ConfiguredObjectRecordHandler
+    {
+
+        @Override
+        public void handle(final ConfiguredObjectRecord record)
+        {
+            _records.put(record.getId(), record);
+        }
+
+    }
 }

Modified: 
qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/store/JsonFileConfigStore.java
URL: 
http://svn.apache.org/viewvc/qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/store/JsonFileConfigStore.java?rev=1753882&r1=1753881&r2=1753882&view=diff
==============================================================================
--- 
qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/store/JsonFileConfigStore.java
 (original)
+++ 
qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/store/JsonFileConfigStore.java
 Sat Jul 23 19:30:45 2016
@@ -37,6 +37,8 @@ import java.util.UUID;
 
 import com.fasterxml.jackson.databind.ObjectMapper;
 import com.fasterxml.jackson.databind.SerializationFeature;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 import org.apache.qpid.server.configuration.BrokerProperties;
 import org.apache.qpid.server.model.ConfiguredObject;
@@ -46,7 +48,7 @@ import org.apache.qpid.server.store.hand
 
 public class JsonFileConfigStore extends AbstractJsonFileStore implements 
DurableConfigurationStore
 {
-
+    private static final Logger LOGGER = 
LoggerFactory.getLogger(JsonFileConfigStore.class);
 
     private static final Comparator<Class<? extends ConfiguredObject>> 
CATEGORY_CLASS_COMPARATOR =
             new Comparator<Class<? extends ConfiguredObject>>()
@@ -78,6 +80,10 @@ public class JsonFileConfigStore extends
 
     private ConfiguredObject<?> _parent;
 
+    private enum State { CLOSED, CONFIGURED, OPEN };
+    private State _state = State.CLOSED;
+    private final Object _lock = new Object();
+
     public JsonFileConfigStore(Class<? extends ConfiguredObject> rootClass)
     {
         super();
@@ -92,57 +98,73 @@ public class JsonFileConfigStore extends
     }
 
     @Override
-    public void openConfigurationStore(ConfiguredObject<?> parent,
-                                       final boolean overwrite,
-                                       final ConfiguredObjectRecord... 
initialRecords)
-    {
-        _parent = parent;
-        _classNameMapping = generateClassNameMap(_parent.getModel(), 
_rootClass);
-        FileBasedSettings fileBasedSettings = (FileBasedSettings)_parent;
-        setup(parent.getName(), fileBasedSettings.getStorePath(), 
parent.getContextValue(String.class, BrokerProperties.POSIX_FILE_PERMISSIONS),
-              Collections.emptyMap());
-        load(overwrite, initialRecords);
+    public void init(ConfiguredObject<?> parent)
+    {
+        assertState(State.CLOSED);
+            _parent = parent;
+            _classNameMapping = generateClassNameMap(_parent.getModel(), 
_rootClass);
+            FileBasedSettings fileBasedSettings = (FileBasedSettings) _parent;
+            setup(parent.getName(),
+                  fileBasedSettings.getStorePath(),
+                  parent.getContextValue(String.class, 
BrokerProperties.POSIX_FILE_PERMISSIONS),
+                  Collections.emptyMap());
+        changeState(State.CLOSED, State.CONFIGURED);
+
     }
 
     @Override
-    public void visitConfiguredObjectRecords(ConfiguredObjectRecordHandler 
handler)
+    public boolean openConfigurationStore(ConfiguredObjectRecordHandler 
handler,
+                                          final ConfiguredObjectRecord... 
initialRecords)
     {
-        handler.begin();
+        changeState(State.CONFIGURED, State.OPEN);
+        boolean isNew = load(initialRecords);
         List<ConfiguredObjectRecord> records = new 
ArrayList<ConfiguredObjectRecord>(_objectsById.values());
         for(ConfiguredObjectRecord record : records)
         {
-            boolean shouldContinue = handler.handle(record);
-            if (!shouldContinue)
-            {
-                break;
-            }
+            handler.handle(record);
+        }
+        return isNew;
+    }
+
+    @Override
+    public void reload(ConfiguredObjectRecordHandler handler)
+    {
+        assertState(State.OPEN);
+        _idsByType.clear();
+        _objectsById.clear();
+        load();
+        List<ConfiguredObjectRecord> records = new 
ArrayList<ConfiguredObjectRecord>(_objectsById.values());
+        for(ConfiguredObjectRecord record : records)
+        {
+            handler.handle(record);
         }
-        handler.end();
     }
 
-    protected void load(final boolean overwrite, final 
ConfiguredObjectRecord[] initialRecords)
+
+    protected boolean load(final ConfiguredObjectRecord... initialRecords)
     {
         final File configFile = getConfigFile();
         try
         {
+            LOGGER.debug("Loading file {}", configFile.getCanonicalPath());
+
             boolean updated = false;
             Collection<ConfiguredObjectRecord> records = 
Collections.emptyList();
-            if(!overwrite)
-            {
-                ConfiguredObjectRecordConverter 
configuredObjectRecordConverter =
-                        new 
ConfiguredObjectRecordConverter(_parent.getModel());
+            ConfiguredObjectRecordConverter configuredObjectRecordConverter =
+                    new ConfiguredObjectRecordConverter(_parent.getModel());
 
-                records = 
configuredObjectRecordConverter.readFromJson(_rootClass, _parent, new 
FileReader(configFile));
-            }
+            records = configuredObjectRecordConverter.readFromJson(_rootClass, 
_parent, new FileReader(configFile));
 
             if(records.isEmpty())
             {
+                LOGGER.debug("File contains no records - using initial 
configuration");
                 records = Arrays.asList(initialRecords);
                 updated = true;
             }
 
             for(ConfiguredObjectRecord record : records)
             {
+                LOGGER.debug("Loading record (Category: {} \t Name: {} \t ID: 
{}", record.getType(), record.getAttributes().get("name"), record.getId());
                 _objectsById.put(record.getId(), record);
                 List<UUID> idsForType = _idsByType.get(record.getType());
                 if (idsForType == null)
@@ -150,12 +172,17 @@ public class JsonFileConfigStore extends
                     idsForType = new ArrayList<>();
                     _idsByType.put(record.getType(), idsForType);
                 }
+                if(idsForType.contains(record.getId()))
+                {
+                    throw new IllegalArgumentException("Duplicate id for 
record " + record);
+                }
                 idsForType.add(record.getId());
             }
             if(updated)
             {
                 save();
             }
+            return updated;
         }
         catch (IOException e)
         {
@@ -166,6 +193,7 @@ public class JsonFileConfigStore extends
     @Override
     public synchronized void create(ConfiguredObjectRecord record) throws 
StoreException
     {
+        assertState(State.OPEN);
         if(_objectsById.containsKey(record.getId()))
         {
             throw new StoreException("Object with id " + record.getId() + " 
already exists");
@@ -197,6 +225,10 @@ public class JsonFileConfigStore extends
             {
                 throw new IllegalStateException("Only a single root entry of 
type " + _rootClass.getSimpleName() + " can exist in the store.");
             }
+            if(idsForType.contains(record.getId()))
+            {
+                throw new IllegalArgumentException("Duplicate id for record " 
+ record);
+            }
 
             idsForType.add(record.getId());
 
@@ -222,7 +254,6 @@ public class JsonFileConfigStore extends
     {
         UUID rootId = getRootId();
         final Map<String, Object> data;
-
         if (rootId == null)
         {
             data = Collections.emptyMap();
@@ -308,6 +339,8 @@ public class JsonFileConfigStore extends
     @Override
     public synchronized UUID[] remove(final ConfiguredObjectRecord... objects) 
throws StoreException
     {
+        assertState(State.OPEN);
+
         if (objects.length == 0)
         {
             return new UUID[0];
@@ -332,6 +365,8 @@ public class JsonFileConfigStore extends
     public synchronized void update(final boolean createIfNecessary, final 
ConfiguredObjectRecord... records)
             throws StoreException
     {
+        assertState(State.OPEN);
+
         if (records.length == 0)
         {
             return;
@@ -381,6 +416,11 @@ public class JsonFileConfigStore extends
                     idsForType = new ArrayList<UUID>();
                     _idsByType.put(type, idsForType);
                 }
+                if(idsForType.contains(record.getId()))
+                {
+                    throw new IllegalArgumentException("Duplicate id for 
record " + record);
+                }
+
                 idsForType.add(id);
             }
         }
@@ -391,6 +431,7 @@ public class JsonFileConfigStore extends
     @Override
     public void closeConfigurationStore()
     {
+
         try
         {
             cleanup();
@@ -399,6 +440,10 @@ public class JsonFileConfigStore extends
         {
             _idsByType.clear();
             _objectsById.clear();
+            synchronized (_lock)
+            {
+                _state = State.CLOSED;
+            }
         }
     }
 
@@ -431,4 +476,25 @@ public class JsonFileConfigStore extends
     {
         return _objectMapper;
     }
+
+    private void assertState(State state)
+    {
+        synchronized (_lock)
+        {
+            if(_state != state)
+            {
+                throw new IllegalStateException("The store must be in state " 
+ state + " to perform this operation, but it is in state " + _state + " 
instead");
+            }
+        }
+    }
+
+    private void changeState(State oldState, State newState)
+    {
+        synchronized (_lock)
+        {
+            assertState(oldState);
+            _state = newState;
+        }
+    }
+
 }




---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to