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]