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 2016/11/29 13:40:20 UTC

[06/13] brooklyn-server git commit: BROOKLYN-345: add (failing) tests for rebind

BROOKLYN-345: add (failing) tests for rebind


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

Branch: refs/heads/master
Commit: b97cd17839d8414fb70339de37417abc0d3ff574
Parents: c856cd1
Author: Aled Sage <al...@gmail.com>
Authored: Wed Nov 16 09:58:08 2016 +0000
Committer: Aled Sage <al...@gmail.com>
Committed: Mon Nov 28 21:11:48 2016 +0000

----------------------------------------------------------------------
 .../camp/brooklyn/AbstractYamlRebindTest.java   |   1 +
 .../camp/brooklyn/ConfigParametersYamlTest.java |  87 ++++++++---
 .../camp/brooklyn/DslAndRebindYamlTest.java     |  18 +++
 .../ServiceFailureDetectorYamlRebindTest.java   | 147 +++++++++++++++++++
 .../rebind/RecordingRebindExceptionHandler.java |  33 ++++-
 5 files changed, 258 insertions(+), 28 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/b97cd178/camp/camp-brooklyn/src/test/java/org/apache/brooklyn/camp/brooklyn/AbstractYamlRebindTest.java
----------------------------------------------------------------------
diff --git a/camp/camp-brooklyn/src/test/java/org/apache/brooklyn/camp/brooklyn/AbstractYamlRebindTest.java b/camp/camp-brooklyn/src/test/java/org/apache/brooklyn/camp/brooklyn/AbstractYamlRebindTest.java
index 5eae76c..2ba96e2 100644
--- a/camp/camp-brooklyn/src/test/java/org/apache/brooklyn/camp/brooklyn/AbstractYamlRebindTest.java
+++ b/camp/camp-brooklyn/src/test/java/org/apache/brooklyn/camp/brooklyn/AbstractYamlRebindTest.java
@@ -82,6 +82,7 @@ public class AbstractYamlRebindTest extends RebindTestFixture<StartableApplicati
         }
     }
 
+    @Override
     protected StartableApplication rebind(RebindOptions options) throws Exception {
         StartableApplication result = super.rebind(options);
         if (launcher != null) {

http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/b97cd178/camp/camp-brooklyn/src/test/java/org/apache/brooklyn/camp/brooklyn/ConfigParametersYamlTest.java
----------------------------------------------------------------------
diff --git a/camp/camp-brooklyn/src/test/java/org/apache/brooklyn/camp/brooklyn/ConfigParametersYamlTest.java b/camp/camp-brooklyn/src/test/java/org/apache/brooklyn/camp/brooklyn/ConfigParametersYamlTest.java
index 7d6828a..2f655c6 100644
--- a/camp/camp-brooklyn/src/test/java/org/apache/brooklyn/camp/brooklyn/ConfigParametersYamlTest.java
+++ b/camp/camp-brooklyn/src/test/java/org/apache/brooklyn/camp/brooklyn/ConfigParametersYamlTest.java
@@ -55,7 +55,7 @@ import com.google.common.base.Joiner;
 import com.google.common.collect.ImmutableMap;
 import com.google.common.collect.Iterables;
 
-public class ConfigParametersYamlTest extends AbstractYamlTest {
+public class ConfigParametersYamlTest extends AbstractYamlRebindTest {
     @SuppressWarnings("unused")
     private static final Logger LOG = LoggerFactory.getLogger(ConfigParametersYamlTest.class);
 
@@ -77,6 +77,40 @@ public class ConfigParametersYamlTest extends AbstractYamlTest {
     }
     
     @Test
+    public void testConfigParameterWithOverriddenValueListedInType() throws Exception {
+        addCatalogItems(
+                "brooklyn.catalog:",
+                "  itemType: entity",
+                "  items:",
+                "  - id: entity-with-keys",
+                "    item:",
+                "      type: "+TestEntity.class.getName(),
+                "      brooklyn.parameters:",
+                "      - name: testConfigParametersListedInType.mykey",
+                "        description: myDescription",
+                "        type: String",
+                "        default: myDefaultVal",
+                "      brooklyn.config:",
+                "        testConfigParametersListedInType.mykey: myOverridingVal");
+        
+        String yaml = Joiner.on("\n").join(
+                "services:",
+                "- type: entity-with-keys");
+        
+        Entity app = createStartWaitAndLogApplication(yaml);
+        TestEntity entity = (TestEntity) Iterables.getOnlyElement(app.getChildren());
+
+        // Check config key is listed
+        assertKeyEquals(entity, "testConfigParametersListedInType.mykey", "myDescription", String.class, "myDefaultVal", "myOverridingVal");
+
+        // Rebind, and then check again that the config key is listed
+        Entity newApp = rebind();
+        TestEntity newEntity = (TestEntity) Iterables.getOnlyElement(newApp.getChildren());
+        assertKeyEquals(newEntity, "testConfigParametersListedInType.mykey", "myDescription", String.class, "myDefaultVal", "myOverridingVal");
+    }
+    
+
+    @Test
     public void testConfigParametersListedInType() throws Exception {
         addCatalogItems(
                 "brooklyn.catalog:",
@@ -100,19 +134,17 @@ public class ConfigParametersYamlTest extends AbstractYamlTest {
         TestEntity entity = (TestEntity) Iterables.getOnlyElement(app.getChildren());
 
         // Check config key is listed
-        ConfigKey<?> key = entity.getEntityType().getConfigKey("testConfigParametersListedInType.mykey");
-        assertNotNull(key);
-        assertEquals(key.getName(), "testConfigParametersListedInType.mykey");
-        assertEquals(key.getDescription(), "myDescription");
-        assertEquals(key.getType(), Map.class);
-        assertEquals(key.getDefaultValue(), ImmutableMap.of("myDefaultKey", "myDefaultVal"));
-        
-        // Check get default value
-        assertEquals(entity.config().get(key), ImmutableMap.of("myDefaultKey", "myDefaultVal"));
+        Map<?,?> expectedVal = ImmutableMap.of("myDefaultKey", "myDefaultVal");
+        assertKeyEquals(entity, "testConfigParametersListedInType.mykey", "myDescription", Map.class, expectedVal, expectedVal);
+
+        // Rebind, and then check again that the config key is listed
+        Entity newApp = rebind();
+        TestEntity newEntity = (TestEntity) Iterables.getOnlyElement(newApp.getChildren());
+        assertKeyEquals(newEntity, "testConfigParametersListedInType.mykey", "myDescription", Map.class, expectedVal, expectedVal);
     }
     
     /**
-     * See comment in testConfigParametersAtRootListedInTemplateSingleEntity for why we have two 
+     * See comment in testConfigParametersAtRootListedInTemplateSingleEntity for why we have two. 
      * Note that (surprisingly!) it's very important that there are two entities listed under 
      * "services". If there is just one, then the BasicApplication created to wrap it will not 
      * have the key. Instead, the single child will have the key. This is because the top-level 
@@ -144,11 +176,11 @@ public class ConfigParametersYamlTest extends AbstractYamlTest {
         
         Entity app = createStartWaitAndLogApplication(yaml);
         
-        ConfigKey<?> key = app.getEntityType().getConfigKey("test.parameter");
-        assertNotNull(key, "No key 'test.parameter'; keys="+app.getEntityType().getConfigKeys());
-        assertEquals(key.getDescription(), "myDescription");
-        assertEquals(key.getType(), String.class);
-        assertEquals(key.getDefaultValue(), "myDefaultParamVal");
+        assertKeyEquals(app, "test.parameter", "myDescription", String.class, "myDefaultParamVal", "myDefaultParamVal");
+
+        // After rebind, check config key is listed
+        newApp = rebind();
+        assertKeyEquals(newApp, "test.parameter", "myDescription", String.class, "myDefaultParamVal", "myDefaultParamVal");
     }
 
     /**
@@ -178,11 +210,12 @@ public class ConfigParametersYamlTest extends AbstractYamlTest {
         Entity app = createStartWaitAndLogApplication(yaml);
         TestEntity entity = (TestEntity) Iterables.getOnlyElement(app.getChildren());
         
-        ConfigKey<?> key = entity.getEntityType().getConfigKey("test.parameter");
-        assertNotNull(key, "No key 'test.parameter'; keys="+entity.getEntityType().getConfigKeys());
-        assertEquals(key.getDescription(), "myDescription");
-        assertEquals(key.getType(), String.class);
-        assertEquals(key.getDefaultValue(), "myDefaultParamVal");
+        assertKeyEquals(entity, "test.parameter", "myDescription", String.class, "myDefaultParamVal", "myDefaultParamVal");
+        
+        // After rebind, check config key is listed
+        newApp = rebind();
+        TestEntity newEntity = (TestEntity) Iterables.getOnlyElement(newApp.getChildren());
+        assertKeyEquals(newEntity, "test.parameter", "myDescription", String.class, "myDefaultParamVal", "myDefaultParamVal");
     }
 
     @Test
@@ -614,4 +647,16 @@ public class ConfigParametersYamlTest extends AbstractYamlTest {
         assertEquals(entity.config().get(ConfigKeys.newConfigKey(Object.class, "my.param.key")), PortRanges.fromInteger(1234));
         assertEquals(entity.sensors().get(Sensors.newSensor(Object.class, "my.param.key")), 1234);
     }
+
+    protected <T> void assertKeyEquals(Entity entity, String keyName, String expectedDescription, Class<T> expectedType, T expectedDefaultVal, T expectedEntityVal) {
+        ConfigKey<?> key = entity.getEntityType().getConfigKey(keyName);
+        assertNotNull(key, "No key '"+keyName+"'; keys="+entity.getEntityType().getConfigKeys());
+
+        assertEquals(key.getName(), keyName);
+        assertEquals(key.getDescription(), expectedDescription);
+        assertEquals(key.getType(), expectedType);
+        assertEquals(key.getDefaultValue(), expectedDefaultVal);
+        
+        assertEquals(entity.config().get(key), expectedEntityVal);
+    }
 }

http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/b97cd178/camp/camp-brooklyn/src/test/java/org/apache/brooklyn/camp/brooklyn/DslAndRebindYamlTest.java
----------------------------------------------------------------------
diff --git a/camp/camp-brooklyn/src/test/java/org/apache/brooklyn/camp/brooklyn/DslAndRebindYamlTest.java b/camp/camp-brooklyn/src/test/java/org/apache/brooklyn/camp/brooklyn/DslAndRebindYamlTest.java
index 91da883..9770338 100644
--- a/camp/camp-brooklyn/src/test/java/org/apache/brooklyn/camp/brooklyn/DslAndRebindYamlTest.java
+++ b/camp/camp-brooklyn/src/test/java/org/apache/brooklyn/camp/brooklyn/DslAndRebindYamlTest.java
@@ -386,6 +386,7 @@ public class DslAndRebindYamlTest extends AbstractYamlRebindTest {
         Entity e2 = rebind(testEntity);
 
         Assert.assertEquals(getConfigInTask(e2, TestEntity.CONF_NAME), "bar");
+        Assert.assertEquals(e2.getConfig(TestEntity.CONF_NAME), "bar");
     }
 
     private Entity entityWithConfigFromRoot() throws Exception {
@@ -397,6 +398,23 @@ public class DslAndRebindYamlTest extends AbstractYamlRebindTest {
                 "  foo: bar");
     }
 
+    @Test
+    public void testDslConfigWithBrooklynParameterDefault() throws Exception {
+        Entity testEntity = setupAndCheckTestEntityInBasicYamlWith(
+                "  id: x",
+                "  brooklyn.parameters:",
+                "  - name: test.param",
+                "    type: String",
+                "    default: myDefaultVal",
+                "  brooklyn.config:",
+                "    test.confName: $brooklyn:config(\"test.param\")");
+        Assert.assertEquals(getConfigInTask(testEntity, TestEntity.CONF_NAME), "myDefaultVal");
+        Assert.assertEquals(testEntity.config().get(TestEntity.CONF_NAME), "myDefaultVal");
+        
+        Entity e2 = rebind(testEntity);
+        Assert.assertEquals(getConfigInTask(e2, TestEntity.CONF_NAME), "myDefaultVal");
+        Assert.assertEquals(e2.config().get(TestEntity.CONF_NAME), "myDefaultVal");
+    }
 
     @Test
     public void testDslFormatString() throws Exception {

http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/b97cd178/camp/camp-brooklyn/src/test/java/org/apache/brooklyn/camp/brooklyn/ServiceFailureDetectorYamlRebindTest.java
----------------------------------------------------------------------
diff --git a/camp/camp-brooklyn/src/test/java/org/apache/brooklyn/camp/brooklyn/ServiceFailureDetectorYamlRebindTest.java b/camp/camp-brooklyn/src/test/java/org/apache/brooklyn/camp/brooklyn/ServiceFailureDetectorYamlRebindTest.java
new file mode 100644
index 0000000..377a2a5
--- /dev/null
+++ b/camp/camp-brooklyn/src/test/java/org/apache/brooklyn/camp/brooklyn/ServiceFailureDetectorYamlRebindTest.java
@@ -0,0 +1,147 @@
+/*
+ * 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.brooklyn.camp.brooklyn;
+
+import static org.apache.brooklyn.camp.brooklyn.ServiceFailureDetectorYamlTest.appVersionedId;
+import static org.apache.brooklyn.camp.brooklyn.ServiceFailureDetectorYamlTest.assertEnricherConfigMatchesDsl;
+import static org.apache.brooklyn.camp.brooklyn.ServiceFailureDetectorYamlTest.assertHasEnricher;
+import static org.apache.brooklyn.camp.brooklyn.ServiceFailureDetectorYamlTest.catalogYamlSimple;
+import static org.apache.brooklyn.camp.brooklyn.ServiceFailureDetectorYamlTest.catalogYamlWithDsl;
+import static org.apache.brooklyn.camp.brooklyn.ServiceFailureDetectorYamlTest.catalogYamlWithDslReferenceParentDefault;
+import static org.apache.brooklyn.camp.brooklyn.ServiceFailureDetectorYamlTest.subscribeToHaSensors;
+
+import org.apache.brooklyn.api.entity.Entity;
+import org.apache.brooklyn.api.mgmt.rebind.RebindManager.RebindFailureMode;
+import org.apache.brooklyn.core.entity.RecordingSensorEventListener;
+import org.apache.brooklyn.core.entity.StartableApplication;
+import org.apache.brooklyn.core.entity.lifecycle.ServiceStateLogic.ServiceNotUpLogic;
+import org.apache.brooklyn.core.mgmt.rebind.RebindExceptionHandlerImpl;
+import org.apache.brooklyn.core.mgmt.rebind.RebindOptions;
+import org.apache.brooklyn.core.mgmt.rebind.RecordingRebindExceptionHandler;
+import org.apache.brooklyn.core.sensor.SensorEventPredicates;
+import org.apache.brooklyn.core.test.entity.TestEntity;
+import org.apache.brooklyn.policy.ha.HASensors;
+import org.apache.brooklyn.policy.ha.ServiceFailureDetector;
+import org.testng.annotations.Test;
+
+import com.google.common.base.Joiner;
+import com.google.common.collect.Iterables;
+
+@Test
+public class ServiceFailureDetectorYamlRebindTest extends AbstractYamlRebindTest {
+    
+    final static String INDICATOR_KEY_1 = "test-indicator-1";
+
+    @Test
+    public void testRebindWhenHealthy() throws Exception {
+        runRebindWhenHealthy(catalogYamlSimple, appVersionedId);
+    }
+    
+    @Test
+    public void testRebindWhenHealthyWithDslConfig() throws Exception {
+        runRebindWhenHealthy(catalogYamlWithDsl, appVersionedId);
+        
+        TestEntity newEntity = (TestEntity) Iterables.getOnlyElement(app().getChildren());
+        ServiceFailureDetector newEnricher = assertHasEnricher(newEntity, ServiceFailureDetector.class);
+        assertEnricherConfigMatchesDsl(newEnricher);
+    }
+
+    @Test
+    public void testRebindWhenHealthyWithDslConfigReferenceParentDefault() throws Exception {
+        runRebindWhenHealthy(catalogYamlWithDslReferenceParentDefault, appVersionedId);
+        
+        TestEntity newEntity = (TestEntity) Iterables.getOnlyElement(app().getChildren());
+        ServiceFailureDetector newEnricher = assertHasEnricher(newEntity, ServiceFailureDetector.class);
+        assertEnricherConfigMatchesDsl(newEnricher);
+    }
+    
+    @Test
+    public void testRebindWhenHasNotUpIndicator() throws Exception {
+        runRebindWhenNotUp(catalogYamlSimple, appVersionedId);
+    }
+    
+    // See https://issues.apache.org/jira/browse/BROOKLYN-345
+    @Test
+    public void testRebinWhenHasNotUpIndicatorWithDslConfig() throws Exception {
+        runRebindWhenNotUp(catalogYamlWithDsl, appVersionedId);
+    }
+    
+    // See https://issues.apache.org/jira/browse/BROOKLYN-345
+    @Test
+    public void testRebindWhenHasNotUpIndicatorWithDslConfigReferenceParentDefault() throws Exception {
+        runRebindWhenNotUp(catalogYamlWithDslReferenceParentDefault, appVersionedId);
+    }
+    
+    protected void runRebindWhenHealthy(String catalogYaml, String appId) throws Exception {
+        addCatalogItems(catalogYaml);
+
+        String appYaml = Joiner.on("\n").join(
+                "services:",
+                "- type: " + appId);
+        createStartWaitAndLogApplication(appYaml);
+
+        // Rebind
+        StartableApplication newApp = rebind();
+        TestEntity newEntity = (TestEntity) Iterables.getOnlyElement(newApp.getChildren());
+        assertHasEnricher(newEntity, ServiceFailureDetector.class);
+        
+        // Confirm ServiceFailureDetector still functions
+        RecordingSensorEventListener<Object> listener = subscribeToHaSensors(newEntity);
+        
+        ServiceNotUpLogic.updateNotUpIndicator(newEntity, INDICATOR_KEY_1, "Simulate a problem");
+        listener.assertHasEventEventually(SensorEventPredicates.sensorEqualTo(HASensors.ENTITY_FAILED));
+        listener.assertEventCount(1);
+    }
+
+    protected void runRebindWhenNotUp(String catalogYaml, String appId) throws Exception {
+        addCatalogItems(catalogYaml);
+
+        String appYaml = Joiner.on("\n").join(
+                "services:",
+                "- type: " + appId);
+        Entity app = createStartWaitAndLogApplication(appYaml);
+        
+        // Make entity go on-fire
+        TestEntity entity = (TestEntity) Iterables.getOnlyElement(app.getChildren());
+        RecordingSensorEventListener<Object> listener = subscribeToHaSensors(entity);
+        ServiceNotUpLogic.updateNotUpIndicator(entity, INDICATOR_KEY_1, "Simulating a problem");
+        listener.assertHasEventEventually(SensorEventPredicates.sensorEqualTo(HASensors.ENTITY_FAILED));
+
+        // Rebind
+        StartableApplication newApp = rebind();
+        TestEntity newEntity = (TestEntity) Iterables.getOnlyElement(newApp.getChildren());
+        assertHasEnricher(newEntity, ServiceFailureDetector.class);
+        
+        // Confirm ServiceFailureDetector still functions
+        RecordingSensorEventListener<Object> newListener = subscribeToHaSensors(newEntity);
+        
+        ServiceNotUpLogic.clearNotUpIndicator(newEntity, INDICATOR_KEY_1);
+        newListener.assertHasEventEventually(SensorEventPredicates.sensorEqualTo(HASensors.ENTITY_RECOVERED));
+        newListener.assertEventCount(1);
+    }
+    
+    @Override
+    protected StartableApplication rebind() throws Exception {
+        RecordingRebindExceptionHandler exceptionHandler = new RecordingRebindExceptionHandler(RebindExceptionHandlerImpl.builder()
+                .addPolicyFailureMode(RebindFailureMode.FAIL_AT_END)
+                .loadPolicyFailureMode(RebindFailureMode.FAIL_AT_END)
+                .danglingRefFailureMode(RebindFailureMode.FAIL_AT_END));
+        return rebind(RebindOptions.create().exceptionHandler(exceptionHandler));
+    }
+}

http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/b97cd178/core/src/test/java/org/apache/brooklyn/core/mgmt/rebind/RecordingRebindExceptionHandler.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/core/mgmt/rebind/RecordingRebindExceptionHandler.java b/core/src/test/java/org/apache/brooklyn/core/mgmt/rebind/RecordingRebindExceptionHandler.java
index 6d27fc7..b94970d 100644
--- a/core/src/test/java/org/apache/brooklyn/core/mgmt/rebind/RecordingRebindExceptionHandler.java
+++ b/core/src/test/java/org/apache/brooklyn/core/mgmt/rebind/RecordingRebindExceptionHandler.java
@@ -22,28 +22,35 @@ import java.util.List;
 import java.util.Map;
 
 import org.apache.brooklyn.api.entity.Entity;
+import org.apache.brooklyn.api.entity.EntityLocal;
 import org.apache.brooklyn.api.location.Location;
 import org.apache.brooklyn.api.mgmt.rebind.RebindManager;
 import org.apache.brooklyn.api.objs.BrooklynObject;
 import org.apache.brooklyn.api.objs.BrooklynObjectType;
-import org.apache.brooklyn.core.mgmt.rebind.RebindExceptionHandlerImpl;
+import org.apache.brooklyn.api.policy.Policy;
+import org.apache.brooklyn.api.sensor.Enricher;
 
 import com.google.common.collect.Lists;
 import com.google.common.collect.Maps;
 
 public class RecordingRebindExceptionHandler extends RebindExceptionHandlerImpl {
 
-    protected final List<Exception> loadMementoFailures = Lists.newArrayList();
-    protected final Map<String, Exception> createFailures = Maps.newLinkedHashMap();
-    protected final Map<BrooklynObject, Exception> rebindFailures = Maps.newLinkedHashMap();
-    protected final Map<BrooklynObject, Exception> manageFailures = Maps.newLinkedHashMap();
-    protected final Map<String, Exception> notFoundFailures = Maps.newLinkedHashMap();
-    protected Exception failed;
+    public final List<Exception> loadMementoFailures = Lists.newArrayList();
+    public final Map<String, Exception> createFailures = Maps.newLinkedHashMap();
+    public final Map<BrooklynObject, Exception> rebindFailures = Maps.newLinkedHashMap();
+    public final Map<BrooklynObject, Exception> manageFailures = Maps.newLinkedHashMap();
+    public final Map<BrooklynObject, Exception> addFailures = Maps.newLinkedHashMap();
+    public final Map<String, Exception> notFoundFailures = Maps.newLinkedHashMap();
+    public Exception failed;
     
     public RecordingRebindExceptionHandler(RebindManager.RebindFailureMode danglingRefFailureMode, RebindManager.RebindFailureMode rebindFailureMode) {
         super(builder().danglingRefFailureMode(danglingRefFailureMode).rebindFailureMode(rebindFailureMode));
     }
 
+    public RecordingRebindExceptionHandler(Builder builder) {
+        super(builder);
+    }
+
     @Override
     public void onLoadMementoFailed(BrooklynObjectType type, String msg, Exception e) {
         loadMementoFailures.add(new IllegalStateException("problem loading "+type.toCamelCase()+" memento: "+msg, e));
@@ -89,4 +96,16 @@ public class RecordingRebindExceptionHandler extends RebindExceptionHandlerImpl
         failed = e;
         return super.onFailed(e);
     }
+    
+    @Override
+    public void onAddEnricherFailed(EntityLocal entity, Enricher enricher, Exception e) {
+        addFailures.put(enricher, e);
+        super.onAddEnricherFailed(entity, enricher, e);
+    }
+    
+    @Override
+    public void onAddPolicyFailed(EntityLocal entity, Policy policy, Exception e) {
+        addFailures.put(policy, e);
+        super.onAddPolicyFailed(entity, policy, e);
+    }
 }