Author: lquack
Date: Thu Jul 14 16:01:06 2016
New Revision: 1752681

URL: http://svn.apache.org/viewvc?rev=1752681&view=rev
Log:
QPID-7332: [Java Broker] Prevent BDB Preference Store downgrading and fix state 
handling on concurrent open and close

Modified:
    
qpid/java/trunk/bdbstore/src/main/java/org/apache/qpid/server/store/berkeleydb/AbstractBDBPreferenceStore.java

Modified: 
qpid/java/trunk/bdbstore/src/main/java/org/apache/qpid/server/store/berkeleydb/AbstractBDBPreferenceStore.java
URL: 
http://svn.apache.org/viewvc/qpid/java/trunk/bdbstore/src/main/java/org/apache/qpid/server/store/berkeleydb/AbstractBDBPreferenceStore.java?rev=1752681&r1=1752680&r2=1752681&view=diff
==============================================================================
--- 
qpid/java/trunk/bdbstore/src/main/java/org/apache/qpid/server/store/berkeleydb/AbstractBDBPreferenceStore.java
 (original)
+++ 
qpid/java/trunk/bdbstore/src/main/java/org/apache/qpid/server/store/berkeleydb/AbstractBDBPreferenceStore.java
 Thu Jul 14 16:01:06 2016
@@ -71,48 +71,17 @@ abstract class AbstractBDBPreferenceStor
 
         try
         {
-            Collection<PreferenceRecord> records = new LinkedHashSet<>();
-
-            Cursor cursor = null;
-
-            try
-            {
-                cursor = getPreferencesDb().openCursor(null, null);
-                DatabaseEntry key = new DatabaseEntry();
-                DatabaseEntry value = new DatabaseEntry();
-                UUIDTupleBinding keyBinding = UUIDTupleBinding.getInstance();
-                MapBinding valueBinding = MapBinding.getInstance();
+            ModelVersion currentVersion =
+                    new ModelVersion(BrokerModel.MODEL_MAJOR_VERSION, 
BrokerModel.MODEL_MINOR_VERSION);
+            ModelVersion storedVersion = getStoredVersion();
 
-                while (cursor.getNext(key, value, LockMode.RMW) == 
OperationStatus.SUCCESS)
-                {
-                    UUID preferenceId = keyBinding.entryToObject(key);
-                    Map<String, Object> preferenceAttributes = 
valueBinding.entryToObject(value);
-                    PreferenceRecord record = new 
PreferenceRecordImpl(preferenceId, preferenceAttributes);
-                    records.add(record);
-                }
-            }
-            catch (RuntimeException e)
+            if (currentVersion.lessThan(storedVersion))
             {
-                throw environmentFacade.handleDatabaseException("Cannot visit 
messages", e);
-            }
-            finally
-            {
-                if (cursor != null)
-                {
-                    try
-                    {
-                        cursor.close();
-                    }
-                    catch (RuntimeException e)
-                    {
-                        throw 
environmentFacade.handleDatabaseException("Cannot close cursor", e);
-                    }
-                }
+                throw new StoreException(String.format("Cannot downgrade 
preference store from '%s' to '%s'", storedVersion, currentVersion));
             }
 
-            ModelVersion currentVersion =
-                    new ModelVersion(BrokerModel.MODEL_MAJOR_VERSION, 
BrokerModel.MODEL_MINOR_VERSION);
-            ModelVersion storedVersion = getStoredVersion();
+            Collection<PreferenceRecord> records = 
getPreferenceRecords(environmentFacade);
+
             if (storedVersion.lessThan(currentVersion))
             {
                 final Collection<UUID> ids = new HashSet<>();
@@ -130,6 +99,7 @@ abstract class AbstractBDBPreferenceStor
         }
         catch (Exception e)
         {
+            _storeState.set(StoreState.ERRORED);
             close();
             throw e;
         }
@@ -229,7 +199,7 @@ abstract class AbstractBDBPreferenceStor
         while (true)
         {
             StoreState storeState = getStoreState();
-            if (storeState.equals(StoreState.OPENED) || 
storeState.equals(StoreState.OPENING))
+            if (storeState.equals(StoreState.OPENED) || 
storeState.equals(StoreState.ERRORED))
             {
                 if (_storeState.compareAndSet(storeState, StoreState.CLOSING))
                 {
@@ -253,6 +223,49 @@ abstract class AbstractBDBPreferenceStor
         return _storeState.get();
     }
 
+    private Collection<PreferenceRecord> getPreferenceRecords(final 
EnvironmentFacade environmentFacade)
+    {
+        Collection<PreferenceRecord> records = new LinkedHashSet<>();
+
+        Cursor cursor = null;
+
+        try
+        {
+            cursor = getPreferencesDb().openCursor(null, null);
+            DatabaseEntry key = new DatabaseEntry();
+            DatabaseEntry value = new DatabaseEntry();
+            UUIDTupleBinding keyBinding = UUIDTupleBinding.getInstance();
+            MapBinding valueBinding = MapBinding.getInstance();
+
+            while (cursor.getNext(key, value, LockMode.RMW) == 
OperationStatus.SUCCESS)
+            {
+                UUID preferenceId = keyBinding.entryToObject(key);
+                Map<String, Object> preferenceAttributes = 
valueBinding.entryToObject(value);
+                PreferenceRecord record = new 
PreferenceRecordImpl(preferenceId, preferenceAttributes);
+                records.add(record);
+            }
+        }
+        catch (RuntimeException e)
+        {
+            throw environmentFacade.handleDatabaseException("Cannot visit 
messages", e);
+        }
+        finally
+        {
+            if (cursor != null)
+            {
+                try
+                {
+                    cursor.close();
+                }
+                catch (RuntimeException e)
+                {
+                    throw environmentFacade.handleDatabaseException("Cannot 
close cursor", e);
+                }
+            }
+        }
+        return records;
+    }
+
     private void updateOrCreateInternal(final Transaction txn,
                                         final Collection<PreferenceRecord> 
preferenceRecords)
     {
@@ -351,6 +364,6 @@ abstract class AbstractBDBPreferenceStor
 
     enum StoreState
     {
-        CLOSED, OPENING, OPENED, CLOSING;
+        CLOSED, OPENING, OPENED, CLOSING, ERRORED;
     }
 }



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

Reply via email to