You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@brooklyn.apache.org by he...@apache.org on 2014/08/01 22:13:00 UTC

[5/8] git commit: Remove duplication in rebind code

Remove duplication in rebind code


Project: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/commit/cbb6e40c
Tree: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/tree/cbb6e40c
Diff: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/diff/cbb6e40c

Branch: refs/heads/master
Commit: cbb6e40c55fa7d2e1382fecbfff0d70ff7b4f79f
Parents: e07155a
Author: Aled Sage <al...@gmail.com>
Authored: Mon Jul 14 15:55:27 2014 +0100
Committer: Aled Sage <al...@gmail.com>
Committed: Mon Jul 14 23:45:19 2014 +0100

----------------------------------------------------------------------
 .../entity/rebind/BrooklynObjectType.java       |  30 +++
 .../rebind/PersistenceExceptionHandler.java     |  13 +-
 .../entity/rebind/RebindExceptionHandler.java   |  43 +---
 .../brooklyn/entity/basic/EntityFunctions.java  |   7 +-
 .../rebind/PeriodicDeltaChangeListener.java     |   8 +-
 .../rebind/PersistenceExceptionHandlerImpl.java |  29 +--
 .../rebind/RebindExceptionHandlerImpl.java      | 244 ++++---------------
 .../entity/rebind/RebindManagerImpl.java        |  36 ++-
 .../entity/rebind/dto/BrooklynMementoImpl.java  |  20 +-
 .../BrooklynMementoPersisterToFile.java         |   1 +
 .../BrooklynMementoPersisterToMultiFile.java    |  20 +-
 .../BrooklynMementoPersisterToObjectStore.java  |  97 +++-----
 .../entity/rebind/RebindFailuresTest.java       |  17 +-
 .../rebind/RecordingRebindExceptionHandler.java | 113 ++-------
 14 files changed, 210 insertions(+), 468 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/cbb6e40c/api/src/main/java/brooklyn/entity/rebind/BrooklynObjectType.java
----------------------------------------------------------------------
diff --git a/api/src/main/java/brooklyn/entity/rebind/BrooklynObjectType.java b/api/src/main/java/brooklyn/entity/rebind/BrooklynObjectType.java
new file mode 100644
index 0000000..a027867
--- /dev/null
+++ b/api/src/main/java/brooklyn/entity/rebind/BrooklynObjectType.java
@@ -0,0 +1,30 @@
+/*
+ * 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 brooklyn.entity.rebind;
+
+import com.google.common.annotations.Beta;
+
+@Beta
+public enum BrooklynObjectType {
+    ENTITY,
+    LOCATION,
+    POLICY,
+    ENRICHER,
+    UNKNOWN;
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/cbb6e40c/api/src/main/java/brooklyn/entity/rebind/PersistenceExceptionHandler.java
----------------------------------------------------------------------
diff --git a/api/src/main/java/brooklyn/entity/rebind/PersistenceExceptionHandler.java b/api/src/main/java/brooklyn/entity/rebind/PersistenceExceptionHandler.java
index 657d2b0..024cbb1 100644
--- a/api/src/main/java/brooklyn/entity/rebind/PersistenceExceptionHandler.java
+++ b/api/src/main/java/brooklyn/entity/rebind/PersistenceExceptionHandler.java
@@ -18,11 +18,8 @@
  */
 package brooklyn.entity.rebind;
 
-import brooklyn.entity.Entity;
-import brooklyn.location.Location;
+import brooklyn.entity.trait.Identifiable;
 import brooklyn.mementos.Memento;
-import brooklyn.policy.Enricher;
-import brooklyn.policy.Policy;
 
 import com.google.common.annotations.Beta;
 
@@ -36,14 +33,8 @@ public interface PersistenceExceptionHandler {
 
     void stop();
 
-    void onGenerateLocationMementoFailed(Location location, Exception e);
-
-    void onGenerateEntityMementoFailed(Entity entity, Exception e);
-    
-    void onGeneratePolicyMementoFailed(Policy policy, Exception e);
+    void onGenerateMementoFailed(BrooklynObjectType type, Identifiable instance, Exception e);
     
-    void onGenerateEnricherMementoFailed(Enricher enricher, Exception e);
-
     void onPersistMementoFailed(Memento memento, Exception e);
     
     void onDeleteMementoFailed(String id, Exception e);

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/cbb6e40c/api/src/main/java/brooklyn/entity/rebind/RebindExceptionHandler.java
----------------------------------------------------------------------
diff --git a/api/src/main/java/brooklyn/entity/rebind/RebindExceptionHandler.java b/api/src/main/java/brooklyn/entity/rebind/RebindExceptionHandler.java
index 7330bbf..4e5aa60 100644
--- a/api/src/main/java/brooklyn/entity/rebind/RebindExceptionHandler.java
+++ b/api/src/main/java/brooklyn/entity/rebind/RebindExceptionHandler.java
@@ -20,6 +20,7 @@ package brooklyn.entity.rebind;
 
 import brooklyn.entity.Entity;
 import brooklyn.entity.basic.EntityLocal;
+import brooklyn.entity.trait.Identifiable;
 import brooklyn.location.Location;
 import brooklyn.policy.Enricher;
 import brooklyn.policy.Policy;
@@ -34,15 +35,7 @@ import com.google.common.annotations.Beta;
 @Beta
 public interface RebindExceptionHandler {
 
-    void onLoadBrooklynMementoFailed(String msg, Exception e);
-    
-    void onLoadLocationMementoFailed(String msg, Exception e);
-
-    void onLoadEntityMementoFailed(String msg, Exception e);
-    
-    void onLoadPolicyMementoFailed(String msg, Exception e);
-    
-    void onLoadEnricherMementoFailed(String msg, Exception e);
+    void onLoadMementoFailed(BrooklynObjectType type, String msg, Exception e);
     
     /**
      * @return the entity to use in place of the missing one, or null (if hasn't thrown an exception)
@@ -64,41 +57,17 @@ public interface RebindExceptionHandler {
      */
     Enricher onDanglingEnricherRef(String id);
 
-    void onCreateLocationFailed(String locId, String locType, Exception e);
-
-    void onCreateEntityFailed(String entityId, String entityType, Exception e);
-
-    void onCreatePolicyFailed(String id, String type, Exception e);
-
-    void onCreateEnricherFailed(String id, String type, Exception e);
-
-    void onLocationNotFound(String id);
-    
-    void onEntityNotFound(String id);
-    
-    void onPolicyNotFound(String id);
-
-    void onPolicyNotFound(String id, String context);
-
-    void onEnricherNotFound(String id);
+    void onCreateFailed(BrooklynObjectType type, String id, String instanceType, Exception e);
 
-    void onEnricherNotFound(String id, String context);
+    void onNotFound(BrooklynObjectType type, String id);
 
-    void onRebindEntityFailed(Entity entity, Exception e);
-
-    void onRebindLocationFailed(Location location, Exception e);
-
-    void onRebindPolicyFailed(Policy policy, Exception e);
-
-    void onRebindEnricherFailed(Enricher enricher, Exception e);
+    void onRebindFailed(BrooklynObjectType type, Identifiable instance, Exception e);
 
     void onAddPolicyFailed(EntityLocal entity, Policy policy, Exception e);
 
     void onAddEnricherFailed(EntityLocal entity, Enricher enricher, Exception e);
 
-    void onManageLocationFailed(Location location, Exception e);
-
-    void onManageEntityFailed(Entity entity, Exception e);
+    void onManageFailed(BrooklynObjectType type, Identifiable instance, Exception e);
 
     void onDone();
     

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/cbb6e40c/core/src/main/java/brooklyn/entity/basic/EntityFunctions.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/entity/basic/EntityFunctions.java b/core/src/main/java/brooklyn/entity/basic/EntityFunctions.java
index 4226a54..af9454c 100644
--- a/core/src/main/java/brooklyn/entity/basic/EntityFunctions.java
+++ b/core/src/main/java/brooklyn/entity/basic/EntityFunctions.java
@@ -26,6 +26,7 @@ import java.util.Map;
 import brooklyn.config.ConfigKey;
 import brooklyn.entity.Application;
 import brooklyn.entity.Entity;
+import brooklyn.entity.trait.Identifiable;
 import brooklyn.event.AttributeSensor;
 import brooklyn.management.ManagementContext;
 import brooklyn.util.flags.TypeCoercions;
@@ -59,9 +60,9 @@ public class EntityFunctions {
         };
     }
     
-    public static Function<Entity, String> id() {
-        return new Function<Entity, String>() {
-            @Override public String apply(Entity input) {
+    public static Function<Identifiable, String> id() {
+        return new Function<Identifiable, String>() {
+            @Override public String apply(Identifiable input) {
                 return (input == null) ? null : input.getId();
             }
         };

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/cbb6e40c/core/src/main/java/brooklyn/entity/rebind/PeriodicDeltaChangeListener.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/entity/rebind/PeriodicDeltaChangeListener.java b/core/src/main/java/brooklyn/entity/rebind/PeriodicDeltaChangeListener.java
index 6507dc7..955ba2e 100644
--- a/core/src/main/java/brooklyn/entity/rebind/PeriodicDeltaChangeListener.java
+++ b/core/src/main/java/brooklyn/entity/rebind/PeriodicDeltaChangeListener.java
@@ -225,28 +225,28 @@ public class PeriodicDeltaChangeListener implements ChangeListener {
                     try {
                         persisterDelta.locations.add(((LocationInternal)location).getRebindSupport().getMemento());
                     } catch (Exception e) {
-                        exceptionHandler.onGenerateLocationMementoFailed(location, e);
+                        exceptionHandler.onGenerateMementoFailed(BrooklynObjectType.LOCATION, location, e);
                     }
                 }
                 for (Entity entity : prevDeltaCollector.entities) {
                     try {
                         persisterDelta.entities.add(((EntityInternal)entity).getRebindSupport().getMemento());
                     } catch (Exception e) {
-                        exceptionHandler.onGenerateEntityMementoFailed(entity, e);
+                        exceptionHandler.onGenerateMementoFailed(BrooklynObjectType.ENTITY, entity, e);
                     }
                 }
                 for (Policy policy : prevDeltaCollector.policies) {
                     try {
                         persisterDelta.policies.add(policy.getRebindSupport().getMemento());
                     } catch (Exception e) {
-                        exceptionHandler.onGeneratePolicyMementoFailed(policy, e);
+                        exceptionHandler.onGenerateMementoFailed(BrooklynObjectType.POLICY, policy, e);
                     }
                 }
                 for (Enricher enricher : prevDeltaCollector.enrichers) {
                     try {
                         persisterDelta.enrichers.add(enricher.getRebindSupport().getMemento());
                     } catch (Exception e) {
-                        exceptionHandler.onGenerateEnricherMementoFailed(enricher, e);
+                        exceptionHandler.onGenerateMementoFailed(BrooklynObjectType.ENRICHER, enricher, e);
                     }
                 }
                 persisterDelta.removedLocationIds = prevDeltaCollector.removedLocationIds;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/cbb6e40c/core/src/main/java/brooklyn/entity/rebind/PersistenceExceptionHandlerImpl.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/entity/rebind/PersistenceExceptionHandlerImpl.java b/core/src/main/java/brooklyn/entity/rebind/PersistenceExceptionHandlerImpl.java
index c8038a2..92f6619 100644
--- a/core/src/main/java/brooklyn/entity/rebind/PersistenceExceptionHandlerImpl.java
+++ b/core/src/main/java/brooklyn/entity/rebind/PersistenceExceptionHandlerImpl.java
@@ -24,11 +24,8 @@ import java.util.concurrent.atomic.AtomicBoolean;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import brooklyn.entity.Entity;
-import brooklyn.location.Location;
+import brooklyn.entity.trait.Identifiable;
 import brooklyn.mementos.Memento;
-import brooklyn.policy.Enricher;
-import brooklyn.policy.Policy;
 import brooklyn.util.exceptions.Exceptions;
 
 import com.google.common.collect.Sets;
@@ -62,27 +59,9 @@ public class PersistenceExceptionHandlerImpl implements PersistenceExceptionHand
     }
     
     @Override
-    public void onGenerateEntityMementoFailed(Entity entity, Exception e) {
-        String errmsg = "generate memento for entity "+entity.getEntityType().getSimpleName()+"("+entity.getId()+")";
-        onErrorImpl(errmsg, e, prevFailedMementoGenerators.add(entity.getId()));
-    }
-    
-    @Override
-    public void onGenerateLocationMementoFailed(Location location, Exception e) {
-        String errmsg = "generate memento for location "+location.getClass().getSimpleName()+"("+location.getId()+")";
-        onErrorImpl(errmsg, e, prevFailedMementoGenerators.add(location.getId()));
-    }
-    
-    @Override
-    public void onGeneratePolicyMementoFailed(Policy policy, Exception e) {
-        String errmsg = "generate memento for policy "+policy.getClass().getSimpleName()+"("+policy.getId()+")";
-        onErrorImpl(errmsg, e, prevFailedMementoGenerators.add(policy.getId()));
-    }
-    
-    @Override
-    public void onGenerateEnricherMementoFailed(Enricher enricher, Exception e) {
-        String errmsg = "generate memento for enricher "+enricher.getClass().getSimpleName()+"("+enricher.getId()+")";
-        onErrorImpl(errmsg, e, prevFailedMementoGenerators.add(enricher.getId()));
+    public void onGenerateMementoFailed(BrooklynObjectType type, Identifiable instance, Exception e) {
+        String errmsg = "generate memento for "+type+" "+instance.getClass().getName()+"("+instance.getId()+")";
+        onErrorImpl(errmsg, e, prevFailedMementoGenerators.add(instance.getId()));
     }
     
     @Override

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/cbb6e40c/core/src/main/java/brooklyn/entity/rebind/RebindExceptionHandlerImpl.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/entity/rebind/RebindExceptionHandlerImpl.java b/core/src/main/java/brooklyn/entity/rebind/RebindExceptionHandlerImpl.java
index 4a1a5b2..53b0c5f 100644
--- a/core/src/main/java/brooklyn/entity/rebind/RebindExceptionHandlerImpl.java
+++ b/core/src/main/java/brooklyn/entity/rebind/RebindExceptionHandlerImpl.java
@@ -30,6 +30,7 @@ import org.slf4j.LoggerFactory;
 import brooklyn.entity.Entity;
 import brooklyn.entity.basic.EntityLocal;
 import brooklyn.entity.rebind.RebindManager.RebindFailureMode;
+import brooklyn.entity.trait.Identifiable;
 import brooklyn.location.Location;
 import brooklyn.policy.Enricher;
 import brooklyn.policy.Policy;
@@ -52,10 +53,7 @@ public class RebindExceptionHandlerImpl implements RebindExceptionHandler {
     protected final Set<String> missingLocations = Sets.newConcurrentHashSet();
     protected final Set<String> missingPolicies = Sets.newConcurrentHashSet();
     protected final Set<String> missingEnrichers = Sets.newConcurrentHashSet();
-    protected final Set<String> creationFailedEntities = Sets.newConcurrentHashSet();
-    protected final Set<String> creationFailedLocations = Sets.newConcurrentHashSet();
-    protected final Set<String> creationFailedPolicies = Sets.newConcurrentHashSet();
-    protected final Set<String> creationFailedEnrichers = Sets.newConcurrentHashSet();
+    protected final Set<String> creationFailedIds = Sets.newConcurrentHashSet();
     protected final Set<Exception> addPolicyFailures = Sets.newConcurrentHashSet();
     protected final Set<Exception> loadPolicyFailures = Sets.newConcurrentHashSet();
     protected final List<Exception> exceptions = Collections.synchronizedList(Lists.<Exception>newArrayList());
@@ -99,64 +97,31 @@ public class RebindExceptionHandlerImpl implements RebindExceptionHandler {
     }
     
     @Override
-    public void onLoadBrooklynMementoFailed(String msg, Exception e) {
-        onLoadMementoFailure(msg, e);
-    }
-    
-    @Override
-    public void onLoadLocationMementoFailed(String msg, Exception e) {
-        onLoadMementoFailure(msg, e);
-    }
-    
-    @Override
-    public void onLoadEntityMementoFailed(String msg, Exception e) {
-        onLoadMementoFailure(msg, e);
-    }
-    
-    @Override
-    public void onLoadPolicyMementoFailed(String msg, Exception e) {
-        Exceptions.propagateIfFatal(e);
-        String errmsg = "problem loading memento: "+msg;
-        
-        switch (loadPolicyFailureMode) {
-        case FAIL_FAST:
-            throw new IllegalStateException("Rebind: aborting due to "+errmsg, e);
-        case FAIL_AT_END:
-            loadPolicyFailures.add(new IllegalStateException(errmsg, e));
-            break;
-        case CONTINUE:
-            LOG.warn(errmsg+"; continuing", e);
-            break;
-        default:
-            throw new IllegalStateException("Unexpected state '"+loadPolicyFailureMode+"' for loadPolicyFailureMode");
-        }
-    }
-    
-    @Override
-    public void onLoadEnricherMementoFailed(String msg, Exception e) {
+    public void onLoadMementoFailed(BrooklynObjectType type, String msg, Exception e) {
         Exceptions.propagateIfFatal(e);
         String errmsg = "problem loading memento: "+msg;
         
-        switch (loadPolicyFailureMode) {
-        case FAIL_FAST:
-            throw new IllegalStateException("Rebind: aborting due to "+errmsg, e);
-        case FAIL_AT_END:
-            loadPolicyFailures.add(new IllegalStateException(errmsg, e));
-            break;
-        case CONTINUE:
-            LOG.warn(errmsg+"; continuing", e);
-            break;
-        default:
-            throw new IllegalStateException("Unexpected state '"+loadPolicyFailureMode+"' for loadPolicyFailureMode");
+        switch (type) {
+            case POLICY:
+            case ENRICHER:
+                switch (loadPolicyFailureMode) {
+                    case FAIL_FAST:
+                        throw new IllegalStateException("Rebind: aborting due to "+errmsg, e);
+                    case FAIL_AT_END:
+                        loadPolicyFailures.add(new IllegalStateException(errmsg, e));
+                        break;
+                    case CONTINUE:
+                        LOG.warn(errmsg+"; continuing", e);
+                        break;
+                    default:
+                        throw new IllegalStateException("Unexpected state '"+loadPolicyFailureMode+"' for loadPolicyFailureMode");
+                }
+                break;
+            default:
+                exceptions.add(new IllegalStateException(errmsg, e));
+                onErrorImpl(errmsg, e);
         }
     }
-    
-    protected void onLoadMementoFailure(String msg, Exception e) {
-        Exceptions.propagateIfFatal(e);
-        String errmsg = "problem loading memento: "+msg;
-        exceptions.add(new IllegalStateException(errmsg, e));
-        onErrorImpl(errmsg, e);
-    }
 
     @Override
     public Entity onDanglingEntityRef(String id) {
@@ -203,151 +168,51 @@ public class RebindExceptionHandlerImpl implements RebindExceptionHandler {
     }
 
     @Override
-    public void onCreateLocationFailed(String id, String type, Exception e) {
-        Exceptions.propagateIfFatal(e);
-        String errmsg = "problem creating location "+id+" of type "+type;
-        creationFailedLocations.add(id);
-        exceptions.add(new IllegalStateException(errmsg, e));
-        onErrorImpl(errmsg, e);
-    }
-
-    @Override
-    public void onCreateEntityFailed(String id, String type, Exception e) {
-        Exceptions.propagateIfFatal(e);
-        String errmsg = "problem creating entity "+id+" of type "+type;
-        creationFailedEntities.add(id);
-        exceptions.add(new IllegalStateException(errmsg, e));
-        onErrorImpl(errmsg, e);
-    }
-
-
-    @Override
-    public void onCreatePolicyFailed(String id, String type, Exception e) {
+    public void onCreateFailed(BrooklynObjectType type, String id, String instanceType, Exception e) {
         Exceptions.propagateIfFatal(e);
-        String errmsg = "problem creating policy "+id+" of type "+type;
-        creationFailedPolicies.add(id);
+        String errmsg = "problem creating "+type+" "+id+" of type "+instanceType;
+        creationFailedIds.add(id);
         exceptions.add(new IllegalStateException(errmsg, e));
         onErrorImpl(errmsg, e);
     }
-    
-    @Override
-    public void onCreateEnricherFailed(String id, String type, Exception e) {
-        Exceptions.propagateIfFatal(e);
-        String errmsg = "problem creating policy "+id+" of type "+type;
-        creationFailedEnrichers.add(id);
-        exceptions.add(new IllegalStateException(errmsg, e));
-        onErrorImpl(errmsg, e);
-    }
-
-    @Override
-    public void onLocationNotFound(String id) {
-        if (creationFailedLocations.contains(id)) {
-            // already know about this; ignore
-        } else {
-            String errmsg = "location '"+id+"' not found";
-            exceptions.add(new IllegalStateException(errmsg));
-            onErrorImpl(errmsg);
-        }
-    }
-    
-    @Override
-    public void onEntityNotFound(String id) {
-        if (creationFailedEntities.contains(id)) {
-            // already know about this; ignore
-        } else {
-            String errmsg = "entity '"+id+"' not found";
-            exceptions.add(new IllegalStateException(errmsg));
-            onErrorImpl(errmsg);
-        }
-    }
 
     @Override
-    public void onPolicyNotFound(String id) {
-        onPolicyNotFound(id, null);
-    }
-    
-    @Override
-    public void onPolicyNotFound(String id, String context) {
-        if (creationFailedPolicies.contains(id)) {
+    public void onNotFound(BrooklynObjectType type, String id) {
+        if (creationFailedIds.contains(id)) {
             // already know about this; ignore
         } else {
-            String errmsg = "policy '"+id+"' not found" + (context == null ? "" : "("+context+")");
+            String errmsg = type+" '"+id+"' not found";
             exceptions.add(new IllegalStateException(errmsg));
             onErrorImpl(errmsg);
         }
     }
-
-    @Override
-    public void onEnricherNotFound(String id) {
-        onEnricherNotFound(id, null);
-    }
     
     @Override
-    public void onEnricherNotFound(String id, String context) {
-        if (creationFailedEnrichers.contains(id)) {
-            // already know about this; ignore
-        } else {
-            String errmsg = "enricher '"+id+"' not found" + (context == null ? "" : "("+context+")");
-            exceptions.add(new IllegalStateException(errmsg));
-            onErrorImpl(errmsg);
-        }
-    }
-
-    @Override
-    public void onRebindLocationFailed(Location location, Exception e) {
-        Exceptions.propagateIfFatal(e);
-        String errmsg = "problem rebinding location "+location.getId()+" ("+location+")";
-        
-        exceptions.add(new IllegalStateException(errmsg, e));
-        onErrorImpl(errmsg, e);
-    }
-
-    @Override
-    public void onRebindEntityFailed(Entity entity, Exception e) {
-        Exceptions.propagateIfFatal(e);
-        String errmsg = "problem rebinding entity "+entity.getId()+" ("+entity+")";
-        
-        exceptions.add(new IllegalStateException(errmsg, e));
-        onErrorImpl(errmsg, e);
-    }
-
-    @Override
-    public void onRebindPolicyFailed(Policy policy, Exception e) {
+    public void onRebindFailed(BrooklynObjectType type, Identifiable instance, Exception e) {
         Exceptions.propagateIfFatal(e);
-        String errmsg = "problem rebinding plicy "+policy.getId()+" ("+policy+")";
+        String errmsg = "problem rebinding "+type+" "+instance.getId()+" ("+instance+")";
         
-        switch (addPolicyFailureMode) {
-        case FAIL_FAST:
-            throw new IllegalStateException("Rebind: aborting due to "+errmsg, e);
-        case FAIL_AT_END:
-            addPolicyFailures.add(new IllegalStateException(errmsg, e));
-            break;
-        case CONTINUE:
-            LOG.warn(errmsg+"; continuing", e);
-            creationFailedPolicies.add(policy.getId());
+        switch (type) {
+        case ENRICHER:
+        case POLICY:
+            switch (addPolicyFailureMode) {
+            case FAIL_FAST:
+                throw new IllegalStateException("Rebind: aborting due to "+errmsg, e);
+            case FAIL_AT_END:
+                addPolicyFailures.add(new IllegalStateException(errmsg, e));
+                break;
+            case CONTINUE:
+                LOG.warn(errmsg+"; continuing", e);
+                creationFailedIds.add(instance.getId());
+                break;
+            default:
+                throw new IllegalStateException("Unexpected state '"+addPolicyFailureMode+"' for addPolicyFailureMode");
+            }
             break;
         default:
-            throw new IllegalStateException("Unexpected state '"+addPolicyFailureMode+"' for addPolicyFailureMode");
-        }
-    }
-
-    @Override
-    public void onRebindEnricherFailed(Enricher enricher, Exception e) {
-        Exceptions.propagateIfFatal(e);
-        String errmsg = "problem rebinding enricher "+enricher.getId()+" ("+enricher+")";
-        
-        switch (addPolicyFailureMode) {
-        case FAIL_FAST:
-            throw new IllegalStateException("Rebind: aborting due to "+errmsg, e);
-        case FAIL_AT_END:
-            addPolicyFailures.add(new IllegalStateException(errmsg, e));
+            exceptions.add(new IllegalStateException(errmsg, e));
+            onErrorImpl(errmsg, e);
             break;
-        case CONTINUE:
-            LOG.warn(errmsg+"; continuing", e);
-            creationFailedEnrichers.add(enricher.getId());
-            break;
-        default:
-            throw new IllegalStateException("Unexpected state '"+addPolicyFailureMode+"' for addPolicyFailureMode");
         }
     }
 
@@ -390,23 +255,14 @@ public class RebindExceptionHandlerImpl implements RebindExceptionHandler {
     }
 
     @Override
-    public void onManageLocationFailed(Location location, Exception e) {
+    public void onManageFailed(BrooklynObjectType type, Identifiable instance, Exception e) {
         Exceptions.propagateIfFatal(e);
-        String errmsg = "problem managing location "+location.getId()+" ("+location+")";
+        String errmsg = "problem managing "+type+" "+instance.getId()+" ("+instance+")";
         
         exceptions.add(new IllegalStateException(errmsg, e));
         onErrorImpl(errmsg, e);
     }
 
-    @Override
-    public void onManageEntityFailed(Entity entity, Exception e) {
-        Exceptions.propagateIfFatal(e);
-        String errmsg = "problem managing entity "+entity.getId()+" ("+entity+")";
-        
-        exceptions.add(new IllegalStateException(errmsg, e));
-        onErrorImpl(errmsg, e);
-    }
-    
     protected void onErrorImpl(String errmsg) {
         onErrorImpl(errmsg, null);
     }

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/cbb6e40c/core/src/main/java/brooklyn/entity/rebind/RebindManagerImpl.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/entity/rebind/RebindManagerImpl.java b/core/src/main/java/brooklyn/entity/rebind/RebindManagerImpl.java
index 34a529e..2bd121c 100644
--- a/core/src/main/java/brooklyn/entity/rebind/RebindManagerImpl.java
+++ b/core/src/main/java/brooklyn/entity/rebind/RebindManagerImpl.java
@@ -23,7 +23,6 @@ import static com.google.common.base.Preconditions.checkNotNull;
 import java.io.IOException;
 import java.util.List;
 import java.util.Map;
-import java.util.Set;
 import java.util.concurrent.Callable;
 import java.util.concurrent.TimeUnit;
 import java.util.concurrent.TimeoutException;
@@ -40,7 +39,6 @@ import brooklyn.entity.basic.AbstractEntity;
 import brooklyn.entity.basic.ConfigKeys;
 import brooklyn.entity.basic.Entities;
 import brooklyn.entity.basic.EntityInternal;
-import brooklyn.entity.proxying.EntitySpec;
 import brooklyn.entity.proxying.InternalEntityFactory;
 import brooklyn.entity.proxying.InternalFactory;
 import brooklyn.entity.proxying.InternalLocationFactory;
@@ -316,7 +314,7 @@ public class RebindManagerImpl implements RebindManager {
                     locations.put(locId, location);
                     rebindContext.registerLocation(locId, location);
                 } catch (Exception e) {
-                    exceptionHandler.onCreateLocationFailed(locId, locType, e);
+                    exceptionHandler.onCreateFailed(BrooklynObjectType.LOCATION, locId, locType, e);
                 }
             }
             
@@ -332,7 +330,7 @@ public class RebindManagerImpl implements RebindManager {
                     entities.put(entityId, entity);
                     rebindContext.registerEntity(entityId, entity);
                 } catch (Exception e) {
-                    exceptionHandler.onCreateEntityFailed(entityId, entityType, e);
+                    exceptionHandler.onCreateFailed(BrooklynObjectType.ENTITY, entityId, entityType, e);
                 }
             }
             
@@ -349,7 +347,7 @@ public class RebindManagerImpl implements RebindManager {
                         policies.put(policyMemento.getId(), policy);
                         rebindContext.registerPolicy(policyMemento.getId(), policy);
                     } catch (Exception e) {
-                        exceptionHandler.onCreatePolicyFailed(policyMemento.getId(), policyMemento.getType(), e);
+                        exceptionHandler.onCreateFailed(BrooklynObjectType.POLICY, policyMemento.getId(), policyMemento.getType(), e);
                     }
                 }
             } else {
@@ -367,7 +365,7 @@ public class RebindManagerImpl implements RebindManager {
                         enrichers.put(enricherMemento.getId(), enricher);
                         rebindContext.registerEnricher(enricherMemento.getId(), enricher);
                     } catch (Exception e) {
-                        exceptionHandler.onCreateEnricherFailed(enricherMemento.getId(), enricherMemento.getType(), e);
+                        exceptionHandler.onCreateFailed(BrooklynObjectType.ENRICHER, enricherMemento.getId(), enricherMemento.getType(), e);
                     }
                 }
             } else {
@@ -385,12 +383,12 @@ public class RebindManagerImpl implements RebindManager {
                 if (LOG.isDebugEnabled()) LOG.debug("RebindManager reconstructing location {}", locMemento);
                 if (location == null) {
                     // usually because of creation-failure, when not using fail-fast
-                    exceptionHandler.onLocationNotFound(locMemento.getId());
+                    exceptionHandler.onNotFound(BrooklynObjectType.LOCATION, locMemento.getId());
                 } else {
                     try {
                         ((LocationInternal)location).getRebindSupport().reconstruct(rebindContext, locMemento);
                     } catch (Exception e) {
-                        exceptionHandler.onRebindLocationFailed(location, e);
+                        exceptionHandler.onRebindFailed(BrooklynObjectType.LOCATION, location, e);
                     }
                 }
             }
@@ -404,12 +402,12 @@ public class RebindManagerImpl implements RebindManager {
     
                     if (policy == null) {
                         // usually because of creation-failure, when not using fail-fast
-                        exceptionHandler.onPolicyNotFound(policyMemento.getId());
+                        exceptionHandler.onNotFound(BrooklynObjectType.POLICY, policyMemento.getId());
                     } else {
                         try {
                             policy.getRebindSupport().reconstruct(rebindContext, policyMemento);
                         } catch (Exception e) {
-                            exceptionHandler.onRebindPolicyFailed(policy, e);
+                            exceptionHandler.onRebindFailed(BrooklynObjectType.POLICY, policy, e);
                             rebindContext.unregisterPolicy(policy);
                         }
                     }
@@ -425,12 +423,12 @@ public class RebindManagerImpl implements RebindManager {
         
                     if (enricher == null) {
                         // usually because of creation-failure, when not using fail-fast
-                        exceptionHandler.onEnricherNotFound(enricherMemento.getId());
+                        exceptionHandler.onNotFound(BrooklynObjectType.ENRICHER, enricherMemento.getId());
                     } else {
                         try {
                             enricher.getRebindSupport().reconstruct(rebindContext, enricherMemento);
                         } catch (Exception e) {
-                            exceptionHandler.onRebindEnricherFailed(enricher, e);
+                            exceptionHandler.onRebindFailed(BrooklynObjectType.ENRICHER, enricher, e);
                             rebindContext.unregisterEnricher(enricher);
                         }
                     }
@@ -446,13 +444,13 @@ public class RebindManagerImpl implements RebindManager {
     
                 if (entity == null) {
                     // usually because of creation-failure, when not using fail-fast
-                    exceptionHandler.onEntityNotFound(entityMemento.getId());
+                    exceptionHandler.onNotFound(BrooklynObjectType.ENTITY, entityMemento.getId());
                 } else {
                     try {
                         entityMemento.injectTypeClass(entity.getClass());
                         ((EntityInternal)entity).getRebindSupport().reconstruct(rebindContext, entityMemento);
                     } catch (Exception e) {
-                        exceptionHandler.onRebindEntityFailed(entity, e);
+                        exceptionHandler.onRebindFailed(BrooklynObjectType.ENTITY, entity, e);
                     }
                 }
             }
@@ -469,14 +467,14 @@ public class RebindManagerImpl implements RebindManager {
     
                 if (entity == null) {
                     // usually because of creation-failure, when not using fail-fast
-                    exceptionHandler.onEntityNotFound(entityMemento.getId());
+                    exceptionHandler.onNotFound(BrooklynObjectType.ENTITY, entityMemento.getId());
                 } else {
                     try {
                         entityMemento.injectTypeClass(entity.getClass());
                         ((EntityInternal)entity).getRebindSupport().addPolicies(rebindContext, entityMemento);
                         ((EntityInternal)entity).getRebindSupport().addEnrichers(rebindContext, entityMemento);
                     } catch (Exception e) {
-                        exceptionHandler.onRebindEntityFailed(entity, e);
+                        exceptionHandler.onRebindFailed(BrooklynObjectType.ENTITY, entity, e);
                     }
                 }
             }
@@ -493,7 +491,7 @@ public class RebindManagerImpl implements RebindManager {
                     try {
                         managementContext.getLocationManager().manage(location);
                     } catch (Exception e) {
-                        exceptionHandler.onManageLocationFailed(location, e);
+                        exceptionHandler.onManageFailed(BrooklynObjectType.LOCATION, location, e);
                     }
                 }
             }
@@ -505,12 +503,12 @@ public class RebindManagerImpl implements RebindManager {
                 Entity entity = rebindContext.getEntity(appId);
                 if (entity == null) {
                     // usually because of creation-failure, when not using fail-fast
-                    exceptionHandler.onEntityNotFound(appId);
+                    exceptionHandler.onNotFound(BrooklynObjectType.ENTITY, appId);
                 } else {
                     try {
                         Entities.startManagement((Application)entity, managementContext);
                     } catch (Exception e) {
-                        exceptionHandler.onManageEntityFailed(entity, e);
+                        exceptionHandler.onManageFailed(BrooklynObjectType.ENTITY, entity, e);
                     }
                     apps.add((Application)entity);
                 }

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/cbb6e40c/core/src/main/java/brooklyn/entity/rebind/dto/BrooklynMementoImpl.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/entity/rebind/dto/BrooklynMementoImpl.java b/core/src/main/java/brooklyn/entity/rebind/dto/BrooklynMementoImpl.java
index 87e18a0..732b7ce 100644
--- a/core/src/main/java/brooklyn/entity/rebind/dto/BrooklynMementoImpl.java
+++ b/core/src/main/java/brooklyn/entity/rebind/dto/BrooklynMementoImpl.java
@@ -29,6 +29,7 @@ import brooklyn.mementos.BrooklynMemento;
 import brooklyn.mementos.EnricherMemento;
 import brooklyn.mementos.EntityMemento;
 import brooklyn.mementos.LocationMemento;
+import brooklyn.mementos.Memento;
 import brooklyn.mementos.PolicyMemento;
 
 import com.google.common.collect.ImmutableList;
@@ -64,6 +65,19 @@ public class BrooklynMementoImpl implements BrooklynMemento, Serializable {
         public Builder topLevelLocationIds(List<String> vals) {
             topLevelLocationIds.addAll(vals); return this;
         }
+        public void memento(Memento memento) {
+            if (memento instanceof EntityMemento) {
+                entity((EntityMemento)memento);
+            } else if (memento instanceof LocationMemento) {
+                location((LocationMemento)memento);
+            } else if (memento instanceof PolicyMemento) {
+                policy((PolicyMemento)memento);
+            } else if (memento instanceof EnricherMemento) {
+                enricher((EnricherMemento)memento);
+            } else {
+                throw new IllegalStateException("Unexpected memento type :"+memento);
+            }
+        }
         public Builder entities(Map<String, EntityMemento> vals) {
             entities.putAll(vals); return this;
         }
@@ -77,7 +91,11 @@ public class BrooklynMementoImpl implements BrooklynMemento, Serializable {
             enrichers.put(val.getId(), val); return this;
         }
         public Builder entity(EntityMemento val) {
-            entities.put(val.getId(), val); return this;
+            entities.put(val.getId(), val);
+            if (val.isTopLevelApp()) {
+                applicationId(val.getId());
+            }
+            return this;
         }
         public Builder location(LocationMemento val) {
             locations.put(val.getId(), val); return this;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/cbb6e40c/core/src/main/java/brooklyn/entity/rebind/persister/BrooklynMementoPersisterToFile.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/entity/rebind/persister/BrooklynMementoPersisterToFile.java b/core/src/main/java/brooklyn/entity/rebind/persister/BrooklynMementoPersisterToFile.java
index 5761215..68dd6eb 100644
--- a/core/src/main/java/brooklyn/entity/rebind/persister/BrooklynMementoPersisterToFile.java
+++ b/core/src/main/java/brooklyn/entity/rebind/persister/BrooklynMementoPersisterToFile.java
@@ -42,6 +42,7 @@ import com.google.common.io.Files;
  * @deprecated since 0.7.0 use BrooklynMementoPersisterToMultiFile instead; the single-file version
  *             has not been tested recently or kept up-to-date. 
  */
+@Deprecated
 public class BrooklynMementoPersisterToFile extends AbstractBrooklynMementoPersister {
 
     // FIXME This is no longer used (instead we use ToMultiFile).

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/cbb6e40c/core/src/main/java/brooklyn/entity/rebind/persister/BrooklynMementoPersisterToMultiFile.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/entity/rebind/persister/BrooklynMementoPersisterToMultiFile.java b/core/src/main/java/brooklyn/entity/rebind/persister/BrooklynMementoPersisterToMultiFile.java
index 935d52d..e587964 100644
--- a/core/src/main/java/brooklyn/entity/rebind/persister/BrooklynMementoPersisterToMultiFile.java
+++ b/core/src/main/java/brooklyn/entity/rebind/persister/BrooklynMementoPersisterToMultiFile.java
@@ -32,6 +32,7 @@ import java.util.concurrent.TimeoutException;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import brooklyn.entity.rebind.BrooklynObjectType;
 import brooklyn.entity.rebind.PersistenceExceptionHandler;
 import brooklyn.entity.rebind.RebindExceptionHandler;
 import brooklyn.entity.rebind.dto.BrooklynMementoImpl;
@@ -60,6 +61,7 @@ import com.google.common.util.concurrent.MoreExecutors;
  * it has a multi-file filesystem backend for equivalent functionality, but is pluggable
  * to support other storage backends 
  */
+@Deprecated
 public class BrooklynMementoPersisterToMultiFile implements BrooklynMementoPersister {
 
     private static final Logger LOG = LoggerFactory.getLogger(BrooklynMementoPersisterToMultiFile.class);
@@ -158,7 +160,7 @@ public class BrooklynMementoPersisterToMultiFile implements BrooklynMementoPersi
             enricherFiles = enrichersDir.listFiles(fileFilter);
         } catch (Exception e) {
             Exceptions.propagateIfFatal(e);
-            exceptionHandler.onLoadBrooklynMementoFailed("Failed to list files", e);
+            exceptionHandler.onLoadMementoFailed(BrooklynObjectType.UNKNOWN, "Failed to list files", e);
             throw new IllegalStateException("Failed to list memento files in "+dir, e);
         }
         
@@ -175,7 +177,7 @@ public class BrooklynMementoPersisterToMultiFile implements BrooklynMementoPersi
                     String type = (String) XmlUtil.xpath(contents, "/entity/type");
                     builder.entity(id, type);
                 } catch (Exception e) {
-                    exceptionHandler.onLoadEntityMementoFailed("File "+file, e);
+                    exceptionHandler.onLoadMementoFailed(BrooklynObjectType.ENTITY, "File "+file, e);
                 }
             }
             for (File file : locationFiles) {
@@ -185,7 +187,7 @@ public class BrooklynMementoPersisterToMultiFile implements BrooklynMementoPersi
                     String type = (String) XmlUtil.xpath(contents, "/location/type");
                     builder.location(id, type);
                 } catch (Exception e) {
-                    exceptionHandler.onLoadLocationMementoFailed("File "+file, e);
+                    exceptionHandler.onLoadMementoFailed(BrooklynObjectType.LOCATION, "File "+file, e);
                 }
             }
             for (File file : policyFiles) {
@@ -195,7 +197,7 @@ public class BrooklynMementoPersisterToMultiFile implements BrooklynMementoPersi
                     String type = (String) XmlUtil.xpath(contents, "/policy/type");
                     builder.policy(id, type);
                 } catch (Exception e) {
-                    exceptionHandler.onLoadPolicyMementoFailed("File "+file, e);
+                    exceptionHandler.onLoadMementoFailed(BrooklynObjectType.POLICY, "File "+file, e);
                 }
             }
             for (File file : enricherFiles) {
@@ -205,7 +207,7 @@ public class BrooklynMementoPersisterToMultiFile implements BrooklynMementoPersi
                     String type = (String) XmlUtil.xpath(contents, "/enricher/type");
                     builder.enricher(id, type);
                 } catch (Exception e) {
-                    exceptionHandler.onLoadEnricherMementoFailed("File "+file, e);
+                    exceptionHandler.onLoadMementoFailed(BrooklynObjectType.ENRICHER, "File "+file, e);
                 }
             }
             
@@ -241,7 +243,7 @@ public class BrooklynMementoPersisterToMultiFile implements BrooklynMementoPersi
             enricherFiles = enrichersDir.listFiles(fileFilter);
         } catch (Exception e) {
             Exceptions.propagateIfFatal(e);
-            exceptionHandler.onLoadBrooklynMementoFailed("Failed to list files", e);
+            exceptionHandler.onLoadMementoFailed(BrooklynObjectType.UNKNOWN, "Failed to list files", e);
             throw new IllegalStateException("Failed to list memento files in "+dir, e);
         }
 
@@ -264,7 +266,7 @@ public class BrooklynMementoPersisterToMultiFile implements BrooklynMementoPersi
                         }
                     }
                 } catch (Exception e) {
-                    exceptionHandler.onLoadEntityMementoFailed("File "+file, e);
+                    exceptionHandler.onLoadMementoFailed(BrooklynObjectType.ENTITY, "File "+file, e);
                 }
             }
             for (File file : locationFiles) {
@@ -276,7 +278,7 @@ public class BrooklynMementoPersisterToMultiFile implements BrooklynMementoPersi
                         builder.location(memento);
                     }
                 } catch (Exception e) {
-                    exceptionHandler.onLoadLocationMementoFailed("File "+file, e);
+                    exceptionHandler.onLoadMementoFailed(BrooklynObjectType.LOCATION, "File "+file, e);
                 }
             }
             for (File file : policyFiles) {
@@ -288,7 +290,7 @@ public class BrooklynMementoPersisterToMultiFile implements BrooklynMementoPersi
                         builder.policy(memento);
                     }
                 } catch (Exception e) {
-                    exceptionHandler.onLoadPolicyMementoFailed("File "+file, e);
+                    exceptionHandler.onLoadMementoFailed(BrooklynObjectType.POLICY, "File "+file, e);
                 }
             }
             for (File file : enricherFiles) {

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/cbb6e40c/core/src/main/java/brooklyn/entity/rebind/persister/BrooklynMementoPersisterToObjectStore.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/entity/rebind/persister/BrooklynMementoPersisterToObjectStore.java b/core/src/main/java/brooklyn/entity/rebind/persister/BrooklynMementoPersisterToObjectStore.java
index 749ae8f..838f252 100644
--- a/core/src/main/java/brooklyn/entity/rebind/persister/BrooklynMementoPersisterToObjectStore.java
+++ b/core/src/main/java/brooklyn/entity/rebind/persister/BrooklynMementoPersisterToObjectStore.java
@@ -38,6 +38,7 @@ import org.slf4j.LoggerFactory;
 import brooklyn.config.BrooklynProperties;
 import brooklyn.config.ConfigKey;
 import brooklyn.entity.basic.ConfigKeys;
+import brooklyn.entity.rebind.BrooklynObjectType;
 import brooklyn.entity.rebind.PeriodicDeltaChangeListener;
 import brooklyn.entity.rebind.PersistenceExceptionHandler;
 import brooklyn.entity.rebind.PersisterDeltaImpl;
@@ -179,7 +180,7 @@ public class BrooklynMementoPersisterToObjectStore implements BrooklynMementoPer
             enricherSubPathList = objectStore.listContentsWithSubPath("enrichers");
         } catch (Exception e) {
             Exceptions.propagateIfFatal(e);
-            exceptionHandler.onLoadBrooklynMementoFailed("Failed to list files", e);
+            exceptionHandler.onLoadMementoFailed(BrooklynObjectType.UNKNOWN, "Failed to list files", e);
             throw new IllegalStateException("Failed to list memento files in "+objectStore, e);
         }
 
@@ -203,7 +204,7 @@ public class BrooklynMementoPersisterToObjectStore implements BrooklynMementoPer
                         builder.entity(id, type);
                     } catch (Exception e) {
                         Exceptions.propagateIfFatal(e);
-                        exceptionHandler.onLoadEntityMementoFailed("Memento "+subPath, e);
+                        exceptionHandler.onLoadMementoFailed(BrooklynObjectType.ENTITY, "Memento "+subPath, e);
                     }
                 }}));
         }
@@ -217,7 +218,7 @@ public class BrooklynMementoPersisterToObjectStore implements BrooklynMementoPer
                         builder.location(id, type);
                     } catch (Exception e) {
                         Exceptions.propagateIfFatal(e);
-                        exceptionHandler.onLoadLocationMementoFailed("Memento "+subPath, e);
+                        exceptionHandler.onLoadMementoFailed(BrooklynObjectType.LOCATION, "Memento "+subPath, e);
                     }
                 }}));
         }
@@ -231,7 +232,7 @@ public class BrooklynMementoPersisterToObjectStore implements BrooklynMementoPer
                         builder.policy(id, type);
                     } catch (Exception e) {
                         Exceptions.propagateIfFatal(e);
-                        exceptionHandler.onLoadPolicyMementoFailed("Memento "+subPath, e);
+                        exceptionHandler.onLoadMementoFailed(BrooklynObjectType.POLICY, "Memento "+subPath, e);
                     }
                 }}));
         }
@@ -245,7 +246,7 @@ public class BrooklynMementoPersisterToObjectStore implements BrooklynMementoPer
                         builder.enricher(id, type);
                     } catch (Exception e) {
                         Exceptions.propagateIfFatal(e);
-                        exceptionHandler.onLoadEnricherMementoFailed("Memento "+subPath, e);
+                        exceptionHandler.onLoadMementoFailed(BrooklynObjectType.ENRICHER, "Memento "+subPath, e);
                     }
                 }}));
         }
@@ -313,7 +314,7 @@ public class BrooklynMementoPersisterToObjectStore implements BrooklynMementoPer
             enricherSubPathList = objectStore.listContentsWithSubPath("enrichers");
         } catch (Exception e) {
             Exceptions.propagateIfFatal(e);
-            exceptionHandler.onLoadBrooklynMementoFailed("Failed to list files", e);
+            exceptionHandler.onLoadMementoFailed(BrooklynObjectType.UNKNOWN, "Failed to list files", e);
             throw new IllegalStateException("Failed to list memento files in "+objectStore+": "+e, e);
         }
         
@@ -325,72 +326,40 @@ public class BrooklynMementoPersisterToObjectStore implements BrooklynMementoPer
         serializer.setLookupContext(lookupContext);
         
         List<ListenableFuture<?>> futures = Lists.newArrayList();
-        
+
+        class MementoLoader implements Runnable {
+            private final String subPath;
+            private final BrooklynObjectType type;
+            public MementoLoader(String subPath, BrooklynObjectType type) {
+                this.subPath = subPath;
+                this.type = type;
+            }
+            public void run() {
+                try {
+                    Memento memento = (Memento) serializer.fromString(read(subPath));
+                    if (memento == null) {
+                        LOG.warn("No "+type.toString().toLowerCase()+"-memento deserialized from " + subPath + "; ignoring and continuing");
+                    } else {
+                        builder.memento(memento);
+                    }
+                } catch (Exception e) {
+                    exceptionHandler.onLoadMementoFailed(type, "Memento "+subPath, e);
+                }
+            }
+        }
+
         try {
             for (final String subPath : entitySubPathList) {
-                futures.add(executor.submit(new Runnable() {
-                    public void run() {
-                        try {
-                            EntityMemento memento = (EntityMemento) serializer.fromString(read(subPath));
-                            if (memento == null) {
-                                LOG.warn("No entity-memento deserialized from " + subPath + "; ignoring and continuing");
-                            } else {
-                                builder.entity(memento);
-                                if (memento.isTopLevelApp()) {
-                                    builder.applicationId(memento.getId());
-                                }
-                            }
-                        } catch (Exception e) {
-                            exceptionHandler.onLoadEntityMementoFailed("Memento "+subPath, e);
-                        }
-                    }}));
+                futures.add(executor.submit(new MementoLoader(subPath, BrooklynObjectType.ENTITY)));
             }
             for (final String subPath : locationSubPathList) {
-                futures.add(executor.submit(new Runnable() {
-                    public void run() {
-                        try {
-                            LocationMemento memento = (LocationMemento) serializer.fromString(read(subPath));
-                            if (memento == null) {
-                                LOG.warn("No location-memento deserialized from " + subPath + "; ignoring and continuing");
-                            } else {
-                                builder.location(memento);
-                            }
-                        } catch (Exception e) {
-                            exceptionHandler.onLoadLocationMementoFailed("Memento "+subPath, e);
-                        }
-                    }}));
+                futures.add(executor.submit(new MementoLoader(subPath, BrooklynObjectType.LOCATION)));
             }
             for (final String subPath : policySubPathList) {
-                futures.add(executor.submit(new Runnable() {
-                    public void run() {
-                        try {
-                            StoreObjectAccessor objectAccessor = objectStore.newAccessor(subPath);
-                            PolicyMemento memento = (PolicyMemento) serializer.fromString(objectAccessor.get());
-                            if (memento == null) {
-                                LOG.warn("No policy-memento deserialized from " + subPath + "; ignoring and continuing");
-                            } else {
-                                builder.policy(memento);
-                            }
-                        } catch (Exception e) {
-                            exceptionHandler.onLoadPolicyMementoFailed("Memento "+subPath, e);
-                        }
-                    }}));
+                futures.add(executor.submit(new MementoLoader(subPath, BrooklynObjectType.POLICY)));
             }
             for (final String subPath : enricherSubPathList) {
-                futures.add(executor.submit(new Runnable() {
-                    public void run() {
-                        try {
-                            StoreObjectAccessor objectAccessor = objectStore.newAccessor(subPath);
-                            EnricherMemento memento = (EnricherMemento) serializer.fromString(objectAccessor.get());
-                            if (memento == null) {
-                                LOG.warn("No enricher-memento deserialized from " + subPath + "; ignoring and continuing");
-                            } else {
-                                builder.enricher(memento);
-                            }
-                        } catch (Exception e) {
-                            exceptionHandler.onLoadEnricherMementoFailed("Memento "+subPath, e);
-                        }
-                    }}));
+                futures.add(executor.submit(new MementoLoader(subPath, BrooklynObjectType.ENRICHER)));
             }
             
             try {

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/cbb6e40c/core/src/test/java/brooklyn/entity/rebind/RebindFailuresTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/brooklyn/entity/rebind/RebindFailuresTest.java b/core/src/test/java/brooklyn/entity/rebind/RebindFailuresTest.java
index 4ab5f00..1fe4007 100644
--- a/core/src/test/java/brooklyn/entity/rebind/RebindFailuresTest.java
+++ b/core/src/test/java/brooklyn/entity/rebind/RebindFailuresTest.java
@@ -40,6 +40,7 @@ import brooklyn.entity.proxying.EntitySpec;
 import brooklyn.entity.rebind.RebindEntityTest.MyEntity;
 import brooklyn.entity.rebind.RebindEntityTest.MyEntityImpl;
 import brooklyn.entity.rebind.RebindManager.RebindFailureMode;
+import brooklyn.entity.trait.Identifiable;
 import brooklyn.event.AttributeSensor;
 import brooklyn.management.EntityManager;
 import brooklyn.management.internal.LocalManagementContext;
@@ -101,10 +102,10 @@ public class RebindFailuresTest extends RebindTestFixtureWithApp {
         }
 
         // exception handler should have been told about failure
-        assertEquals(toEntityIds(exceptionHandler.rebindEntityFailures.keySet()), ImmutableSet.of(origFailingE.getId()));
+        assertEquals(toIds(exceptionHandler.rebindFailures.keySet()), ImmutableSet.of(origFailingE.getId()));
 
         // Expect that on failure will have continued with rebind, and then report all problems
-        assertEquals(toEntityIds(newEntityManager.getEntities()), ImmutableSet.of(origApp.getId(), origFailingE.getId()));
+        assertEquals(toIds(newEntityManager.getEntities()), ImmutableSet.of(origApp.getId(), origFailingE.getId()));
     }
     
     @Test
@@ -127,10 +128,10 @@ public class RebindFailuresTest extends RebindTestFixtureWithApp {
         }
 
         // exception handler should have been told about failure
-        assertEquals(toEntityIds(exceptionHandler.rebindEntityFailures.keySet()), ImmutableSet.of(origFailingE.getId()));
+        assertEquals(toIds(exceptionHandler.rebindFailures.keySet()), ImmutableSet.of(origFailingE.getId()));
         
         // entities will not have been managed
-        assertEquals(toEntityIds(newEntityManager.getEntities()), ImmutableSet.of());
+        assertEquals(toIds(newEntityManager.getEntities()), ImmutableSet.of());
     }
     
     @Test
@@ -148,10 +149,10 @@ public class RebindFailuresTest extends RebindTestFixtureWithApp {
         newApp = rebind(newManagementContext, exceptionHandler);
 
         // exception handler should have been told about failure
-        assertEquals(toEntityIds(exceptionHandler.rebindEntityFailures.keySet()), ImmutableSet.of(origFailingE.getId()));
+        assertEquals(toIds(exceptionHandler.rebindFailures.keySet()), ImmutableSet.of(origFailingE.getId()));
         
         // TODO How should brooklyn indicate that this entity's rebind failed? What can we assert?
-        assertEquals(toEntityIds(newEntityManager.getEntities()), ImmutableSet.of(origApp.getId(), origFailingE.getId()));
+        assertEquals(toIds(newEntityManager.getEntities()), ImmutableSet.of(origApp.getId(), origFailingE.getId()));
     }
     
     @Test
@@ -203,8 +204,8 @@ public class RebindFailuresTest extends RebindTestFixtureWithApp {
         assertFalse(newEnricher.isPresent(), "enricher="+newEnricher);
     }
 
-    private Set<String> toEntityIds(Iterable<? extends Entity> entities) {
-        return ImmutableSet.copyOf(Iterables.transform(entities, EntityFunctions.id()));
+    private Set<String> toIds(Iterable<? extends Identifiable> instances) {
+        return ImmutableSet.copyOf(Iterables.transform(instances, EntityFunctions.id()));
     }
     
     public static class MyPolicyFailingImpl extends AbstractPolicy {

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/cbb6e40c/core/src/test/java/brooklyn/entity/rebind/RecordingRebindExceptionHandler.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/brooklyn/entity/rebind/RecordingRebindExceptionHandler.java b/core/src/test/java/brooklyn/entity/rebind/RecordingRebindExceptionHandler.java
index 378c39d..f9dbe78 100644
--- a/core/src/test/java/brooklyn/entity/rebind/RecordingRebindExceptionHandler.java
+++ b/core/src/test/java/brooklyn/entity/rebind/RecordingRebindExceptionHandler.java
@@ -22,8 +22,8 @@ import java.util.List;
 import java.util.Map;
 
 import brooklyn.entity.Entity;
+import brooklyn.entity.trait.Identifiable;
 import brooklyn.location.Location;
-import brooklyn.policy.Policy;
 
 import com.google.common.collect.Lists;
 import com.google.common.collect.Maps;
@@ -31,17 +31,10 @@ import com.google.common.collect.Maps;
 public class RecordingRebindExceptionHandler extends RebindExceptionHandlerImpl {
 
     protected final List<Exception> loadMementoFailures = Lists.newArrayList();
-    protected final Map<String, Exception> createLocationFailures = Maps.newLinkedHashMap();
-    protected final Map<String, Exception> createEntityFailures = Maps.newLinkedHashMap();
-    protected final Map<String, Exception> createPolicyFailures = Maps.newLinkedHashMap();
-    protected final Map<Location, Exception> rebindLocationFailures = Maps.newLinkedHashMap();
-    protected final Map<Entity, Exception> rebindEntityFailures = Maps.newLinkedHashMap();
-    protected final Map<Policy, Exception> rebindPolicyFailures = Maps.newLinkedHashMap();
-    protected final Map<Location, Exception> manageLocationFailures = Maps.newLinkedHashMap();
-    protected final Map<Entity, Exception> manageEntityFailures = Maps.newLinkedHashMap();
-    protected final Map<String, Exception> locationNotFoundFailures = Maps.newLinkedHashMap();
-    protected final Map<String, Exception> entityNotFoundFailures = Maps.newLinkedHashMap();
-    protected final Map<String, Exception> policyNotFoundFailures = Maps.newLinkedHashMap();
+    protected final Map<String, Exception> createFailures = Maps.newLinkedHashMap();
+    protected final Map<Identifiable, Exception> rebindFailures = Maps.newLinkedHashMap();
+    protected final Map<Identifiable, Exception> manageFailures = Maps.newLinkedHashMap();
+    protected final Map<String, Exception> notFoundFailures = Maps.newLinkedHashMap();
     protected Exception failed;
     
     public RecordingRebindExceptionHandler(RebindManager.RebindFailureMode danglingRefFailureMode, RebindManager.RebindFailureMode rebindFailureMode) {
@@ -49,33 +42,9 @@ public class RecordingRebindExceptionHandler extends RebindExceptionHandlerImpl
     }
 
     @Override
-    public void onLoadBrooklynMementoFailed(String msg, Exception e) {
-        loadMementoFailures.add(new IllegalStateException("problem loading mementos: "+msg, e));
-        super.onLoadBrooklynMementoFailed(msg, e);
-    }
-    
-    @Override
-    public void onLoadLocationMementoFailed(String msg, Exception e) {
-        loadMementoFailures.add(new IllegalStateException("problem loading mementos: "+msg, e));
-        super.onLoadLocationMementoFailed(msg, e);
-    }
-    
-    @Override
-    public void onLoadEntityMementoFailed(String msg, Exception e) {
-        loadMementoFailures.add(new IllegalStateException("problem loading mementos: "+msg, e));
-        super.onLoadEntityMementoFailed(msg, e);
-    }
-    
-    @Override
-    public void onLoadPolicyMementoFailed(String msg, Exception e) {
-        loadMementoFailures.add(new IllegalStateException("problem loading mementos: "+msg, e));
-        super.onLoadPolicyMementoFailed(msg, e);
-    }
-
-    @Override
-    public void onLoadEnricherMementoFailed(String msg, Exception e) {
-        loadMementoFailures.add(new IllegalStateException("problem loading mementos: "+msg, e));
-        super.onLoadPolicyMementoFailed(msg, e);
+    public void onLoadMementoFailed(BrooklynObjectType type, String msg, Exception e) {
+        loadMementoFailures.add(new IllegalStateException("problem loading "+type+" memento: "+msg, e));
+        super.onLoadMementoFailed(type, msg, e);
     }
     
     @Override
@@ -89,72 +58,30 @@ public class RecordingRebindExceptionHandler extends RebindExceptionHandlerImpl
     }
 
     @Override
-    public void onCreateLocationFailed(String id, String type, Exception e) {
-        createLocationFailures.put(id, new IllegalStateException("problem creating location "+id+" of type "+type, e));
-        super.onCreateLocationFailed(id, type, e);
-    }
-
-    @Override
-    public void onCreateEntityFailed(String id, String type, Exception e) {
-        createEntityFailures.put(id, new IllegalStateException("problem creating entity "+id+" of type "+type, e));
-        super.onCreateEntityFailed(id, type, e);
+    public void onCreateFailed(BrooklynObjectType type, String id, String instanceType, Exception e) {
+        createFailures.put(id, new IllegalStateException("problem creating location "+id+" of type "+instanceType, e));
+        super.onCreateFailed(type, id, instanceType, e);
     }
 
     @Override
-    public void onCreatePolicyFailed(String id, String type, Exception e) {
-        createPolicyFailures.put(id, new IllegalStateException("problem creating policy "+id+" of type "+type, e));
-        super.onCreatePolicyFailed(id, type, e);
-    }
-
-    @Override
-    public void onLocationNotFound(String id) {
-        locationNotFoundFailures.put(id, new IllegalStateException("location '"+id+"' not found"));
-        super.onLocationNotFound(id);
-    }
-    
-    @Override
-    public void onEntityNotFound(String id) {
-        entityNotFoundFailures.put(id, new IllegalStateException("entity '"+id+"' not found"));
-        super.onEntityNotFound(id);
+    public void onNotFound(BrooklynObjectType type, String id) {
+        notFoundFailures.put(id, new IllegalStateException(type+" '"+id+"' not found"));
+        super.onNotFound(type, id);
     }
     
     @Override
-    public void onPolicyNotFound(String id) {
-        locationNotFoundFailures.put(id, new IllegalStateException("policy'"+id+"' not found"));
-        super.onPolicyNotFound(id);
-    }
-
-    @Override
-    public void onRebindLocationFailed(Location location, Exception e) {
-        rebindLocationFailures.put(location, new IllegalStateException("problem rebinding location "+location.getId()+" ("+location+")", e));
-        super.onRebindLocationFailed(location, e);
-    }
-
-    @Override
-    public void onRebindEntityFailed(Entity entity, Exception e) {
-        rebindEntityFailures.put(entity, new IllegalStateException("problem rebinding entity "+entity.getId()+" ("+entity+")", e));
-        super.onRebindEntityFailed(entity, e);
-    }
-
-    @Override
-    public void onRebindPolicyFailed(Policy policy, Exception e) {
-        rebindPolicyFailures.put(policy, new IllegalStateException("problem rebinding plicy "+policy.getId()+" ("+policy+")", e));
-        super.onRebindPolicyFailed(policy, e);
+    public void onRebindFailed(BrooklynObjectType type, Identifiable instance, Exception e) {
+        rebindFailures.put(instance, new IllegalStateException("problem rebinding "+type+" "+instance.getId()+" ("+instance+")", e));
+        super.onRebindFailed(type, instance, e);
     }
 
     @Override
-    public void onManageLocationFailed(Location location, Exception e) {
-        manageLocationFailures.put(location, new IllegalStateException("problem managing location "+location.getId()+" ("+location+")", e));
-        super.onManageLocationFailed(location, e);
+    public void onManageFailed(BrooklynObjectType type, Identifiable instance, Exception e) {
+        manageFailures.put(instance, new IllegalStateException("problem managing "+type+" "+instance.getId()+" ("+instance+")", e));
+        super.onManageFailed(type, instance, e);
     }
 
     @Override
-    public void onManageEntityFailed(Entity entity, Exception e) {
-        manageEntityFailures.put(entity, new IllegalStateException("problem managing entity "+entity.getId()+" ("+entity+")", e));
-        super.onManageEntityFailed(entity, e);
-    }
-    
-    @Override
     public void onDone() {
         super.onDone();
     }