Author: lquack
Date: Mon Jul 18 10:02:25 2016
New Revision: 1753191

URL: http://svn.apache.org/viewvc?rev=1753191&view=rev
Log:
QPID-7335: [Java Broker] Invoke preferences operations in dedicated threads

Added:
    
qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/model/OperationTimeoutException.java
      - copied, changed from r1753106, 
qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/model/preferences/UserPreferences.java
    
qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/util/FutureHelper.java
Modified:
    
qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/configuration/updater/TaskExecutor.java
    
qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/configuration/updater/TaskExecutorImpl.java
    
qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/model/adapter/BrokerAdapter.java
    
qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/model/preferences/UserPreferences.java
    
qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/model/preferences/UserPreferencesImpl.java
    
qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/store/preferences/PreferencesRecoverer.java
    
qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/virtualhost/AbstractVirtualHost.java
    
qpid/java/trunk/broker-core/src/test/java/org/apache/qpid/server/configuration/updater/CurrentThreadTaskExecutor.java
    
qpid/java/trunk/broker-core/src/test/java/org/apache/qpid/server/model/preferences/PreferenceTestHelper.java
    
qpid/java/trunk/broker-core/src/test/java/org/apache/qpid/server/model/preferences/UserPreferencesTest.java
    
qpid/java/trunk/broker-core/src/test/java/org/apache/qpid/server/model/testmodels/singleton/PreferencesTest.java
    
qpid/java/trunk/broker-core/src/test/java/org/apache/qpid/server/store/preferences/PreferencesRecovererTest.java
    
qpid/java/trunk/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/HttpManagementConfiguration.java
    
qpid/java/trunk/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/rest/RestServlet.java
    
qpid/java/trunk/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/rest/RestUserPreferenceHandler.java
    
qpid/java/trunk/broker-plugins/management-http/src/test/java/org/apache/qpid/server/management/plugin/servlet/rest/RestUserPreferenceHandlerTest.java

Modified: 
qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/configuration/updater/TaskExecutor.java
URL: 
http://svn.apache.org/viewvc/qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/configuration/updater/TaskExecutor.java?rev=1753191&r1=1753190&r2=1753191&view=diff
==============================================================================
--- 
qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/configuration/updater/TaskExecutor.java
 (original)
+++ 
qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/configuration/updater/TaskExecutor.java
 Mon Jul 18 10:02:25 2016
@@ -23,7 +23,8 @@ package org.apache.qpid.server.configura
 import java.security.Principal;
 import java.util.concurrent.CancellationException;
 import java.util.concurrent.Executor;
-import java.util.concurrent.Future;
+
+import com.google.common.util.concurrent.ListenableFuture;
 
 public interface TaskExecutor extends Executor
 {
@@ -48,7 +49,7 @@ public interface TaskExecutor extends Ex
 
     <T, E extends Exception> T run(Task<T, E> task) throws 
CancellationException, E;
 
-    <T, E extends Exception> Future<T> submit(Task<T, E> task) throws 
CancellationException, E;
+    <T, E extends Exception> ListenableFuture<T> submit(Task<T, E> task) 
throws CancellationException, E;
 
     Factory getFactory();
 }

Modified: 
qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/configuration/updater/TaskExecutorImpl.java
URL: 
http://svn.apache.org/viewvc/qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/configuration/updater/TaskExecutorImpl.java?rev=1753191&r1=1753190&r2=1753191&view=diff
==============================================================================
--- 
qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/configuration/updater/TaskExecutorImpl.java
 (original)
+++ 
qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/configuration/updater/TaskExecutorImpl.java
 Mon Jul 18 10:02:25 2016
@@ -28,7 +28,6 @@ import java.util.List;
 import java.util.Set;
 import java.util.concurrent.Callable;
 import java.util.concurrent.CancellationException;
-import java.util.concurrent.ExecutionException;
 import java.util.concurrent.Executor;
 import java.util.concurrent.ExecutorService;
 import java.util.concurrent.Executors;
@@ -41,10 +40,14 @@ import java.util.concurrent.atomic.Atomi
 
 import javax.security.auth.Subject;
 
+import com.google.common.util.concurrent.Futures;
+import com.google.common.util.concurrent.ListenableFuture;
+import com.google.common.util.concurrent.ListeningExecutorService;
+import com.google.common.util.concurrent.MoreExecutors;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import org.apache.qpid.server.util.ServerScopedRuntimeException;
+import org.apache.qpid.server.util.FutureHelper;
 
 public class TaskExecutorImpl implements TaskExecutor
 {
@@ -54,7 +57,7 @@ public class TaskExecutorImpl implements
 
     private volatile Thread _taskThread;
     private final AtomicBoolean _running = new AtomicBoolean();
-    private volatile ExecutorService _executor;
+    private volatile ListeningExecutorService _executor;
     private final ImmediateIfSameThreadExecutor _wrappedExecutor = new 
ImmediateIfSameThreadExecutor();
     private final String _name;
 
@@ -81,7 +84,7 @@ public class TaskExecutorImpl implements
         if (_running.compareAndSet(false, true))
         {
             LOGGER.debug("Starting task executor {}", _name);
-            _executor = Executors.newFixedThreadPool(1, new ThreadFactory()
+            _executor = 
MoreExecutors.listeningDecorator(Executors.newFixedThreadPool(1, new 
ThreadFactory()
             {
                 @Override
                 public Thread newThread(Runnable r)
@@ -89,7 +92,7 @@ public class TaskExecutorImpl implements
                     _taskThread = new TaskThread(r, _name, 
TaskExecutorImpl.this);
                     return _taskThread;
                 }
-            });
+            }));
             LOGGER.debug("Task executor is started");
         }
     }
@@ -137,12 +140,12 @@ public class TaskExecutorImpl implements
     }
 
     @Override
-    public <T, E extends Exception> Future<T> submit(Task<T, E> userTask) 
throws E
+    public <T, E extends Exception> ListenableFuture<T> submit(Task<T, E> 
userTask) throws E
     {
         return submitWrappedTask(new TaskLoggingWrapper<>(userTask));
     }
 
-    private <T, E extends Exception> Future<T> 
submitWrappedTask(TaskLoggingWrapper<T, E> task) throws E
+    private <T, E extends Exception> ListenableFuture<T> 
submitWrappedTask(TaskLoggingWrapper<T, E> task) throws E
     {
         checkState(task);
         if (isTaskExecutorThread())
@@ -152,7 +155,7 @@ public class TaskExecutorImpl implements
                 LOGGER.trace("Running {} immediately", task);
             }
             T result = task.execute();
-            return new ImmediateFuture<>(result);
+            return Futures.immediateFuture(result);
         }
         else
         {
@@ -172,44 +175,11 @@ public class TaskExecutorImpl implements
         _wrappedExecutor.execute(command);
     }
 
-
     @Override
     public <T, E extends Exception> T run(Task<T, E> userTask) throws 
CancellationException, E
     {
         TaskLoggingWrapper<T, E> task = new TaskLoggingWrapper<>(userTask);
-        try
-        {
-            Future<T> future = submitWrappedTask(task);
-            return future.get();
-        }
-        catch (InterruptedException e)
-        {
-            Thread.currentThread().interrupt();
-            throw new ServerScopedRuntimeException("Task execution was 
interrupted: " + task, e);
-        }
-        catch (ExecutionException e)
-        {
-            Throwable cause = e.getCause();
-            if (cause instanceof RuntimeException)
-            {
-                throw (RuntimeException) cause;
-            }
-            else if (cause instanceof Error)
-            {
-                throw (Error) cause;
-            }
-            else
-            {
-                try
-                {
-                    throw (E) cause;
-                }
-                catch (ClassCastException cce)
-                {
-                    throw new ServerScopedRuntimeException("Failed to execute 
user task: " + task, cause);
-                }
-            }
-        }
+        return FutureHelper.<T, E>await(submitWrappedTask(task));
     }
 
     private boolean isTaskExecutorThread()

Copied: 
qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/model/OperationTimeoutException.java
 (from r1753106, 
qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/model/preferences/UserPreferences.java)
URL: 
http://svn.apache.org/viewvc/qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/model/OperationTimeoutException.java?p2=qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/model/OperationTimeoutException.java&p1=qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/model/preferences/UserPreferences.java&r1=1753106&r2=1753191&rev=1753191&view=diff
==============================================================================
--- 
qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/model/preferences/UserPreferences.java
 (original)
+++ 
qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/model/OperationTimeoutException.java
 Mon Jul 18 10:02:25 2016
@@ -15,25 +15,26 @@
  * KIND, either express or implied.  See the License for the
  * specific language governing permissions and limitations
  * under the License.
- *
  */
 
-package org.apache.qpid.server.model.preferences;
+package org.apache.qpid.server.model;
 
-import java.util.Collection;
-import java.util.Set;
+import java.util.concurrent.TimeoutException;
 
-public interface UserPreferences
+public class OperationTimeoutException extends RuntimeException
 {
-    void updateOrAppend(Collection<Preference> preferences);
-
-    Set<Preference> getPreferences();
-
-    void replace(Collection<Preference> preferences);
-
-    void replaceByType(String type, Collection<Preference> preferences);
-
-    void replaceByTypeAndName(String type, String name, Preference preference);
-
-    Set<Preference> getVisiblePreferences();
+    public OperationTimeoutException(final String message)
+    {
+        super(message);
+    }
+
+    public OperationTimeoutException(final String message, final Throwable 
cause)
+    {
+        super(message, cause);
+    }
+
+    public OperationTimeoutException(final Exception e)
+    {
+        super(e);
+    }
 }

Modified: 
qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/model/adapter/BrokerAdapter.java
URL: 
http://svn.apache.org/viewvc/qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/model/adapter/BrokerAdapter.java?rev=1753191&r1=1753190&r2=1753191&view=diff
==============================================================================
--- 
qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/model/adapter/BrokerAdapter.java
 (original)
+++ 
qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/model/adapter/BrokerAdapter.java
 Mon Jul 18 10:02:25 2016
@@ -62,6 +62,8 @@ import com.google.common.util.concurrent
 import com.google.common.util.concurrent.ListenableFuture;
 import org.apache.qpid.bytebuffer.QpidByteBuffer;
 import org.apache.qpid.server.BrokerPrincipal;
+import org.apache.qpid.server.configuration.updater.TaskExecutor;
+import org.apache.qpid.server.configuration.updater.TaskExecutorImpl;
 import org.apache.qpid.server.logging.QpidLoggerTurboFilter;
 import org.apache.qpid.server.logging.StartupAppender;
 import org.apache.qpid.server.plugin.SystemAddressSpaceCreator;
@@ -198,6 +200,7 @@ public class BrokerAdapter extends Abstr
     private final AddressSpaceRegistry _addressSpaceRegistry = new 
AddressSpaceRegistry();
     private ConfigurationChangeListener _accessControlProviderListener = new 
AccessControlProviderListener();
     private final AccessControl _accessControl;
+    private TaskExecutor _preferenceTaskExecutor;
 
     @ManagedObjectFactoryConstructor
     public BrokerAdapter(Map<String, Object> attributes,
@@ -422,6 +425,33 @@ public class BrokerAdapter extends Abstr
         }
     }
 
+    @SuppressWarnings("unused")
+    @StateTransition( currentState = {State.ACTIVE, State.ERRORED}, 
desiredState = State.STOPPED )
+    private ListenableFuture<Void> doStop()
+    {
+        closePreferenceStore();
+        stopPreferenceTaskExecutor();
+        return Futures.immediateFuture(null);
+    }
+
+    private void closePreferenceStore()
+    {
+        PreferenceStore ps = _preferenceStore;
+        if (ps != null)
+        {
+            ps.close();
+        }
+    }
+
+    private void stopPreferenceTaskExecutor()
+    {
+        TaskExecutor preferenceTaskExecutor = _preferenceTaskExecutor;
+        if (preferenceTaskExecutor != null)
+        {
+            preferenceTaskExecutor.stop();
+        }
+    }
+
     @Override
     public void initiateShutdown()
     {
@@ -473,7 +503,10 @@ public class BrokerAdapter extends Abstr
 
         final PreferenceStoreUpdaterImpl updater = new 
PreferenceStoreUpdaterImpl();
         final Collection<PreferenceRecord> preferenceRecords = 
_preferenceStore.openAndLoad(updater);
-        new PreferencesRecoverer().recoverPreferences(this, preferenceRecords, 
_preferenceStore);
+        _preferenceTaskExecutor = new TaskExecutorImpl("broker-" + getName() + 
"-preferences", null);
+        _preferenceTaskExecutor.start();
+        PreferencesRecoverer preferencesRecoverer = new 
PreferencesRecoverer(_preferenceTaskExecutor);
+        preferencesRecoverer.recoverPreferences(this, preferenceRecords, 
_preferenceStore);
 
         if (isManagementMode())
         {
@@ -793,10 +826,8 @@ public class BrokerAdapter extends Abstr
 
         shutdownHouseKeeping();
 
-        if (_preferenceStore != null)
-        {
-            _preferenceStore.close();
-        }
+        closePreferenceStore();
+        stopPreferenceTaskExecutor();
 
         _eventLogger.message(BrokerMessages.STOPPED());
 

Modified: 
qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/model/preferences/UserPreferences.java
URL: 
http://svn.apache.org/viewvc/qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/model/preferences/UserPreferences.java?rev=1753191&r1=1753190&r2=1753191&view=diff
==============================================================================
--- 
qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/model/preferences/UserPreferences.java
 (original)
+++ 
qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/model/preferences/UserPreferences.java
 Mon Jul 18 10:02:25 2016
@@ -22,18 +22,23 @@ package org.apache.qpid.server.model.pre
 
 import java.util.Collection;
 import java.util.Set;
+import java.util.UUID;
+
+import com.google.common.util.concurrent.ListenableFuture;
 
 public interface UserPreferences
 {
-    void updateOrAppend(Collection<Preference> preferences);
+    ListenableFuture<Void> updateOrAppend(Collection<Preference> preferences);
+
+    ListenableFuture<Set<Preference>> getPreferences();
 
-    Set<Preference> getPreferences();
+    ListenableFuture<Void> replace(Collection<Preference> preferences);
 
-    void replace(Collection<Preference> preferences);
+    ListenableFuture<Void> replaceByType(String type, Collection<Preference> 
preferences);
 
-    void replaceByType(String type, Collection<Preference> preferences);
+    ListenableFuture<Void> replaceByTypeAndName(String type, String name, 
Preference preference);
 
-    void replaceByTypeAndName(String type, String name, Preference preference);
+    ListenableFuture<Set<Preference>> getVisiblePreferences();
 
-    Set<Preference> getVisiblePreferences();
+    ListenableFuture<Void> delete(String type, String name, UUID id);
 }

Modified: 
qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/model/preferences/UserPreferencesImpl.java
URL: 
http://svn.apache.org/viewvc/qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/model/preferences/UserPreferencesImpl.java?rev=1753191&r1=1753190&r2=1753191&view=diff
==============================================================================
--- 
qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/model/preferences/UserPreferencesImpl.java
 (original)
+++ 
qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/model/preferences/UserPreferencesImpl.java
 Mon Jul 18 10:02:25 2016
@@ -22,7 +22,9 @@ package org.apache.qpid.server.model.pre
 
 import java.security.AccessController;
 import java.security.Principal;
+import java.security.PrivilegedAction;
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.Collection;
 import java.util.Collections;
 import java.util.Comparator;
@@ -39,10 +41,11 @@ import java.util.UUID;
 import javax.security.auth.Subject;
 
 import com.google.common.collect.Ordering;
+import com.google.common.util.concurrent.ListenableFuture;
 
-
-
-
+import org.apache.qpid.server.configuration.updater.Task;
+import org.apache.qpid.server.configuration.updater.TaskExecutor;
+import org.apache.qpid.server.model.ConfiguredObject;
 import org.apache.qpid.server.security.auth.AuthenticatedPrincipal;
 import org.apache.qpid.server.store.preferences.PreferenceRecord;
 import org.apache.qpid.server.store.preferences.PreferenceRecordImpl;
@@ -50,21 +53,22 @@ import org.apache.qpid.server.store.pref
 
 public class UserPreferencesImpl implements UserPreferences
 {
-    private final static Comparator<Preference> PREFERENCE_COMPARATOR = new 
Comparator<Preference>()
+    private static final Comparator<Preference> PREFERENCE_COMPARATOR = new 
Comparator<Preference>()
     {
         private final Ordering<Comparable> _ordering = 
Ordering.natural().nullsFirst();
+
         @Override
         public int compare(final Preference o1, final Preference o2)
         {
             int nameOrder = _ordering.compare(o1.getName(), o2.getName());
-            if(nameOrder != 0)
+            if (nameOrder != 0)
             {
                 return nameOrder;
             }
             else
             {
                 int typeOrder = _ordering.compare(o1.getType(), o2.getType());
-                if(typeOrder != 0)
+                if (typeOrder != 0)
                 {
                     return typeOrder;
                 }
@@ -79,13 +83,19 @@ public class UserPreferencesImpl impleme
     private final Map<UUID, Preference> _preferences;
     private final Map<String, List<Preference>> _preferencesByName;
     private final PreferenceStore _preferenceStore;
+    private final TaskExecutor _executor;
+    private final ConfiguredObject<?> _associatedObject;
 
-    public UserPreferencesImpl(final PreferenceStore preferenceStore, final 
Collection<Preference> preferences)
+    public UserPreferencesImpl(final TaskExecutor executor,
+                               final ConfiguredObject<?> associatedObject,
+                               final PreferenceStore preferenceStore,
+                               final Collection<Preference> preferences)
     {
         _preferences = new HashMap<>();
         _preferencesByName = new HashMap<>();
         _preferenceStore = preferenceStore;
-
+        _executor = executor;
+        _associatedObject = associatedObject;
         for (Preference preference : preferences)
         {
             addPreference(preference);
@@ -93,7 +103,20 @@ public class UserPreferencesImpl impleme
     }
 
     @Override
-    public void updateOrAppend(final Collection<Preference> preferences)
+    public ListenableFuture<Void> updateOrAppend(final Collection<Preference> 
preferences)
+    {
+        return _executor.submit(new PreferencesTask<Void>("updateOrAppend", 
preferences)
+        {
+            @Override
+            public Void doOperation()
+            {
+                doUpdateOrAppend(preferences);
+                return null;
+            }
+        });
+    }
+
+    private void doUpdateOrAppend(final Collection<Preference> preferences)
     {
         validateNewPreferencesForUpdate(preferences);
 
@@ -117,7 +140,19 @@ public class UserPreferencesImpl impleme
     }
 
     @Override
-    public Set<Preference> getPreferences()
+    public ListenableFuture<Set<Preference>> getPreferences()
+    {
+        return _executor.submit(new 
PreferencesTask<Set<Preference>>("getPreferences")
+        {
+            @Override
+            public Set<Preference> doOperation()
+            {
+                return doGetPreferences();
+            }
+        });
+    }
+
+    private Set<Preference> doGetPreferences()
     {
         Principal currentPrincipal = getMainPrincipalOrThrow();
 
@@ -133,13 +168,34 @@ public class UserPreferencesImpl impleme
     }
 
     @Override
-    public void replace(final Collection<Preference> preferences)
+    public ListenableFuture<Void> replace(final Collection<Preference> 
preferences)
     {
-        replaceByType(null, preferences);
+        return _executor.submit(new PreferencesTask<Void>("replace", 
preferences)
+        {
+            @Override
+            public Void doOperation()
+            {
+                doReplaceByType(null, preferences);
+                return null;
+            }
+        });
     }
 
     @Override
-    public void replaceByType(final String type, final Collection<Preference> 
preferences)
+    public ListenableFuture<Void> replaceByType(final String type, final 
Collection<Preference> preferences)
+    {
+        return _executor.submit(new PreferencesTask<Void>("replaceByType", 
type, preferences)
+        {
+            @Override
+            public Void doOperation()
+            {
+                doReplaceByType(type, preferences);
+                return null;
+            }
+        });
+    }
+
+    private void doReplaceByType(final String type, final 
Collection<Preference> preferences)
     {
         Principal currentPrincipal = getMainPrincipalOrThrow();
 
@@ -170,12 +226,27 @@ public class UserPreferencesImpl impleme
 
         for (Preference preference : preferences)
         {
-           addPreference(preference);
+            addPreference(preference);
         }
     }
 
     @Override
-    public void replaceByTypeAndName(final String type, final String name, 
final Preference newPreference)
+    public ListenableFuture<Void> replaceByTypeAndName(final String type,
+                                                       final String name,
+                                                       final Preference 
newPreference)
+    {
+        return _executor.submit(new 
PreferencesTask<Void>("replaceByTypeAndName", type, name, newPreference)
+        {
+            @Override
+            public Void doOperation()
+            {
+                doReplaceByTypeAndName(type, name, newPreference);
+                return null;
+            }
+        });
+    }
+
+    private void doReplaceByTypeAndName(final String type, final String name, 
final Preference newPreference)
     {
         Principal currentPrincipal = getMainPrincipalOrThrow();
 
@@ -204,7 +275,6 @@ public class UserPreferencesImpl impleme
                                          ? 
Collections.<PreferenceRecord>emptyList()
                                          : 
Collections.singleton(PreferenceRecordImpl.fromPreference(newPreference)));
 
-
         if (existingPreferenceId != null)
         {
             _preferences.remove(existingPreferenceId);
@@ -218,7 +288,69 @@ public class UserPreferencesImpl impleme
     }
 
     @Override
-    public Set<Preference> getVisiblePreferences()
+    public ListenableFuture<Void> delete(final String type, final String name, 
final UUID id)
+    {
+        return _executor.submit(new PreferencesTask<Void>("delete", type, 
name, id)
+        {
+            @Override
+            public Void doOperation()
+            {
+                doDelete(type, name, id);
+                return null;
+            }
+        });
+    }
+
+    private void doDelete(final String type, final String name, final UUID id)
+    {
+        if (type == null && name != null)
+        {
+            throw new IllegalArgumentException("Cannot specify name without 
specifying type");
+        }
+
+        if (id != null)
+        {
+            final Set<Preference> allPreferences = doGetPreferences();
+            for (Preference preference : allPreferences)
+            {
+                if (id.equals(preference.getId()))
+                {
+                    if ((type == null || type.equals(preference.getType()))
+                        && (name == null || name.equals(preference.getName())))
+                    {
+                        doReplaceByTypeAndName(preference.getType(), 
preference.getName(), null);
+                    }
+                    break;
+                }
+            }
+        }
+        else
+        {
+            if (type != null && name != null)
+            {
+                doReplaceByTypeAndName(type, name, null);
+            }
+            else
+            {
+                doReplaceByType(type, Collections.<Preference>emptySet());
+            }
+        }
+    }
+
+    @Override
+    public ListenableFuture<Set<Preference>> getVisiblePreferences()
+    {
+        return _executor.submit(new 
PreferencesTask<Set<Preference>>("getVisiblePreferences")
+        {
+            @Override
+            public Set<Preference> doOperation()
+            {
+                return doGetVisiblePreferences();
+            }
+        });
+    }
+
+    private Set<Preference> doGetVisiblePreferences()
     {
         Set<Principal> currentPrincipals = getPrincipalsOrThrow();
 
@@ -431,4 +563,57 @@ public class UserPreferencesImpl impleme
         }
         return false;
     }
+
+    private abstract class PreferencesTask<T> implements Task<T, 
RuntimeException>
+    {
+        private final Subject _subject;
+        private final String _action;
+        private final Object[] _arguments;
+        private String _argumentString;
+
+
+        private PreferencesTask(final String action, final Object... arguments)
+        {
+            _action = action;
+            _arguments = arguments;
+            _subject = Subject.getSubject(AccessController.getContext());
+        }
+
+        @Override
+        public T execute() throws RuntimeException
+        {
+            return Subject.doAs(_subject, new PrivilegedAction<T>()
+            {
+                @Override
+                public T run()
+                {
+                    return doOperation();
+                }
+            });
+        }
+
+        protected abstract T doOperation();
+
+        @Override
+        public String getObject()
+        {
+            return _associatedObject.getName();
+        }
+
+        @Override
+        public String getAction()
+        {
+            return _action;
+        }
+
+        @Override
+        public String getArguments()
+        {
+            if (_argumentString == null && _arguments != null)
+            {
+                _argumentString = _arguments.length == 1 ? 
String.valueOf(_arguments[0]) : Arrays.toString(_arguments);
+            }
+            return _argumentString;
+        }
+    }
 }

Modified: 
qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/store/preferences/PreferencesRecoverer.java
URL: 
http://svn.apache.org/viewvc/qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/store/preferences/PreferencesRecoverer.java?rev=1753191&r1=1753190&r2=1753191&view=diff
==============================================================================
--- 
qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/store/preferences/PreferencesRecoverer.java
 (original)
+++ 
qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/store/preferences/PreferencesRecoverer.java
 Mon Jul 18 10:02:25 2016
@@ -31,6 +31,7 @@ import java.util.UUID;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import org.apache.qpid.server.configuration.updater.TaskExecutor;
 import org.apache.qpid.server.model.ConfiguredObject;
 import org.apache.qpid.server.model.preferences.Preference;
 import org.apache.qpid.server.model.preferences.PreferenceFactory;
@@ -39,6 +40,13 @@ import org.apache.qpid.server.model.pref
 public class PreferencesRecoverer
 {
     private static final Logger LOGGER = 
LoggerFactory.getLogger(PreferencesRecoverer.class);
+    private TaskExecutor _executor;
+
+    public PreferencesRecoverer(final TaskExecutor executor)
+    {
+        _executor = executor;
+    }
+
 
     public void recoverPreferences(ConfiguredObject<?> parent,
                                    Collection<PreferenceRecord> 
preferenceRecords,
@@ -111,7 +119,10 @@ public class PreferencesRecoverer
                 }
             }
         }
-        associatedObject.setUserPreferences(new 
UserPreferencesImpl(preferenceStore, recoveredPreferences));
+        associatedObject.setUserPreferences(new UserPreferencesImpl(_executor,
+                                                                    
associatedObject,
+                                                                    
preferenceStore,
+                                                                    
recoveredPreferences));
 
         if (!(associatedObject instanceof PreferencesRoot))
         {

Added: 
qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/util/FutureHelper.java
URL: 
http://svn.apache.org/viewvc/qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/util/FutureHelper.java?rev=1753191&view=auto
==============================================================================
--- 
qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/util/FutureHelper.java
 (added)
+++ 
qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/util/FutureHelper.java
 Mon Jul 18 10:02:25 2016
@@ -0,0 +1,86 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.qpid.server.util;
+
+import java.util.concurrent.CancellationException;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.Future;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.TimeoutException;
+
+import org.apache.qpid.server.model.OperationTimeoutException;
+
+public class FutureHelper
+{
+    public static <T, E extends Exception> T await(Future<T> future, long 
timeout, TimeUnit timeUnit)
+            throws OperationTimeoutException, CancellationException, E
+    {
+        try
+        {
+            if (timeout > 0)
+            {
+                return future.get(timeout, timeUnit);
+            }
+            else
+            {
+                return future.get();
+            }
+        }
+        catch (InterruptedException e)
+        {
+            Thread.currentThread().interrupt();
+            throw new ServerScopedRuntimeException("Future execution was 
interrupted", e);
+        }
+        catch (ExecutionException e)
+        {
+            Throwable cause = e.getCause();
+            if (cause instanceof RuntimeException)
+            {
+                throw (RuntimeException) cause;
+            }
+            else if (cause instanceof Error)
+            {
+                throw (Error) cause;
+            }
+            else
+            {
+                try
+                {
+                    throw (E) cause;
+                }
+                catch (ClassCastException cce)
+                {
+                    throw new ServerScopedRuntimeException("Future failed", 
cause);
+                }
+            }
+        }
+        catch (TimeoutException e)
+        {
+            throw new OperationTimeoutException(e);
+        }
+    }
+
+    public static <T, E extends Exception> T await(Future<T> future)
+            throws OperationTimeoutException, CancellationException, E
+    {
+        return FutureHelper.<T, E>await(future, 0, null);
+    }
+
+}

Modified: 
qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/virtualhost/AbstractVirtualHost.java
URL: 
http://svn.apache.org/viewvc/qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/virtualhost/AbstractVirtualHost.java?rev=1753191&r1=1753190&r2=1753191&view=diff
==============================================================================
--- 
qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/virtualhost/AbstractVirtualHost.java
 (original)
+++ 
qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/virtualhost/AbstractVirtualHost.java
 Mon Jul 18 10:02:25 2016
@@ -60,6 +60,8 @@ import org.apache.qpid.pool.SuppressingI
 import org.apache.qpid.server.configuration.updater.Task;
 import org.apache.qpid.server.configuration.BrokerProperties;
 import org.apache.qpid.server.configuration.IllegalConfigurationException;
+import org.apache.qpid.server.configuration.updater.TaskExecutor;
+import org.apache.qpid.server.configuration.updater.TaskExecutorImpl;
 import org.apache.qpid.server.exchange.DefaultDestination;
 import org.apache.qpid.server.logging.EventLogger;
 import org.apache.qpid.server.logging.messages.MessageStoreMessages;
@@ -122,6 +124,7 @@ public abstract class AbstractVirtualHos
     private final AccessControlContext _housekeepingJobContext;
     private final AccessControlContext _fileSystemSpaceCheckerJobContext;
     private final AtomicBoolean _acceptsConnections = new AtomicBoolean(false);
+    private TaskExecutor _preferenceTaskExecutor;
 
     private static enum BlockingType { STORE, FILESYSTEM };
 
@@ -1076,6 +1079,7 @@ public abstract class AbstractVirtualHos
         _dtxRegistry.close();
         closeMessageStore();
         closePreferenceStore();
+        stopPreferenceTaskExecutor();
         shutdownHouseKeeping();
         closeNetworkConnectionScheduler();
         _eventLogger.message(VirtualHostMessages.CLOSED(getName()));
@@ -1657,13 +1661,22 @@ public abstract class AbstractVirtualHos
                 closeNetworkConnectionScheduler();
                 closeMessageStore();
                 closePreferenceStore();
+                stopPreferenceTaskExecutor();
                 setState(State.STOPPED);
-
                 stopLogging(loggers);
             }
         });
     }
 
+    private void stopPreferenceTaskExecutor()
+    {
+        TaskExecutor preferenceTaskExecutor = _preferenceTaskExecutor;
+        if (preferenceTaskExecutor != null)
+        {
+            preferenceTaskExecutor.stop();
+        }
+    }
+
     private void closePreferenceStore()
     {
         PreferenceStore ps = _preferenceStore;
@@ -2092,7 +2105,10 @@ public abstract class AbstractVirtualHos
         {
             final PreferenceStoreUpdater updater = new 
PreferenceStoreUpdaterImpl();
             Collection<PreferenceRecord> records = 
_preferenceStore.openAndLoad(updater);
-            new PreferencesRecoverer().recoverPreferences(this, records, 
_preferenceStore);
+            _preferenceTaskExecutor = new TaskExecutorImpl("virtualhost-" + 
getName() + "-preferences", null);
+            _preferenceTaskExecutor.start();
+            PreferencesRecoverer preferencesRecoverer = new 
PreferencesRecoverer(_preferenceTaskExecutor);
+            preferencesRecoverer.recoverPreferences(this, records, 
_preferenceStore);
 
             initialiseHouseKeeping(getHousekeepingCheckPeriod());
             finalState = State.ACTIVE;

Modified: 
qpid/java/trunk/broker-core/src/test/java/org/apache/qpid/server/configuration/updater/CurrentThreadTaskExecutor.java
URL: 
http://svn.apache.org/viewvc/qpid/java/trunk/broker-core/src/test/java/org/apache/qpid/server/configuration/updater/CurrentThreadTaskExecutor.java?rev=1753191&r1=1753190&r2=1753191&view=diff
==============================================================================
--- 
qpid/java/trunk/broker-core/src/test/java/org/apache/qpid/server/configuration/updater/CurrentThreadTaskExecutor.java
 (original)
+++ 
qpid/java/trunk/broker-core/src/test/java/org/apache/qpid/server/configuration/updater/CurrentThreadTaskExecutor.java
 Mon Jul 18 10:02:25 2016
@@ -21,12 +21,11 @@
 package org.apache.qpid.server.configuration.updater;
 
 import java.util.concurrent.CancellationException;
-import java.util.concurrent.ExecutionException;
-import java.util.concurrent.Future;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.TimeoutException;
 import java.util.concurrent.atomic.AtomicReference;
 
+import com.google.common.util.concurrent.Futures;
+import com.google.common.util.concurrent.ListenableFuture;
+
 public class CurrentThreadTaskExecutor implements TaskExecutor
 {
     private final AtomicReference<Thread> _thread = new AtomicReference<>();
@@ -78,42 +77,11 @@ public class CurrentThreadTaskExecutor i
     }
 
     @Override
-    public <T, E extends Exception> Future<T> submit(Task<T, E> task) throws 
CancellationException, E
+    public <T, E extends Exception> ListenableFuture<T> submit(Task<T, E> 
task) throws CancellationException, E
     {
         checkThread();
         final T result = task.execute();
-        return new Future<T>()
-        {
-            @Override
-            public boolean cancel(boolean mayInterruptIfRunning)
-            {
-                return true;
-            }
-
-            @Override
-            public boolean isCancelled()
-            {
-                return false;
-            }
-
-            @Override
-            public boolean isDone()
-            {
-                return true;
-            }
-
-            @Override
-            public T get() throws InterruptedException, ExecutionException
-            {
-                return result;
-            }
-
-            @Override
-            public T get(long timeout, TimeUnit unit) throws 
InterruptedException, ExecutionException, TimeoutException
-            {
-                return result;
-            }
-        };
+        return Futures.immediateFuture(result);
     }
 
     public static TaskExecutor newStartedInstance()

Modified: 
qpid/java/trunk/broker-core/src/test/java/org/apache/qpid/server/model/preferences/PreferenceTestHelper.java
URL: 
http://svn.apache.org/viewvc/qpid/java/trunk/broker-core/src/test/java/org/apache/qpid/server/model/preferences/PreferenceTestHelper.java?rev=1753191&r1=1753190&r2=1753191&view=diff
==============================================================================
--- 
qpid/java/trunk/broker-core/src/test/java/org/apache/qpid/server/model/preferences/PreferenceTestHelper.java
 (original)
+++ 
qpid/java/trunk/broker-core/src/test/java/org/apache/qpid/server/model/preferences/PreferenceTestHelper.java
 Mon Jul 18 10:02:25 2016
@@ -27,8 +27,10 @@ import java.util.HashMap;
 import java.util.Map;
 import java.util.Set;
 import java.util.UUID;
+import java.util.concurrent.Future;
 
 import org.apache.qpid.server.store.preferences.PreferenceRecord;
+import org.apache.qpid.server.util.FutureHelper;
 
 public class PreferenceTestHelper
 {
@@ -79,4 +81,10 @@ public class PreferenceTestHelper
                          new HashMap<>(actualRecord.getAttributes()));
         }
     }
+
+    public static <T> T awaitPreferenceFuture(final Future<T> future)
+    {
+        return FutureHelper.<T, RuntimeException>await(future);
+    }
+
 }

Modified: 
qpid/java/trunk/broker-core/src/test/java/org/apache/qpid/server/model/preferences/UserPreferencesTest.java
URL: 
http://svn.apache.org/viewvc/qpid/java/trunk/broker-core/src/test/java/org/apache/qpid/server/model/preferences/UserPreferencesTest.java?rev=1753191&r1=1753190&r2=1753191&view=diff
==============================================================================
--- 
qpid/java/trunk/broker-core/src/test/java/org/apache/qpid/server/model/preferences/UserPreferencesTest.java
 (original)
+++ 
qpid/java/trunk/broker-core/src/test/java/org/apache/qpid/server/model/preferences/UserPreferencesTest.java
 Mon Jul 18 10:02:25 2016
@@ -18,6 +18,7 @@
  */
 package org.apache.qpid.server.model.preferences;
 
+import static 
org.apache.qpid.server.model.preferences.PreferenceTestHelper.awaitPreferenceFuture;
 import static org.mockito.Matchers.argThat;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.verify;
@@ -37,6 +38,8 @@ import com.google.common.collect.Sets;
 import org.hamcrest.Description;
 import org.mockito.ArgumentMatcher;
 
+import org.apache.qpid.server.configuration.updater.CurrentThreadTaskExecutor;
+import org.apache.qpid.server.configuration.updater.TaskExecutor;
 import org.apache.qpid.server.model.ConfiguredObject;
 import org.apache.qpid.server.security.auth.AuthenticatedPrincipal;
 import org.apache.qpid.server.security.group.GroupPrincipal;
@@ -57,6 +60,7 @@ public class UserPreferencesTest extends
     private PreferenceStore _preferenceStore;
     private UUID _testId;
     private AuthenticatedPrincipal _owner;
+    private TaskExecutor _preferenceTaskExecutor;
 
     @Override
     public void setUp() throws Exception
@@ -64,7 +68,12 @@ public class UserPreferencesTest extends
         super.setUp();
         _configuredObject = mock(ConfiguredObject.class);
         _preferenceStore = mock(PreferenceStore.class);
-        _userPreferences = new UserPreferencesImpl(_preferenceStore, 
Collections.<Preference>emptyList());
+        _preferenceTaskExecutor = new CurrentThreadTaskExecutor();
+        _preferenceTaskExecutor.start();
+        _userPreferences = new UserPreferencesImpl(_preferenceTaskExecutor,
+                                                   _configuredObject,
+                                                   _preferenceStore,
+                                                   
Collections.<Preference>emptyList());
         _groupPrincipal = new GroupPrincipal(MYGROUP);
         _owner = new AuthenticatedPrincipal(MYUSER);
         _subject = new Subject(true,
@@ -74,6 +83,12 @@ public class UserPreferencesTest extends
         _testId = UUID.randomUUID();
     }
 
+    @Override
+    public void tearDown() throws Exception
+    {
+        _preferenceTaskExecutor.stop();
+        super.tearDown();
+    }
 
     public void testUpdateOrAppend() throws Exception
     {
@@ -87,7 +102,7 @@ public class UserPreferencesTest extends
             @Override
             public Void run()
             {
-                
_userPreferences.updateOrAppend(Collections.singleton(preference));
+                
awaitPreferenceFuture(_userPreferences.updateOrAppend(Collections.singleton(preference)));
                 return null;
             }
         });
@@ -108,7 +123,7 @@ public class UserPreferencesTest extends
             @Override
             public Void run()
             {
-                _userPreferences.replace(Collections.singleton(preference));
+                
awaitPreferenceFuture(_userPreferences.replace(Collections.singleton(preference)));
                 return null;
             }
         });
@@ -136,8 +151,8 @@ public class UserPreferencesTest extends
             @Override
             public Void run()
             {
-                _userPreferences.updateOrAppend(Arrays.asList(queryPreference, 
dashboardPreference));
-                _userPreferences.replaceByType("query", 
Collections.singletonList(newQueryPreference));
+                
awaitPreferenceFuture(_userPreferences.updateOrAppend(Arrays.asList(queryPreference,
 dashboardPreference)));
+                awaitPreferenceFuture(_userPreferences.replaceByType("query", 
Collections.singletonList(newQueryPreference)));
                 return null;
             }
         });
@@ -167,8 +182,8 @@ public class UserPreferencesTest extends
             @Override
             public Void run()
             {
-                
_userPreferences.updateOrAppend(Arrays.asList(queryPreference1, 
queryPreference2, dashboardPreference));
-                _userPreferences.replaceByTypeAndName("query", "test", 
newQueryPreference);
+                
awaitPreferenceFuture(_userPreferences.updateOrAppend(Arrays.asList(queryPreference1,
 queryPreference2, dashboardPreference)));
+                
awaitPreferenceFuture(_userPreferences.replaceByTypeAndName("query", "test", 
newQueryPreference));
                 return null;
             }
         });

Modified: 
qpid/java/trunk/broker-core/src/test/java/org/apache/qpid/server/model/testmodels/singleton/PreferencesTest.java
URL: 
http://svn.apache.org/viewvc/qpid/java/trunk/broker-core/src/test/java/org/apache/qpid/server/model/testmodels/singleton/PreferencesTest.java?rev=1753191&r1=1753190&r2=1753191&view=diff
==============================================================================
--- 
qpid/java/trunk/broker-core/src/test/java/org/apache/qpid/server/model/testmodels/singleton/PreferencesTest.java
 (original)
+++ 
qpid/java/trunk/broker-core/src/test/java/org/apache/qpid/server/model/testmodels/singleton/PreferencesTest.java
 Mon Jul 18 10:02:25 2016
@@ -20,10 +20,12 @@
 
 package org.apache.qpid.server.model.testmodels.singleton;
 
+import static 
org.apache.qpid.server.model.preferences.PreferenceTestHelper.awaitPreferenceFuture;
 import static org.mockito.Mockito.mock;
 
 import java.security.Principal;
 import java.security.PrivilegedAction;
+import java.util.Arrays;
 import java.util.Collection;
 import java.util.Collections;
 import java.util.Date;
@@ -35,6 +37,8 @@ import java.util.UUID;
 
 import javax.security.auth.Subject;
 
+import org.apache.qpid.server.configuration.updater.CurrentThreadTaskExecutor;
+import org.apache.qpid.server.configuration.updater.TaskExecutor;
 import org.apache.qpid.server.model.ConfiguredObject;
 import org.apache.qpid.server.model.Model;
 import org.apache.qpid.server.model.preferences.Preference;
@@ -52,6 +56,8 @@ public class PreferencesTest extends Qpi
     private final Model _model = TestModel.getInstance();
     private ConfiguredObject<?> _testObject;
     private Subject _testSubject;
+    private TaskExecutor _preferenceTaskExecutor;
+    private PreferenceStore _preferenceStore;
 
     @Override
     public void setUp() throws Exception
@@ -61,12 +67,23 @@ public class PreferencesTest extends Qpi
         _testObject = _model.getObjectFactory()
                             .create(TestSingleton.class,
                                     Collections.<String, 
Object>singletonMap(ConfiguredObject.NAME, objectName));
+
+        _preferenceTaskExecutor = new CurrentThreadTaskExecutor();
+        _preferenceTaskExecutor.start();
+        _preferenceStore = mock(PreferenceStore.class);
         _testObject.setUserPreferences(new UserPreferencesImpl(
-                mock(PreferenceStore.class), Collections.<Preference>emptySet()
+                _preferenceTaskExecutor, _testObject, _preferenceStore, 
Collections.<Preference>emptySet()
         ));
         _testSubject = TestPrincipalUtils.createTestSubject(TEST_USERNAME);
     }
 
+    @Override
+    public void tearDown() throws Exception
+    {
+        _preferenceTaskExecutor.stop();
+        super.tearDown();
+    }
+
     public void testSimpleRoundTrip()
     {
         final Preference p = PreferenceFactory.recover(_testObject, 
PreferenceTestHelper.createPreferenceAttributes(
@@ -84,8 +101,8 @@ public class PreferencesTest extends Qpi
             public Void run()
             {
                 Set<Preference> preferences = Collections.singleton(p);
-                _testObject.getUserPreferences().updateOrAppend(preferences);
-                assertEquals("roundtrip failed", preferences, 
_testObject.getUserPreferences().getPreferences());
+                
awaitPreferenceFuture(_testObject.getUserPreferences().updateOrAppend(preferences));
+                assertEquals("roundtrip failed", preferences, 
awaitPreferenceFuture(_testObject.getUserPreferences().getPreferences()));
                 return null;
             }
         });
@@ -111,7 +128,7 @@ public class PreferencesTest extends Qpi
                 Set<Preference> preferences = Collections.singleton(p);
                 try
                 {
-                    
_testObject.getUserPreferences().updateOrAppend(preferences);
+                    
awaitPreferenceFuture(_testObject.getUserPreferences().updateOrAppend(preferences));
                     fail("Saving of preferences owned by somebody else should 
not be allowed");
                 }
                 catch (SecurityException e)
@@ -155,8 +172,8 @@ public class PreferencesTest extends Qpi
             public Void run()
             {
                 Set<Preference> preferences = 
Collections.singleton(testUser2Preference);
-                
_testObject.getUserPreferences().updateOrAppend(Collections.singleton(testUser2Preference));
-                Set<Preference> p2s = 
_testObject.getUserPreferences().getPreferences();
+                
awaitPreferenceFuture(_testObject.getUserPreferences().updateOrAppend(Collections.singleton(testUser2Preference)));
+                Set<Preference> p2s = 
awaitPreferenceFuture(_testObject.getUserPreferences().getPreferences());
                 assertEquals("Unexpected preferences for subject 2", 
preferences, p2s);
                 return null;
             }
@@ -191,10 +208,10 @@ public class PreferencesTest extends Qpi
             @Override
             public Void run()
             {
-                
_testObject.getUserPreferences().updateOrAppend(Collections.singleton(p1));
-                
_testObject.getUserPreferences().updateOrAppend(Collections.singleton(p2));
+                
awaitPreferenceFuture(_testObject.getUserPreferences().updateOrAppend(Collections.singleton(p1)));
+                
awaitPreferenceFuture(_testObject.getUserPreferences().updateOrAppend(Collections.singleton(p2)));
 
-                Set<Preference> preferences = 
_testObject.getUserPreferences().getPreferences();
+                Set<Preference> preferences = 
awaitPreferenceFuture(_testObject.getUserPreferences().getPreferences());
                 assertEquals("Unexpected number of preferences", 1, 
preferences.size());
                 Preference newPreference = preferences.iterator().next();
                 assertEquals("Unexpected preference id", p2.getId(), 
newPreference.getId());
@@ -231,10 +248,10 @@ public class PreferencesTest extends Qpi
             @Override
             public Void run()
             {
-                
_testObject.getUserPreferences().updateOrAppend(Collections.singleton(p1));
+                
awaitPreferenceFuture(_testObject.getUserPreferences().updateOrAppend(Collections.singleton(p1)));
                 try
                 {
-                    
_testObject.getUserPreferences().updateOrAppend(Collections.singleton(p2));
+                    
awaitPreferenceFuture(_testObject.getUserPreferences().updateOrAppend(Collections.singleton(p2)));
                     fail("Type change should not be allowed");
                 }
                 catch (IllegalArgumentException e)
@@ -272,11 +289,11 @@ public class PreferencesTest extends Qpi
             @Override
             public Void run()
             {
-                
_testObject.getUserPreferences().updateOrAppend(Collections.singleton(p1));
+                
awaitPreferenceFuture(_testObject.getUserPreferences().updateOrAppend(Collections.singleton(p1)));
 
                 try
                 {
-                    
_testObject.getUserPreferences().updateOrAppend(Collections.singleton(p2));
+                    
awaitPreferenceFuture(_testObject.getUserPreferences().updateOrAppend(Collections.singleton(p2)));
                     fail("Property with same name and same type should not be 
allowed");
                 }
                 catch (IllegalArgumentException e)
@@ -318,7 +335,7 @@ public class PreferencesTest extends Qpi
                 preferences.add(p2);
                 try
                 {
-                    
_testObject.getUserPreferences().updateOrAppend(preferences);
+                    
awaitPreferenceFuture(_testObject.getUserPreferences().updateOrAppend(preferences));
                     fail("Property with same name and same type should not be 
allowed");
                 }
                 catch (IllegalArgumentException e)
@@ -371,10 +388,11 @@ public class PreferencesTest extends Qpi
             @Override
             public Void run()
             {
-                
_testObject.getUserPreferences().updateOrAppend(Collections.singleton(p1));
-                
_testObject.getUserPreferences().replace(Collections.singleton(p2));
+                
awaitPreferenceFuture(_testObject.getUserPreferences().updateOrAppend(Collections.singleton(p1)));
+                
awaitPreferenceFuture(_testObject.getUserPreferences().replace(Collections.singleton(p2)));
 
-                Collection<Preference> retrievedPreferences = 
_testObject.getUserPreferences().getPreferences();
+                Collection<Preference> retrievedPreferences =
+                        
awaitPreferenceFuture(_testObject.getUserPreferences().getPreferences());
                 assertEquals("Unexpected number of preferences", 1, 
retrievedPreferences.size());
                 assertEquals("Unexpected preference", p2, 
retrievedPreferences.iterator().next());
 
@@ -385,7 +403,331 @@ public class PreferencesTest extends Qpi
         assertSinglePreference(testSubject2, unaffectedPreference);
     }
 
-    public void testDelete()
+    public void testDeleteAll() throws Exception
+    {
+        final Preference p1 = PreferenceFactory.recover(_testObject, 
PreferenceTestHelper.createPreferenceAttributes(
+                null,
+                null,
+                "X-type-1",
+                "propName",
+                null,
+                TEST_USERNAME,
+                null,
+                Collections.<String, Object>emptyMap()));
+        final Preference p2 = PreferenceFactory.recover(_testObject, 
PreferenceTestHelper.createPreferenceAttributes(
+                null,
+                null,
+                "X-type-2",
+                "propName",
+                null,
+                TEST_USERNAME,
+                null,
+                Collections.<String, Object>emptyMap()));
+        updateOrAppendAs(_testSubject, p1, p2);
+
+        Subject.doAs(_testSubject, new PrivilegedAction<Void>()
+        {
+            @Override
+            public Void run()
+            {
+                
awaitPreferenceFuture(_testObject.getUserPreferences().delete(null, null, 
null));
+                Set<Preference> result = 
awaitPreferenceFuture(_testObject.getUserPreferences().getPreferences());
+                assertEquals("Unexpected number of preferences", 0, 
result.size());
+                return null;
+            }
+        });
+    }
+
+    public void testDeleteByType() throws Exception
+    {
+        final String deleteType = "X-type-1";
+        final Preference deletePreference =
+                PreferenceFactory.recover(_testObject, 
PreferenceTestHelper.createPreferenceAttributes(
+                        null,
+                        null,
+                        deleteType,
+                        "propName",
+                        null,
+                        TEST_USERNAME,
+                        null,
+                        Collections.<String, Object>emptyMap()));
+        String unaffectedType = "X-type-2";
+        final Preference unaffectedPreference =
+                PreferenceFactory.recover(_testObject, 
PreferenceTestHelper.createPreferenceAttributes(
+                        null,
+                        null,
+                        unaffectedType,
+                        "propName",
+                        null,
+                        TEST_USERNAME,
+                        null,
+                        Collections.<String, Object>emptyMap()));
+        updateOrAppendAs(_testSubject, deletePreference, unaffectedPreference);
+
+        Subject.doAs(_testSubject, new PrivilegedAction<Void>()
+        {
+            @Override
+            public Void run()
+            {
+                
awaitPreferenceFuture(_testObject.getUserPreferences().delete(deleteType, null, 
null));
+                Set<Preference> result = 
awaitPreferenceFuture(_testObject.getUserPreferences().getPreferences());
+                assertEquals("Unexpected number of preferences", 1, 
result.size());
+                assertEquals("Unexpected preference Id",
+                             unaffectedPreference.getId(),
+                             result.iterator().next().getId());
+                return null;
+            }
+        });
+    }
+
+    public void testDeleteByTypeAndName() throws Exception
+    {
+        final String deleteType = "X-type-1";
+        final String deletePropertyName = "propName";
+        final Preference deletePreference =
+                PreferenceFactory.recover(_testObject, 
PreferenceTestHelper.createPreferenceAttributes(
+                        null,
+                        null,
+                        deleteType,
+                        deletePropertyName,
+                        null,
+                        TEST_USERNAME,
+                        null,
+                        Collections.<String, Object>emptyMap()));
+        final Preference unaffectedPreference1 =
+                PreferenceFactory.recover(_testObject, 
PreferenceTestHelper.createPreferenceAttributes(
+                        null,
+                        null,
+                        deleteType,
+                        "propName2",
+                        null,
+                        TEST_USERNAME,
+                        null,
+                        Collections.<String, Object>emptyMap()));
+        String unaffectedType = "X-type-2";
+        final Preference unaffectedPreference2 =
+                PreferenceFactory.recover(_testObject, 
PreferenceTestHelper.createPreferenceAttributes(
+                        null,
+                        null,
+                        unaffectedType,
+                        deletePropertyName,
+                        null,
+                        TEST_USERNAME,
+                        null,
+                        Collections.<String, Object>emptyMap()));
+        updateOrAppendAs(_testSubject, deletePreference, 
unaffectedPreference1, unaffectedPreference2);
+
+        Subject.doAs(_testSubject, new PrivilegedAction<Void>()
+        {
+            @Override
+            public Void run()
+            {
+                
awaitPreferenceFuture(_testObject.getUserPreferences().delete(deleteType, 
deletePropertyName, null));
+                Set<Preference> result = 
awaitPreferenceFuture(_testObject.getUserPreferences().getPreferences());
+                assertEquals("Unexpected number of preferences", 2, 
result.size());
+                Set<UUID> ids = new HashSet<>(result.size());
+                for (Preference p : result)
+                {
+                    ids.add(p.getId());
+                }
+                assertTrue(String.format("unaffectedPreference1 unexpectedly 
deleted"), ids.contains(unaffectedPreference1.getId()));
+                assertTrue(String.format("unaffectedPreference2 unexpectedly 
deleted"), ids.contains(unaffectedPreference2.getId()));
+                return null;
+            }
+        });
+    }
+
+    public void testDeleteById() throws Exception
+    {
+        final String deleteType = "X-type-1";
+        final Preference deletePreference =
+                PreferenceFactory.recover(_testObject, 
PreferenceTestHelper.createPreferenceAttributes(
+                        null,
+                        null,
+                        deleteType,
+                        "propName",
+                        null,
+                        TEST_USERNAME,
+                        null,
+                        Collections.<String, Object>emptyMap()));
+        final Preference unaffectedPreference1 =
+                PreferenceFactory.recover(_testObject, 
PreferenceTestHelper.createPreferenceAttributes(
+                        null,
+                        null,
+                        deleteType,
+                        "propName2",
+                        null,
+                        TEST_USERNAME,
+                        null,
+                        Collections.<String, Object>emptyMap()));
+        String unaffectedType = "X-type-2";
+        final Preference unaffectedPreference2 =
+                PreferenceFactory.recover(_testObject, 
PreferenceTestHelper.createPreferenceAttributes(
+                        null,
+                        null,
+                        unaffectedType,
+                        "propName",
+                        null,
+                        TEST_USERNAME,
+                        null,
+                        Collections.<String, Object>emptyMap()));
+        updateOrAppendAs(_testSubject, deletePreference, 
unaffectedPreference1, unaffectedPreference2);
+
+        Subject.doAs(_testSubject, new PrivilegedAction<Void>()
+        {
+            @Override
+            public Void run()
+            {
+                
awaitPreferenceFuture(_testObject.getUserPreferences().delete(null, null, 
deletePreference.getId()));
+                Set<Preference> result = 
awaitPreferenceFuture(_testObject.getUserPreferences().getPreferences());
+                assertEquals("Unexpected number of preferences", 2, 
result.size());
+                Set<UUID> ids = new HashSet<>(result.size());
+                for (Preference p : result)
+                {
+                    ids.add(p.getId());
+                }
+                assertTrue(String.format("unaffectedPreference1 unexpectedly 
deleted"), ids.contains(unaffectedPreference1.getId()));
+                assertTrue(String.format("unaffectedPreference2 unexpectedly 
deleted"), ids.contains(unaffectedPreference2.getId()));
+                return null;
+            }
+        });
+    }
+
+    public void testDeleteByTypeAndId() throws Exception
+    {
+        final String deleteType = "X-type-1";
+        final Preference deletePreference =
+                PreferenceFactory.recover(_testObject, 
PreferenceTestHelper.createPreferenceAttributes(
+                        null,
+                        null,
+                        deleteType,
+                        "propName",
+                        null,
+                        TEST_USERNAME,
+                        null,
+                        Collections.<String, Object>emptyMap()));
+        final Preference unaffectedPreference1 =
+                PreferenceFactory.recover(_testObject, 
PreferenceTestHelper.createPreferenceAttributes(
+                        null,
+                        null,
+                        deleteType,
+                        "propName2",
+                        null,
+                        TEST_USERNAME,
+                        null,
+                        Collections.<String, Object>emptyMap()));
+        String unaffectedType = "X-type-2";
+        final Preference unaffectedPreference2 =
+                PreferenceFactory.recover(_testObject, 
PreferenceTestHelper.createPreferenceAttributes(
+                        null,
+                        null,
+                        unaffectedType,
+                        "propName",
+                        null,
+                        TEST_USERNAME,
+                        null,
+                        Collections.<String, Object>emptyMap()));
+        updateOrAppendAs(_testSubject, deletePreference, 
unaffectedPreference1, unaffectedPreference2);
+
+        Subject.doAs(_testSubject, new PrivilegedAction<Void>()
+        {
+            @Override
+            public Void run()
+            {
+                
awaitPreferenceFuture(_testObject.getUserPreferences().delete(deleteType, null, 
deletePreference.getId()));
+                Set<Preference> result = 
awaitPreferenceFuture(_testObject.getUserPreferences().getPreferences());
+                assertEquals("Unexpected number of preferences", 2, 
result.size());
+                Set<UUID> ids = new HashSet<>(result.size());
+                for (Preference p : result)
+                {
+                    ids.add(p.getId());
+                }
+                assertTrue(String.format("unaffectedPreference1 unexpectedly 
deleted"), ids.contains(unaffectedPreference1.getId()));
+                assertTrue(String.format("unaffectedPreference2 unexpectedly 
deleted"), ids.contains(unaffectedPreference2.getId()));
+                return null;
+            }
+        });
+    }
+
+    public void testDeleteByTypeAndNameAndId() throws Exception
+    {
+        final String deleteType = "X-type-1";
+        final String deletePropertyName = "propName";
+        final Preference deletePreference =
+                PreferenceFactory.recover(_testObject, 
PreferenceTestHelper.createPreferenceAttributes(
+                        null,
+                        null,
+                        deleteType,
+                        deletePropertyName,
+                        null,
+                        TEST_USERNAME,
+                        null,
+                        Collections.<String, Object>emptyMap()));
+        final Preference unaffectedPreference1 =
+                PreferenceFactory.recover(_testObject, 
PreferenceTestHelper.createPreferenceAttributes(
+                        null,
+                        null,
+                        deleteType,
+                        "propName2",
+                        null,
+                        TEST_USERNAME,
+                        null,
+                        Collections.<String, Object>emptyMap()));
+        String unaffectedType = "X-type-2";
+        final Preference unaffectedPreference2 =
+                PreferenceFactory.recover(_testObject, 
PreferenceTestHelper.createPreferenceAttributes(
+                        null,
+                        null,
+                        unaffectedType,
+                        deletePropertyName,
+                        null,
+                        TEST_USERNAME,
+                        null,
+                        Collections.<String, Object>emptyMap()));
+        updateOrAppendAs(_testSubject, deletePreference, 
unaffectedPreference1, unaffectedPreference2);
+
+        Subject.doAs(_testSubject, new PrivilegedAction<Void>()
+        {
+            @Override
+            public Void run()
+            {
+                
awaitPreferenceFuture(_testObject.getUserPreferences().delete(deleteType, 
deletePropertyName, deletePreference.getId()));
+                Set<Preference> result = 
awaitPreferenceFuture(_testObject.getUserPreferences().getPreferences());
+                assertEquals("Unexpected number of preferences", 2, 
result.size());
+                Set<UUID> ids = new HashSet<>(result.size());
+                for (Preference p : result)
+                {
+                    ids.add(p.getId());
+                }
+                assertTrue(String.format("unaffectedPreference1 unexpectedly 
deleted"), ids.contains(unaffectedPreference1.getId()));
+                assertTrue(String.format("unaffectedPreference2 unexpectedly 
deleted"), ids.contains(unaffectedPreference2.getId()));
+                return null;
+            }
+        });
+    }
+
+    public void testDeleteByNameWithoutType() throws Exception
+    {
+        Subject.doAs(_testSubject, new PrivilegedAction<Void>()
+        {
+            @Override
+            public Void run()
+            {
+                try
+                {
+                    
awaitPreferenceFuture(_testObject.getUserPreferences().delete(null, "test", 
null));
+                    fail("delete by name without type should not be allowed");
+                }
+                catch (IllegalArgumentException e)
+                {
+                    // pass
+                }
+                return null;
+            }
+        });
+    }
+
+    public void testDeleteViaReplace()
     {
         final String preferenceType = "X-testType";
         Subject testSubject2 = 
TestPrincipalUtils.createTestSubject(TEST_USERNAME2);
@@ -416,10 +758,11 @@ public class PreferencesTest extends Qpi
             @Override
             public Void run()
             {
-                
_testObject.getUserPreferences().updateOrAppend(Collections.singleton(p1));
-                
_testObject.getUserPreferences().replace(Collections.<Preference>emptySet());
+                
awaitPreferenceFuture(_testObject.getUserPreferences().updateOrAppend(Collections.singleton(p1)));
+                
awaitPreferenceFuture(_testObject.getUserPreferences().replace(Collections.<Preference>emptySet()));
 
-                Collection<Preference> retrievedPreferences = 
_testObject.getUserPreferences().getPreferences();
+                Collection<Preference> retrievedPreferences =
+                        
awaitPreferenceFuture(_testObject.getUserPreferences().getPreferences());
                 assertEquals("Unexpected number of preferences", 0, 
retrievedPreferences.size());
 
                 return null;
@@ -429,7 +772,7 @@ public class PreferencesTest extends Qpi
         assertSinglePreference(testSubject2, unaffectedPreference);
     }
 
-    public void testDeleteByType()
+    public void testDeleteViaReplaceByType()
     {
         final String preferenceType = "X-testType";
         final String unaffectedPreferenceType = "X-unaffectedType";
@@ -474,11 +817,12 @@ public class PreferencesTest extends Qpi
                 Set<Preference> preferences = new HashSet<>();
                 preferences.add(p1);
                 preferences.add(p2);
-                _testObject.getUserPreferences().updateOrAppend(preferences);
+                
awaitPreferenceFuture(_testObject.getUserPreferences().updateOrAppend(preferences));
 
-                _testObject.getUserPreferences().replaceByType(preferenceType, 
Collections.<Preference>emptySet());
+                
awaitPreferenceFuture(_testObject.getUserPreferences().replaceByType(preferenceType,
 Collections.<Preference>emptySet()));
 
-                Collection<Preference> retrievedPreferences = 
_testObject.getUserPreferences().getPreferences();
+                Collection<Preference> retrievedPreferences =
+                        
awaitPreferenceFuture(_testObject.getUserPreferences().getPreferences());
                 assertEquals("Unexpected number of preferences", 1, 
retrievedPreferences.size());
                 assertTrue("Unexpected preference", 
retrievedPreferences.contains(p2));
                 return null;
@@ -488,7 +832,7 @@ public class PreferencesTest extends Qpi
         assertSinglePreference(testSubject2, unaffectedPreference);
     }
 
-    public void testDeleteByTypeAndName()
+    public void testDeleteViaReplaceByTypeAndName()
     {
         final String preferenceType = "X-testType";
         Subject testSubject2 = 
TestPrincipalUtils.createTestSubject(TEST_USERNAME2);
@@ -534,11 +878,12 @@ public class PreferencesTest extends Qpi
                 Set<Preference> preferences = new HashSet<>();
                 preferences.add(p1);
                 preferences.add(p2);
-                _testObject.getUserPreferences().updateOrAppend(preferences);
+                
awaitPreferenceFuture(_testObject.getUserPreferences().updateOrAppend(preferences));
 
-                
_testObject.getUserPreferences().replaceByTypeAndName(preferenceType, 
"propName", null);
+                
awaitPreferenceFuture(_testObject.getUserPreferences().replaceByTypeAndName(preferenceType,
 "propName", null));
 
-                Collection<Preference> retrievedPreferences = 
_testObject.getUserPreferences().getPreferences();
+                Collection<Preference> retrievedPreferences =
+                        
awaitPreferenceFuture(_testObject.getUserPreferences().getPreferences());
                 assertEquals("Unexpected number of preferences", 1, 
retrievedPreferences.size());
                 assertTrue("Unexpected preference", 
retrievedPreferences.contains(p2));
 
@@ -602,12 +947,13 @@ public class PreferencesTest extends Qpi
                 Set<Preference> preferences = new HashSet<>();
                 preferences.add(p1);
                 preferences.add(p2);
-                _testObject.getUserPreferences().updateOrAppend(preferences);
+                
awaitPreferenceFuture(_testObject.getUserPreferences().updateOrAppend(preferences));
 
                 preferences = Collections.singleton(p3);
-                _testObject.getUserPreferences().replaceByType(replaceType, 
preferences);
+                
awaitPreferenceFuture(_testObject.getUserPreferences().replaceByType(replaceType,
 preferences));
 
-                Set<Preference> retrievedPreferences = 
_testObject.getUserPreferences().getPreferences();
+                Set<Preference> retrievedPreferences =
+                        
awaitPreferenceFuture(_testObject.getUserPreferences().getPreferences());
                 assertEquals("Unexpected number of preferences", 2, 
retrievedPreferences.size());
                 assertTrue("Preference of different type was replaced", 
retrievedPreferences.contains(p2));
                 assertTrue("Preference was not replaced", 
retrievedPreferences.contains(p3));
@@ -684,11 +1030,12 @@ public class PreferencesTest extends Qpi
                 preferences.add(p1);
                 preferences.add(p1b);
                 preferences.add(p2);
-                _testObject.getUserPreferences().updateOrAppend(preferences);
+                
awaitPreferenceFuture(_testObject.getUserPreferences().updateOrAppend(preferences));
 
-                
_testObject.getUserPreferences().replaceByTypeAndName(replaceType, "propName", 
p3);
+                
awaitPreferenceFuture(_testObject.getUserPreferences().replaceByTypeAndName(replaceType,
 "propName", p3));
 
-                Set<Preference> retrievedPreferences = 
_testObject.getUserPreferences().getPreferences();
+                Set<Preference> retrievedPreferences =
+                        
awaitPreferenceFuture(_testObject.getUserPreferences().getPreferences());
                 assertEquals("Unexpected number of preferences", 3, 
retrievedPreferences.size());
                 assertTrue("Preference of different name was replaced", 
retrievedPreferences.contains(p1b));
                 assertTrue("Preference of different type was replaced", 
retrievedPreferences.contains(p2));
@@ -720,7 +1067,7 @@ public class PreferencesTest extends Qpi
             @Override
             public Void run()
             {
-                
_testObject.getUserPreferences().updateOrAppend(Collections.singleton(sharedPreference));
+                
awaitPreferenceFuture(_testObject.getUserPreferences().updateOrAppend(Collections.singleton(sharedPreference)));
                 return null;
             }
         });
@@ -741,7 +1088,7 @@ public class PreferencesTest extends Qpi
             @Override
             public Void run()
             {
-                
_testObject.getUserPreferences().updateOrAppend(Collections.singleton(notSharedPreference));
+                
awaitPreferenceFuture(_testObject.getUserPreferences().updateOrAppend(Collections.singleton(notSharedPreference)));
                 return null;
             }
         });
@@ -762,9 +1109,10 @@ public class PreferencesTest extends Qpi
             public Void run()
             {
 
-                
_testObject.getUserPreferences().updateOrAppend(Collections.singleton(p));
+                
awaitPreferenceFuture(_testObject.getUserPreferences().updateOrAppend(Collections.singleton(p)));
 
-                Set<Preference> retrievedPreferences = 
_testObject.getUserPreferences().getVisiblePreferences();
+                Set<Preference> retrievedPreferences =
+                        
awaitPreferenceFuture(_testObject.getUserPreferences().getVisiblePreferences());
                 assertEquals("Unexpected number of preferences", 2, 
retrievedPreferences.size());
                 assertTrue("Preference of my peer did not exist in visible 
set",
                            retrievedPreferences.contains(sharedPreference));
@@ -798,7 +1146,7 @@ public class PreferencesTest extends Qpi
             @Override
             public Void run()
             {
-                
_testObject.getUserPreferences().updateOrAppend(Collections.singleton(sharedPreference));
+                
awaitPreferenceFuture(_testObject.getUserPreferences().updateOrAppend(Collections.singleton(sharedPreference)));
                 return null;
             }
         });
@@ -819,9 +1167,10 @@ public class PreferencesTest extends Qpi
             @Override
             public Void run()
             {
-                
_testObject.getUserPreferences().updateOrAppend(Collections.singleton(testUserPreference));
+                
awaitPreferenceFuture(_testObject.getUserPreferences().updateOrAppend(Collections.singleton(testUserPreference)));
 
-                Set<Preference> retrievedPreferences = 
_testObject.getUserPreferences().getVisiblePreferences();
+                Set<Preference> retrievedPreferences =
+                        
awaitPreferenceFuture(_testObject.getUserPreferences().getVisiblePreferences());
                 assertEquals("Unexpected number of preferences", 2, 
retrievedPreferences.size());
                 assertTrue("Preference of my peer did not exist in visible 
set",
                            retrievedPreferences.contains(sharedPreference));
@@ -906,14 +1255,14 @@ public class PreferencesTest extends Qpi
         assertEquals("Unexpected preference attributes", expectedAttributes, 
p.getAttributes());
     }
 
-    private void updateOrAppendAs(final Subject testSubject, final Preference 
testUserPreference)
+    private void updateOrAppendAs(final Subject testSubject, final 
Preference... testUserPreference)
     {
         Subject.doAs(testSubject, new PrivilegedAction<Void>()
         {
             @Override
             public Void run()
             {
-                
_testObject.getUserPreferences().updateOrAppend(Collections.singleton(testUserPreference));
+                
awaitPreferenceFuture(_testObject.getUserPreferences().updateOrAppend(Arrays.asList(testUserPreference)));
                 return null;
             }
         });
@@ -926,7 +1275,8 @@ public class PreferencesTest extends Qpi
             @Override
             public Void run()
             {
-                Collection<Preference> retrievedPreferences = 
_testObject.getUserPreferences().getPreferences();
+                Collection<Preference> retrievedPreferences =
+                        
awaitPreferenceFuture(_testObject.getUserPreferences().getPreferences());
                 assertEquals("Unexpected number of preferences", 1, 
retrievedPreferences.size());
                 assertEquals("Unexpected preference", preference, 
retrievedPreferences.iterator().next());
                 return null;

Modified: 
qpid/java/trunk/broker-core/src/test/java/org/apache/qpid/server/store/preferences/PreferencesRecovererTest.java
URL: 
http://svn.apache.org/viewvc/qpid/java/trunk/broker-core/src/test/java/org/apache/qpid/server/store/preferences/PreferencesRecovererTest.java?rev=1753191&r1=1753190&r2=1753191&view=diff
==============================================================================
--- 
qpid/java/trunk/broker-core/src/test/java/org/apache/qpid/server/store/preferences/PreferencesRecovererTest.java
 (original)
+++ 
qpid/java/trunk/broker-core/src/test/java/org/apache/qpid/server/store/preferences/PreferencesRecovererTest.java
 Mon Jul 18 10:02:25 2016
@@ -19,6 +19,7 @@
 
 package org.apache.qpid.server.store.preferences;
 
+import static 
org.apache.qpid.server.model.preferences.PreferenceTestHelper.awaitPreferenceFuture;
 import static org.mockito.Mockito.mock;
 
 import java.security.PrivilegedAction;
@@ -30,6 +31,8 @@ import java.util.UUID;
 
 import javax.security.auth.Subject;
 
+import org.apache.qpid.server.configuration.updater.CurrentThreadTaskExecutor;
+import org.apache.qpid.server.configuration.updater.TaskExecutor;
 import org.apache.qpid.server.model.ConfiguredObject;
 import org.apache.qpid.server.model.Model;
 import org.apache.qpid.server.model.preferences.Preference;
@@ -48,6 +51,8 @@ public class PreferencesRecovererTest ex
     private TestCar _testObject;
     private ConfiguredObject<?> _testChildObject;
     private Subject _testSubject;
+    private TaskExecutor _preferenceTaskExecutor;
+    private PreferencesRecoverer _recoverer;
 
     @Override
     public void setUp() throws Exception
@@ -60,20 +65,27 @@ public class PreferencesRecovererTest ex
         _testChildObject = _testObject.createChild(TestEngine.class,
                                                    Collections.<String, 
Object>singletonMap(ConfiguredObject.NAME, getTestName()));
         _testSubject = TestPrincipalUtils.createTestSubject(TEST_USERNAME);
+        _preferenceTaskExecutor = new CurrentThreadTaskExecutor();
+        _preferenceTaskExecutor.start();
+        _recoverer = new PreferencesRecoverer(_preferenceTaskExecutor);
+    }
+
+    @Override
+    public void tearDown() throws Exception
+    {
+        _preferenceTaskExecutor.stop();
+        super.tearDown();
     }
 
     public void testRecoverEmptyPreferences() throws Exception
     {
-        PreferencesRecoverer recoverer = new PreferencesRecoverer();
-        recoverer.recoverPreferences(_testObject, 
Collections.<PreferenceRecord>emptyList(), _store);
+        _recoverer.recoverPreferences(_testObject, 
Collections.<PreferenceRecord>emptyList(), _store);
         assertNotNull("Object should have UserPreferences", 
_testObject.getUserPreferences());
         assertNotNull("Child object should have UserPreferences", 
_testChildObject.getUserPreferences());
     }
 
     public void testRecoverPreferences() throws Exception
     {
-        PreferencesRecoverer recoverer = new PreferencesRecoverer();
-
         final UUID p1Id = UUID.randomUUID();
         Map<String, Object> pref1Attributes = 
PreferenceTestHelper.createPreferenceAttributes(
                 _testObject.getId(),
@@ -96,17 +108,17 @@ public class PreferencesRecovererTest ex
                 null,
                 Collections.<String, Object>emptyMap());
         PreferenceRecord record2 = new PreferenceRecordImpl(p2Id, 
pref2Attributes);
-        recoverer.recoverPreferences(_testObject, Arrays.asList(record1, 
record2), _store);
+        _recoverer.recoverPreferences(_testObject, Arrays.asList(record1, 
record2), _store);
 
         Subject.doAs(_testSubject, new PrivilegedAction<Void>()
         {
             @Override
             public Void run()
             {
-                Set<Preference> preferences = 
_testObject.getUserPreferences().getPreferences();
+                Set<Preference> preferences = 
awaitPreferenceFuture(_testObject.getUserPreferences().getPreferences());
                 assertEquals("Unexpected number of preferences", 1, 
preferences.size());
 
-                Set<Preference> childPreferences = 
_testChildObject.getUserPreferences().getPreferences();
+                Set<Preference> childPreferences = 
awaitPreferenceFuture(_testChildObject.getUserPreferences().getPreferences());
                 assertEquals("Unexpected number of preferences", 1, 
childPreferences.size());
                 return null;
             }

Modified: 
qpid/java/trunk/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/HttpManagementConfiguration.java
URL: 
http://svn.apache.org/viewvc/qpid/java/trunk/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/HttpManagementConfiguration.java?rev=1753191&r1=1753190&r2=1753191&view=diff
==============================================================================
--- 
qpid/java/trunk/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/HttpManagementConfiguration.java
 (original)
+++ 
qpid/java/trunk/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/HttpManagementConfiguration.java
 Mon Jul 18 10:02:25 2016
@@ -73,6 +73,10 @@ public interface HttpManagementConfigura
     @ManagedContextDefault( name = MAX_HTTP_FILE_UPLOAD_SIZE_CONTEXT_NAME)
     static final long DEFAULT_MAX_UPLOAD_SIZE = 100 * 1024;
 
+    String PREFERENCE_OPERTAION_TIMEOUT_CONTEXT_NAME = 
"qpid.httpManagement.preferenceOperationTimeout";
+    @SuppressWarnings("unused")
+    @ManagedContextDefault( name = PREFERENCE_OPERTAION_TIMEOUT_CONTEXT_NAME)
+    long DEFAULT_PREFERENCE_OPERTAION_TIMEOUT = 10000L;
 
     AuthenticationProvider getAuthenticationProvider(HttpServletRequest 
request);
 }



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

Reply via email to