You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@brooklyn.apache.org by ge...@apache.org on 2017/04/28 10:32:05 UTC

[04/13] brooklyn-server git commit: done the basics, bundle persistence working and with a test

http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/abd0cb8b/core/src/main/java/org/apache/brooklyn/core/plan/PlanToSpecTransformer.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/core/plan/PlanToSpecTransformer.java b/core/src/main/java/org/apache/brooklyn/core/plan/PlanToSpecTransformer.java
index ff1d33a..f0295cf 100644
--- a/core/src/main/java/org/apache/brooklyn/core/plan/PlanToSpecTransformer.java
+++ b/core/src/main/java/org/apache/brooklyn/core/plan/PlanToSpecTransformer.java
@@ -27,6 +27,7 @@ import org.apache.brooklyn.api.entity.EntitySpec;
 import org.apache.brooklyn.api.internal.AbstractBrooklynObjectSpec;
 import org.apache.brooklyn.core.mgmt.ManagementContextInjectable;
 import org.apache.brooklyn.core.typereg.BrooklynTypePlanTransformer;
+import org.apache.brooklyn.core.typereg.UnsupportedTypePlanException;
 
 import com.google.common.annotations.Beta;
 
@@ -50,20 +51,20 @@ public interface PlanToSpecTransformer extends ManagementContextInjectable {
     /** creates an {@link EntitySpec} given a complete plan textual description for a top-level application, 
      * according to the transformation rules this understands.
      * <p>
-     * should throw {@link PlanNotRecognizedException} if not supported. */
-    EntitySpec<? extends Application> createApplicationSpec(String plan) throws PlanNotRecognizedException;
+     * should throw {@link UnsupportedTypePlanException} if not supported. */
+    EntitySpec<? extends Application> createApplicationSpec(String plan) throws PlanNotRecognizedException, UnsupportedTypePlanException;
     
     /** creates an object spec given a catalog item.
      * <p>
      * the catalog item might be known by type, or its source plan fragment text might be inspected and transformed.
      * implementations will typically look at the {@link CatalogItem#getCatalogItemType()} first.
      * <p>
-     * should throw {@link PlanNotRecognizedException} if this transformer does not know what to do with the plan.
+     * should throw {@link UnsupportedTypePlanException} if this transformer does not know what to do with the plan.
      * 
      * @param item - The catalog item to convert to a spec. The item might not be fully populated (i.e. missing {@code symbolicName} if called
      *        from the catalog parser).
      * @param encounteredTypes - The {@code symbolicName}s of catalog items being resolved up the stack, but not including {@code item}.
      */
-    <T,SpecT extends AbstractBrooklynObjectSpec<? extends T, SpecT>> SpecT createCatalogSpec(CatalogItem<T, SpecT> item, Set<String> encounteredTypes) throws PlanNotRecognizedException;
+    <T,SpecT extends AbstractBrooklynObjectSpec<? extends T, SpecT>> SpecT createCatalogSpec(CatalogItem<T, SpecT> item, Set<String> encounteredTypes) throws PlanNotRecognizedException, UnsupportedTypePlanException;
     
 }

http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/abd0cb8b/core/src/main/java/org/apache/brooklyn/core/typereg/BasicManagedBundle.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/core/typereg/BasicManagedBundle.java b/core/src/main/java/org/apache/brooklyn/core/typereg/BasicManagedBundle.java
index 8d92794..1ee8aa5 100644
--- a/core/src/main/java/org/apache/brooklyn/core/typereg/BasicManagedBundle.java
+++ b/core/src/main/java/org/apache/brooklyn/core/typereg/BasicManagedBundle.java
@@ -25,6 +25,7 @@ import org.apache.brooklyn.api.mgmt.rebind.RebindSupport;
 import org.apache.brooklyn.api.typereg.ManagedBundle;
 import org.apache.brooklyn.api.typereg.OsgiBundleWithUrl;
 import org.apache.brooklyn.config.ConfigKey;
+import org.apache.brooklyn.core.mgmt.rebind.BasicManagedBundleRebindSupport;
 import org.apache.brooklyn.core.objs.AbstractBrooklynObject;
 import org.apache.brooklyn.core.objs.BrooklynObjectInternal;
 
@@ -148,7 +149,7 @@ public class BasicManagedBundle extends AbstractBrooklynObject implements Manage
 
     @Override
     public RebindSupport<?> getRebindSupport() {
-        throw new UnsupportedOperationException();
+        return new BasicManagedBundleRebindSupport(this);
     }
 
     @Override

http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/abd0cb8b/core/src/main/java/org/apache/brooklyn/core/typereg/TypePlanTransformers.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/core/typereg/TypePlanTransformers.java b/core/src/main/java/org/apache/brooklyn/core/typereg/TypePlanTransformers.java
index 8ca0289..ba81e07 100644
--- a/core/src/main/java/org/apache/brooklyn/core/typereg/TypePlanTransformers.java
+++ b/core/src/main/java/org/apache/brooklyn/core/typereg/TypePlanTransformers.java
@@ -120,11 +120,7 @@ public class TypePlanTransformers {
                     continue;
                 }
                 return Maybe.of(result);
-            } catch (UnsupportedTypePlanException e) {
-                transformersWhoDontSupport.add(t.getFormatCode() +
-                    (Strings.isNonBlank(e.getMessage()) ? " ("+e.getMessage()+")" : ""));
-            } catch (@SuppressWarnings("deprecation") org.apache.brooklyn.core.plan.PlanNotRecognizedException e) {
-                // just in case (shouldn't happen)
+            } catch (@SuppressWarnings("deprecation") org.apache.brooklyn.core.plan.PlanNotRecognizedException | UnsupportedTypePlanException e) {
                 transformersWhoDontSupport.add(t.getFormatCode() +
                     (Strings.isNonBlank(e.getMessage()) ? " ("+e.getMessage()+")" : ""));
             } catch (Throwable e) {

http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/abd0cb8b/core/src/test/java/org/apache/brooklyn/core/mgmt/ha/HighAvailabilityManagerSplitBrainTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/core/mgmt/ha/HighAvailabilityManagerSplitBrainTest.java b/core/src/test/java/org/apache/brooklyn/core/mgmt/ha/HighAvailabilityManagerSplitBrainTest.java
index d7d9ac9..c3657c6 100644
--- a/core/src/test/java/org/apache/brooklyn/core/mgmt/ha/HighAvailabilityManagerSplitBrainTest.java
+++ b/core/src/test/java/org/apache/brooklyn/core/mgmt/ha/HighAvailabilityManagerSplitBrainTest.java
@@ -37,8 +37,6 @@ import org.apache.brooklyn.api.mgmt.ha.ManagementPlaneSyncRecordPersister;
 import org.apache.brooklyn.core.BrooklynFeatureEnablement;
 import org.apache.brooklyn.core.entity.Entities;
 import org.apache.brooklyn.core.entity.factory.ApplicationBuilder;
-import org.apache.brooklyn.core.mgmt.ha.HighAvailabilityManagerImpl;
-import org.apache.brooklyn.core.mgmt.ha.ManagementPlaneSyncRecordPersisterToObjectStore;
 import org.apache.brooklyn.core.mgmt.ha.TestEntityFailingRebind.RebindException;
 import org.apache.brooklyn.core.mgmt.internal.ManagementContextInternal;
 import org.apache.brooklyn.core.mgmt.persist.BrooklynMementoPersisterToObjectStore;
@@ -71,7 +69,7 @@ public class HighAvailabilityManagerSplitBrainTest {
     private static final Logger log = LoggerFactory.getLogger(HighAvailabilityManagerSplitBrainTest.class);
     
     private List<HaMgmtNode> nodes = new MutableList<HighAvailabilityManagerSplitBrainTest.HaMgmtNode>();
-    Map<String,String> sharedBackingStore = MutableMap.of();
+    Map<String,byte[]> sharedBackingStore = MutableMap.of();
     Map<String,Date> sharedBackingStoreDates = MutableMap.of();
     private AtomicLong sharedTime; // used to set the ticker's return value
     private ClassLoader classLoader = getClass().getClassLoader();

http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/abd0cb8b/core/src/test/java/org/apache/brooklyn/core/mgmt/ha/HotStandbyTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/core/mgmt/ha/HotStandbyTest.java b/core/src/test/java/org/apache/brooklyn/core/mgmt/ha/HotStandbyTest.java
index 4fefddd..abdee40 100644
--- a/core/src/test/java/org/apache/brooklyn/core/mgmt/ha/HotStandbyTest.java
+++ b/core/src/test/java/org/apache/brooklyn/core/mgmt/ha/HotStandbyTest.java
@@ -78,7 +78,7 @@ public class HotStandbyTest {
     private static final Logger log = LoggerFactory.getLogger(HotStandbyTest.class);
     
     private List<HaMgmtNode> nodes = new MutableList<HotStandbyTest.HaMgmtNode>();
-    Map<String,String> sharedBackingStore = MutableMap.of();
+    Map<String,byte[]> sharedBackingStore = MutableMap.of();
     Map<String,Date> sharedBackingStoreDates = MutableMap.of();
     private ClassLoader classLoader = getClass().getClassLoader();
     

http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/abd0cb8b/core/src/test/java/org/apache/brooklyn/core/mgmt/ha/WarmStandbyTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/core/mgmt/ha/WarmStandbyTest.java b/core/src/test/java/org/apache/brooklyn/core/mgmt/ha/WarmStandbyTest.java
index 7aa7353..c245ee2 100644
--- a/core/src/test/java/org/apache/brooklyn/core/mgmt/ha/WarmStandbyTest.java
+++ b/core/src/test/java/org/apache/brooklyn/core/mgmt/ha/WarmStandbyTest.java
@@ -55,7 +55,7 @@ public class WarmStandbyTest {
     private static final Logger log = LoggerFactory.getLogger(WarmStandbyTest.class);
     
     private List<HaMgmtNode> nodes = new MutableList<WarmStandbyTest.HaMgmtNode>();
-    Map<String,String> sharedBackingStore = MutableMap.of();
+    Map<String,byte[]> sharedBackingStore = MutableMap.of();
     Map<String,Date> sharedBackingStoreDates = MutableMap.of();
     private ClassLoader classLoader = getClass().getClassLoader();
     

http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/abd0cb8b/core/src/test/java/org/apache/brooklyn/core/mgmt/osgi/OsgiVersionMoreEntityTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/core/mgmt/osgi/OsgiVersionMoreEntityTest.java b/core/src/test/java/org/apache/brooklyn/core/mgmt/osgi/OsgiVersionMoreEntityTest.java
index c4b9fdf..059b83d 100644
--- a/core/src/test/java/org/apache/brooklyn/core/mgmt/osgi/OsgiVersionMoreEntityTest.java
+++ b/core/src/test/java/org/apache/brooklyn/core/mgmt/osgi/OsgiVersionMoreEntityTest.java
@@ -23,14 +23,12 @@ import java.io.IOException;
 import java.lang.reflect.InvocationTargetException;
 import java.util.Arrays;
 import java.util.List;
-import java.util.Map;
 
 import org.apache.brooklyn.api.entity.Entity;
 import org.apache.brooklyn.api.entity.EntitySpec;
 import org.apache.brooklyn.api.mgmt.ManagementContext;
 import org.apache.brooklyn.api.objs.BrooklynObject;
 import org.apache.brooklyn.api.policy.PolicySpec;
-import org.apache.brooklyn.api.typereg.ManagedBundle;
 import org.apache.brooklyn.api.typereg.RegisteredType;
 import org.apache.brooklyn.core.catalog.internal.CatalogEntityItemDto;
 import org.apache.brooklyn.core.catalog.internal.CatalogItemBuilder;
@@ -44,11 +42,8 @@ import org.apache.brooklyn.core.objs.proxy.InternalEntityFactory;
 import org.apache.brooklyn.core.objs.proxy.InternalPolicyFactory;
 import org.apache.brooklyn.core.test.entity.LocalManagementContextForTests;
 import org.apache.brooklyn.core.test.entity.TestApplication;
-import org.apache.brooklyn.core.typereg.BasicManagedBundle;
-import org.apache.brooklyn.test.Asserts;
 import org.apache.brooklyn.test.support.TestResourceUnavailableException;
 import org.apache.brooklyn.util.collections.MutableList;
-import org.apache.brooklyn.util.core.ResourceUtils;
 import org.apache.brooklyn.util.core.osgi.OsgiTestBase;
 import org.apache.brooklyn.util.core.osgi.Osgis;
 import org.apache.brooklyn.util.guava.Maybe;
@@ -71,20 +66,8 @@ import com.google.common.collect.Iterables;
  * Tests that OSGi entities load correctly and have the right catalog information set.
  * Note further tests done elsewhere using CAMP YAML (referring to methods in this class).
  */
-public class OsgiVersionMoreEntityTest {
+public class OsgiVersionMoreEntityTest implements OsgiTestResources {
    
-    public static final String BROOKLYN_TEST_OSGI_ENTITIES_PATH = OsgiTestResources.BROOKLYN_TEST_OSGI_ENTITIES_PATH;
-    public static final String BROOKLYN_TEST_OSGI_ENTITIES_URL = "classpath:"+OsgiTestResources.BROOKLYN_TEST_OSGI_ENTITIES_PATH;
-
-    public static final String BROOKLYN_TEST_MORE_ENTITIES_V1_PATH = OsgiTestResources.BROOKLYN_TEST_MORE_ENTITIES_V1_PATH;
-    public static final String BROOKLYN_TEST_MORE_ENTITIES_V1_URL = "classpath:"+BROOKLYN_TEST_MORE_ENTITIES_V1_PATH;
-    public static final String BROOKLYN_TEST_MORE_ENTITIES_V2_PATH = OsgiTestResources.BROOKLYN_TEST_MORE_ENTITIES_V2_PATH;
-    public static final String BROOKLYN_TEST_MORE_ENTITIES_V2_URL = "classpath:"+BROOKLYN_TEST_MORE_ENTITIES_V2_PATH;
-    public static final String BROOKLYN_TEST_MORE_ENTITIES_V2_EVIL_TWIN_PATH = OsgiTestResources.BROOKLYN_TEST_MORE_ENTITIES_V2_EVIL_TWIN_PATH;
-    public static final String BROOKLYN_TEST_MORE_ENTITIES_V2_EVIL_TWIN_URL = "classpath:"+BROOKLYN_TEST_MORE_ENTITIES_V2_EVIL_TWIN_PATH;
-    
-    public static final String TEST_VERSION = "0.1.0";
-
     public static final String EXPECTED_SAY_HI_BROOKLYN_RESPONSE_FROM_V1 = "Hi BROOKLYN from V1";
     public static final String EXPECTED_SAY_HI_BROOKLYN_RESPONSE_FROM_V2 = "HI BROOKLYN FROM V2";
     public static final String EXPECTED_SAY_HI_BROOKLYN_RESPONSE_FROM_V2_EVIL_TWIN = "HO BROOKLYN FROM V2 EVIL TWIN";
@@ -223,18 +206,6 @@ public class OsgiVersionMoreEntityTest {
     }
 
     @Test
-    public void testBrooklynManagedBundleInstall() throws Exception {
-        BasicManagedBundle mb = new BasicManagedBundle();
-        Bundle b = ((ManagementContextInternal)mgmt).getOsgiManager().get().installUploadedBundle(mb, 
-            new ResourceUtils(getClass()).getResourceFromUrl(BROOKLYN_TEST_MORE_ENTITIES_V1_URL));
-        Assert.assertEquals(mb.getSymbolicName(), b.getSymbolicName());
-        
-        Map<String, ManagedBundle> bundles = ((ManagementContextInternal)mgmt).getOsgiManager().get().getManagedBundles();
-        Asserts.assertSize(bundles.keySet(), 1);
-        Assert.assertEquals(mb.getId(), Iterables.getOnlyElement( bundles.keySet() ));
-    }
-    
-    @Test
     public void testMoreEntitiesV1() throws Exception {
         TestResourceUnavailableException.throwIfResourceUnavailable(getClass(), BROOKLYN_TEST_MORE_ENTITIES_V1_PATH);
 

http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/abd0cb8b/core/src/test/java/org/apache/brooklyn/core/mgmt/persist/BrooklynMementoPersisterTestFixture.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/core/mgmt/persist/BrooklynMementoPersisterTestFixture.java b/core/src/test/java/org/apache/brooklyn/core/mgmt/persist/BrooklynMementoPersisterTestFixture.java
index 6f6d363..75dd95b 100644
--- a/core/src/test/java/org/apache/brooklyn/core/mgmt/persist/BrooklynMementoPersisterTestFixture.java
+++ b/core/src/test/java/org/apache/brooklyn/core/mgmt/persist/BrooklynMementoPersisterTestFixture.java
@@ -38,8 +38,6 @@ import org.apache.brooklyn.api.policy.PolicySpec;
 import org.apache.brooklyn.api.sensor.Enricher;
 import org.apache.brooklyn.core.entity.Entities;
 import org.apache.brooklyn.core.entity.factory.ApplicationBuilder;
-import org.apache.brooklyn.core.mgmt.persist.BrooklynMementoPersisterToObjectStore;
-import org.apache.brooklyn.core.mgmt.persist.PersistenceObjectStore;
 import org.apache.brooklyn.core.mgmt.rebind.PersistenceExceptionHandlerImpl;
 import org.apache.brooklyn.core.mgmt.rebind.RebindContextImpl;
 import org.apache.brooklyn.core.mgmt.rebind.RebindTestUtils;
@@ -48,11 +46,11 @@ import org.apache.brooklyn.core.test.entity.TestApplication;
 import org.apache.brooklyn.core.test.entity.TestEntity;
 import org.apache.brooklyn.core.test.policy.TestPolicy;
 import org.apache.brooklyn.enricher.stock.Enrichers;
+import org.apache.brooklyn.location.ssh.SshMachineLocation;
 import org.testng.SkipException;
 import org.testng.annotations.AfterMethod;
 import org.testng.annotations.BeforeMethod;
 import org.testng.annotations.Test;
-import org.apache.brooklyn.location.ssh.SshMachineLocation;
 
 import com.google.common.collect.Iterables;
 

http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/abd0cb8b/core/src/test/java/org/apache/brooklyn/core/mgmt/persist/InMemoryObjectStore.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/core/mgmt/persist/InMemoryObjectStore.java b/core/src/test/java/org/apache/brooklyn/core/mgmt/persist/InMemoryObjectStore.java
index c842fd1..3f05e5e 100644
--- a/core/src/test/java/org/apache/brooklyn/core/mgmt/persist/InMemoryObjectStore.java
+++ b/core/src/test/java/org/apache/brooklyn/core/mgmt/persist/InMemoryObjectStore.java
@@ -18,35 +18,36 @@
  */
 package org.apache.brooklyn.core.mgmt.persist;
 
+import java.io.IOException;
 import java.util.Date;
 import java.util.List;
 import java.util.Map;
 
 import org.apache.brooklyn.api.mgmt.ManagementContext;
 import org.apache.brooklyn.api.mgmt.ha.HighAvailabilityMode;
-import org.apache.brooklyn.core.mgmt.persist.PersistMode;
-import org.apache.brooklyn.core.mgmt.persist.PersistenceObjectStore;
-import org.apache.brooklyn.core.mgmt.persist.StoreObjectAccessorLocking;
 import org.apache.brooklyn.util.collections.MutableList;
 import org.apache.brooklyn.util.collections.MutableMap;
+import org.apache.brooklyn.util.exceptions.Exceptions;
+import org.apache.brooklyn.util.stream.Streams;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import com.google.common.base.Objects;
+import com.google.common.base.MoreObjects;
+import com.google.common.io.ByteSource;
 
 public class InMemoryObjectStore implements PersistenceObjectStore {
 
     private static final Logger log = LoggerFactory.getLogger(InMemoryObjectStore.class);
 
-    final Map<String,String> filesByName;
+    final Map<String,byte[]> filesByName;
     final Map<String, Date> fileModTimesByName;
     boolean prepared = false;
     
     public InMemoryObjectStore() {
-        this(MutableMap.<String,String>of(), MutableMap.<String,Date>of());
+        this(MutableMap.<String,byte[]>of(), MutableMap.<String,Date>of());
     }
     
-    public InMemoryObjectStore(Map<String,String> map, Map<String, Date> fileModTimesByName) {
+    public InMemoryObjectStore(Map<String,byte[]> map, Map<String, Date> fileModTimesByName) {
         filesByName = map;
         this.fileModTimesByName = fileModTimesByName;
         log.debug("Using memory-based objectStore");
@@ -72,24 +73,26 @@ public class InMemoryObjectStore implements PersistenceObjectStore {
     }
     
     public static class SingleThreadedInMemoryStoreObjectAccessor implements StoreObjectAccessor {
-        private final Map<String, String> map;
+        private final Map<String, byte[]> map;
         private final Map<String, Date> mapModTime;
         private final String key;
 
-        public SingleThreadedInMemoryStoreObjectAccessor(Map<String,String> map, Map<String, Date> mapModTime, String key) {
+        public SingleThreadedInMemoryStoreObjectAccessor(Map<String,byte[]> map, Map<String, Date> mapModTime, String key) {
             this.map = map;
             this.mapModTime = mapModTime;
             this.key = key;
         }
         @Override
         public String get() {
-            synchronized (map) {
-                return map.get(key);
-            }
+            byte[] b = getBytes();
+            if (b==null) return null;
+            return new String(b);
         }
         @Override
         public byte[] getBytes() {
-            return get().getBytes();
+            synchronized (map) {
+                return map.get(key);
+            }
         }
         @Override
         public boolean exists() {
@@ -99,9 +102,17 @@ public class InMemoryObjectStore implements PersistenceObjectStore {
         }
         @Override
         public void put(String val) {
-            synchronized (map) {
-                map.put(key, val);
-                mapModTime.put(key, new Date());
+            put(ByteSource.wrap(val.getBytes()));
+        }
+        @Override
+        public void put(ByteSource bytes) {
+            try {
+                synchronized (map) {
+                    map.put(key, Streams.readFullyAndClose(bytes.openStream()));
+                    mapModTime.put(key, new Date());
+                }
+            } catch (IOException e) {
+                throw Exceptions.propagate(e);
             }
         }
         @Override
@@ -111,7 +122,7 @@ public class InMemoryObjectStore implements PersistenceObjectStore {
                 if (val2==null) val2 = val;
                 else val2 = val2 + val;
 
-                map.put(key, val2);
+                put(val2);
                 mapModTime.put(key, new Date());
             }
         }
@@ -148,7 +159,7 @@ public class InMemoryObjectStore implements PersistenceObjectStore {
 
     @Override
     public String toString() {
-        return Objects.toStringHelper(this).add("size", filesByName.size()).toString();
+        return MoreObjects.toStringHelper(this).add("size", filesByName.size()).toString();
     }
 
     @Override

http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/abd0cb8b/core/src/test/java/org/apache/brooklyn/core/mgmt/persist/ListeningObjectStore.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/core/mgmt/persist/ListeningObjectStore.java b/core/src/test/java/org/apache/brooklyn/core/mgmt/persist/ListeningObjectStore.java
index 436638d..5bf6a76 100644
--- a/core/src/test/java/org/apache/brooklyn/core/mgmt/persist/ListeningObjectStore.java
+++ b/core/src/test/java/org/apache/brooklyn/core/mgmt/persist/ListeningObjectStore.java
@@ -18,6 +18,7 @@
  */
 package org.apache.brooklyn.core.mgmt.persist;
 
+import java.io.IOException;
 import java.util.Date;
 import java.util.List;
 import java.util.concurrent.TimeoutException;
@@ -27,6 +28,8 @@ import java.util.concurrent.atomic.AtomicLong;
 import org.apache.brooklyn.api.mgmt.ManagementContext;
 import org.apache.brooklyn.api.mgmt.ha.HighAvailabilityMode;
 import org.apache.brooklyn.util.collections.MutableList;
+import org.apache.brooklyn.util.exceptions.Exceptions;
+import org.apache.brooklyn.util.stream.Streams;
 import org.apache.brooklyn.util.text.Strings;
 import org.apache.brooklyn.util.time.CountdownTimer;
 import org.apache.brooklyn.util.time.Duration;
@@ -34,6 +37,7 @@ import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 import com.google.common.base.Preconditions;
+import com.google.common.io.ByteSource;
 
 public class ListeningObjectStore implements PersistenceObjectStore {
 
@@ -209,6 +213,20 @@ public class ListeningObjectStore implements PersistenceObjectStore {
             delegate.put(val);
         }
         @Override
+        public void put(ByteSource val) {
+            if (writesFailSilently)
+                return;
+
+            for (ObjectStoreTransactionListener listener: listeners) {
+                try {
+                    listener.recordDataOut("writing (binary) "+path, Streams.readFullyAndClose(val.openStream()).length);
+                } catch (IOException e) {
+                    throw Exceptions.propagate(e);
+                }
+            }
+            delegate.put(val);
+        }
+        @Override
         public void append(String s) {
             if (writesFailSilently)
                 return;

http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/abd0cb8b/core/src/test/java/org/apache/brooklyn/core/mgmt/persist/XmlMementoSerializerTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/core/mgmt/persist/XmlMementoSerializerTest.java b/core/src/test/java/org/apache/brooklyn/core/mgmt/persist/XmlMementoSerializerTest.java
index ed07b07..e8bc120 100644
--- a/core/src/test/java/org/apache/brooklyn/core/mgmt/persist/XmlMementoSerializerTest.java
+++ b/core/src/test/java/org/apache/brooklyn/core/mgmt/persist/XmlMementoSerializerTest.java
@@ -47,6 +47,7 @@ import org.apache.brooklyn.api.policy.Policy;
 import org.apache.brooklyn.api.sensor.AttributeSensor;
 import org.apache.brooklyn.api.sensor.Enricher;
 import org.apache.brooklyn.api.sensor.Feed;
+import org.apache.brooklyn.api.typereg.ManagedBundle;
 import org.apache.brooklyn.api.typereg.RegisteredType;
 import org.apache.brooklyn.config.ConfigInheritance;
 import org.apache.brooklyn.core.catalog.internal.CatalogItemBuilder;
@@ -84,6 +85,7 @@ import org.testng.annotations.AfterMethod;
 import org.testng.annotations.BeforeMethod;
 import org.testng.annotations.Test;
 
+import com.google.common.annotations.VisibleForTesting;
 import com.google.common.base.Joiner;
 import com.google.common.base.Objects;
 import com.google.common.base.Predicate;
@@ -292,24 +294,26 @@ public class XmlMementoSerializerTest {
         final TestApplication app = TestApplication.Factory.newManagedInstanceForTests();
         ManagementContext managementContext = app.getManagementContext();
         try {
-            serializer.setLookupContext(new LookupContextImpl(managementContext,
-                    ImmutableList.of(app), ImmutableList.<Location>of(), ImmutableList.<Policy>of(),
-                    ImmutableList.<Enricher>of(), ImmutableList.<Feed>of(), ImmutableList.<CatalogItem<?, ?>>of(), true));
+            serializer.setLookupContext(newEmptyLookupManagementContext(managementContext, true).add(app));
             assertSerializeAndDeserialize(app);
         } finally {
             Entities.destroyAll(managementContext);
         }
     }
 
+    private LookupContextImpl newEmptyLookupManagementContext(ManagementContext managementContext, boolean failOnDangling) {
+        return new LookupContextImpl(managementContext,
+                ImmutableList.<Entity>of(), ImmutableList.<Location>of(), ImmutableList.<Policy>of(),
+                ImmutableList.<Enricher>of(), ImmutableList.<Feed>of(), ImmutableList.<CatalogItem<?, ?>>of(), ImmutableList.<ManagedBundle>of(), failOnDangling);
+    }
+
     @Test
     public void testLocation() throws Exception {
         final TestApplication app = TestApplication.Factory.newManagedInstanceForTests();
         ManagementContext managementContext = app.getManagementContext();
         try {
             final Location loc = managementContext.getLocationManager().createLocation(LocationSpec.create(SimulatedLocation.class));
-            serializer.setLookupContext(new LookupContextImpl(managementContext,
-                    ImmutableList.<Entity>of(), ImmutableList.of(loc), ImmutableList.<Policy>of(),
-                    ImmutableList.<Enricher>of(), ImmutableList.<Feed>of(), ImmutableList.<CatalogItem<?, ?>>of(), true));
+            serializer.setLookupContext(newEmptyLookupManagementContext(managementContext, true).add(loc));
             assertSerializeAndDeserialize(loc);
         } finally {
             Entities.destroyAll(managementContext);
@@ -328,9 +332,7 @@ public class XmlMementoSerializerTest {
                     .iconUrl("iconUrl")
                     .libraries(CatalogItemDtoAbstract.parseLibraries(ImmutableList.of("library-url")))
                     .build();
-            serializer.setLookupContext(new LookupContextImpl(managementContext,
-                    ImmutableList.<Entity>of(), ImmutableList.<Location>of(), ImmutableList.<Policy>of(),
-                    ImmutableList.<Enricher>of(), ImmutableList.<Feed>of(), ImmutableList.of(catalogItem), true));
+            serializer.setLookupContext(newEmptyLookupManagementContext(managementContext, true).add(catalogItem));
             assertSerializeAndDeserialize(catalogItem);
         } finally {
             Entities.destroyAll(managementContext);
@@ -381,10 +383,8 @@ public class XmlMementoSerializerTest {
         EntitySpec<DynamicCluster> spec = EntitySpec.create(DynamicCluster.class)
             .configure(DynamicCluster.INITIAL_SIZE, 1)
             .configure(DynamicCluster.MEMBER_SPEC, mgmt.getTypeRegistry().createSpec(ci, null, EntitySpec.class));
-
-        serializer.setLookupContext(new LookupContextImpl(mgmt,
-            ImmutableList.<Entity>of(), ImmutableList.<Location>of(), ImmutableList.<Policy>of(),
-            ImmutableList.<Enricher>of(), ImmutableList.<Feed>of(), ImmutableList.<CatalogItem<?,?>>of(), true));
+        
+        serializer.setLookupContext(newEmptyLookupManagementContext(mgmt, true));
         assertSerializeAndDeserialize(spec);
     }
     
@@ -392,9 +392,7 @@ public class XmlMementoSerializerTest {
     public void testOsgiBundleNameNotIncludedForWhiteListed() throws Exception {
         mgmt = LocalManagementContextForTests.builder(true).disableOsgi(false).build();
 
-        serializer.setLookupContext(new LookupContextImpl(mgmt,
-            ImmutableList.<Entity>of(), ImmutableList.<Location>of(), ImmutableList.<Policy>of(),
-            ImmutableList.<Enricher>of(), ImmutableList.<Feed>of(), ImmutableList.<CatalogItem<?,?>>of(), true));
+        serializer.setLookupContext(newEmptyLookupManagementContext(mgmt, true));
         
         Object obj = PersistMode.AUTO;
         
@@ -413,10 +411,7 @@ public class XmlMementoSerializerTest {
         TestResourceUnavailableException.throwIfResourceUnavailable(getClass(), bundlePath);
         
         mgmt = LocalManagementContextForTests.builder(true).disableOsgi(false).build();
-
-        serializer.setLookupContext(new LookupContextImpl(mgmt,
-                ImmutableList.<Entity>of(), ImmutableList.<Location>of(), ImmutableList.<Policy>of(),
-                ImmutableList.<Enricher>of(), ImmutableList.<Feed>of(), ImmutableList.<CatalogItem<?,?>>of(), true));
+        serializer.setLookupContext(newEmptyLookupManagementContext(mgmt, true));
         
         Bundle bundle = installBundle(mgmt, bundleUrl);
         
@@ -464,9 +459,7 @@ public class XmlMementoSerializerTest {
         serializer = new XmlMementoSerializer<Object>(mgmt.getCatalogClassLoader(),
                 ImmutableMap.<String,String>of());
         
-        serializer.setLookupContext(new LookupContextImpl(mgmt,
-                ImmutableList.<Entity>of(), ImmutableList.<Location>of(), ImmutableList.<Policy>of(),
-                ImmutableList.<Enricher>of(), ImmutableList.<Feed>of(), ImmutableList.<CatalogItem<?,?>>of(), true));
+        serializer.setLookupContext(newEmptyLookupManagementContext(mgmt, true));
 
         // i.e. prepended with bundle name
         String serializedForm = Joiner.on("\n").join(
@@ -496,9 +489,7 @@ public class XmlMementoSerializerTest {
         serializer = new XmlMementoSerializer<Object>(mgmt.getCatalogClassLoader(),
                 ImmutableMap.of(oldBundlePrefix + ":" + classname, bundlePrefix + ":" + classname));
         
-        serializer.setLookupContext(new LookupContextImpl(mgmt,
-                ImmutableList.<Entity>of(), ImmutableList.<Location>of(), ImmutableList.<Policy>of(),
-                ImmutableList.<Enricher>of(), ImmutableList.<Feed>of(), ImmutableList.<CatalogItem<?,?>>of(), true));
+        serializer.setLookupContext(newEmptyLookupManagementContext(mgmt, true));
 
         // i.e. prepended with bundle name
         String serializedForm = Joiner.on("\n").join(
@@ -528,10 +519,7 @@ public class XmlMementoSerializerTest {
 
         serializer = new XmlMementoSerializer<Object>(mgmt.getCatalogClassLoader(),
                 ImmutableMap.of(oldClassname, classname));
-        
-        serializer.setLookupContext(new LookupContextImpl(mgmt,
-                ImmutableList.<Entity>of(), ImmutableList.<Location>of(), ImmutableList.<Policy>of(),
-                ImmutableList.<Enricher>of(), ImmutableList.<Feed>of(), ImmutableList.<CatalogItem<?,?>>of(), true));
+        serializer.setLookupContext(newEmptyLookupManagementContext(mgmt, true));
 
         // i.e. prepended with bundle name
         String serializedForm = Joiner.on("\n").join(
@@ -548,10 +536,7 @@ public class XmlMementoSerializerTest {
     @Test(groups="Broken")
     public void testOsgiBundleNamePrefixIncludedForDownstreamDependency() throws Exception {
         mgmt = LocalManagementContextForTests.builder(true).disableOsgi(false).build();
-
-        serializer.setLookupContext(new LookupContextImpl(mgmt,
-                ImmutableList.<Entity>of(), ImmutableList.<Location>of(), ImmutableList.<Policy>of(),
-                ImmutableList.<Enricher>of(), ImmutableList.<Feed>of(), ImmutableList.<CatalogItem<?,?>>of(), true));
+        serializer.setLookupContext(newEmptyLookupManagementContext(mgmt, true));
         
         // Using a guava type (which is a downstream dependency of Brooklyn)
         String bundleName = "com.goole.guava";
@@ -575,9 +560,7 @@ public class XmlMementoSerializerTest {
         final TestEntity entity = app.createAndManageChild(EntitySpec.create(TestEntity.class));
         ManagementContext managementContext = app.getManagementContext();
         try {
-            serializer.setLookupContext(new LookupContextImpl(managementContext,
-                    ImmutableList.of(app), ImmutableList.<Location>of(), ImmutableList.<Policy>of(),
-                    ImmutableList.<Enricher>of(), ImmutableList.<Feed>of(), ImmutableList.<CatalogItem<?, ?>>of(), false));
+            serializer.setLookupContext(newEmptyLookupManagementContext(managementContext, false).add(app));
             
             List<?> resultList = serializeAndDeserialize(ImmutableList.of(app, entity));
             assertEquals(resultList, ImmutableList.of(app));
@@ -599,9 +582,7 @@ public class XmlMementoSerializerTest {
         ReffingEntity reffer = new ReffingEntity(app);
         ManagementContext managementContext = app.getManagementContext();
         try {
-            serializer.setLookupContext(new LookupContextImpl(managementContext,
-                    ImmutableList.of(app), ImmutableList.<Location>of(), ImmutableList.<Policy>of(),
-                    ImmutableList.<Enricher>of(), ImmutableList.<Feed>of(), ImmutableList.<CatalogItem<?, ?>>of(), true));
+            serializer.setLookupContext(newEmptyLookupManagementContext(managementContext, true).add(app));
             ReffingEntity reffer2 = assertSerializeAndDeserialize(reffer);
             assertEquals(reffer2.entity, app);
         } finally {
@@ -615,9 +596,7 @@ public class XmlMementoSerializerTest {
         ReffingEntity reffer = new ReffingEntity((Object)app);
         ManagementContext managementContext = app.getManagementContext();
         try {
-            serializer.setLookupContext(new LookupContextImpl(managementContext,
-                    ImmutableList.of(app), ImmutableList.<Location>of(), ImmutableList.<Policy>of(),
-                    ImmutableList.<Enricher>of(), ImmutableList.<Feed>of(), ImmutableList.<CatalogItem<?, ?>>of(), true));
+            serializer.setLookupContext(newEmptyLookupManagementContext(managementContext, true).add(app));
             ReffingEntity reffer2 = assertSerializeAndDeserialize(reffer);
             assertEquals(reffer2.obj, app);
         } finally {
@@ -685,7 +664,7 @@ public class XmlMementoSerializerTest {
         LOG.info("serializedForm=" + serializedForm);
         return (T) serializer.fromString(serializedForm);
     }
-
+    
     static class LookupContextImpl implements LookupContext {
         private final ManagementContext mgmt;
         private final Map<String, Entity> entities;
@@ -694,11 +673,13 @@ public class XmlMementoSerializerTest {
         private final Map<String, Enricher> enrichers;
         private final Map<String, Feed> feeds;
         private final Map<String, CatalogItem<?, ?>> catalogItems;
+        private final Map<String, ManagedBundle> bundles;
         private final boolean failOnDangling;
 
         LookupContextImpl(ManagementContext mgmt, Iterable<? extends Entity> entities, Iterable<? extends Location> locations,
                 Iterable<? extends Policy> policies, Iterable<? extends Enricher> enrichers, Iterable<? extends Feed> feeds,
-                Iterable<? extends CatalogItem<?, ?>> catalogItems, boolean failOnDangling) {
+                Iterable<? extends CatalogItem<?, ?>> catalogItems, Iterable<? extends ManagedBundle> bundles,
+                    boolean failOnDangling) {
             this.mgmt = mgmt;
             this.entities = Maps.newLinkedHashMap();
             this.locations = Maps.newLinkedHashMap();
@@ -706,17 +687,20 @@ public class XmlMementoSerializerTest {
             this.enrichers = Maps.newLinkedHashMap();
             this.feeds = Maps.newLinkedHashMap();
             this.catalogItems = Maps.newLinkedHashMap();
+            this.bundles = Maps.newLinkedHashMap();
             for (Entity entity : entities) this.entities.put(entity.getId(), entity);
             for (Location location : locations) this.locations.put(location.getId(), location);
             for (Policy policy : policies) this.policies.put(policy.getId(), policy);
             for (Enricher enricher : enrichers) this.enrichers.put(enricher.getId(), enricher);
             for (Feed feed : feeds) this.feeds.put(feed.getId(), feed);
             for (CatalogItem<?, ?> catalogItem : catalogItems) this.catalogItems.put(catalogItem.getId(), catalogItem);
+            for (ManagedBundle bundle : bundles) this.bundles.put(bundle.getId(), bundle);
             this.failOnDangling = failOnDangling;
         }
         LookupContextImpl(ManagementContext mgmt, Map<String,? extends Entity> entities, Map<String,? extends Location> locations,
                 Map<String,? extends Policy> policies, Map<String,? extends Enricher> enrichers, Map<String,? extends Feed> feeds,
-                Map<String, ? extends CatalogItem<?, ?>> catalogItems, boolean failOnDangling) {
+                Map<String, ? extends CatalogItem<?, ?>> catalogItems, Map<String,? extends ManagedBundle> bundles,
+                boolean failOnDangling) {
             this.mgmt = mgmt;
             this.entities = ImmutableMap.copyOf(entities);
             this.locations = ImmutableMap.copyOf(locations);
@@ -724,6 +708,7 @@ public class XmlMementoSerializerTest {
             this.enrichers = ImmutableMap.copyOf(enrichers);
             this.feeds = ImmutableMap.copyOf(feeds);
             this.catalogItems = ImmutableMap.copyOf(catalogItems);
+            this.bundles = ImmutableMap.copyOf(bundles);
             this.failOnDangling = failOnDangling;
         }
         @Override public ManagementContext lookupManagementContext() {
@@ -783,6 +768,15 @@ public class XmlMementoSerializerTest {
             }
             return null;
         }
+        @Override public ManagedBundle lookupBundle(String id) {
+            if (bundles.containsKey(id)) {
+                return bundles.get(id);
+            }
+            if (failOnDangling) {
+                throw new NoSuchElementException("no bundle with id "+id+"; contenders are "+bundles.keySet());
+            }
+            return null;
+        }
         
         @Override
         public BrooklynObject lookup(BrooklynObjectType type, String id) {
@@ -798,6 +792,7 @@ public class XmlMementoSerializerTest {
             
             switch (type) {
             case CATALOG_ITEM: return lookupCatalogItem(id);
+            case MANAGED_BUNDLE: return lookupBundle(id);
             case ENRICHER: return lookupEnricher(id);
             case ENTITY: return lookupEntity(id);
             case FEED: return lookupFeed(id);
@@ -807,6 +802,21 @@ public class XmlMementoSerializerTest {
             }
             throw new IllegalStateException("Unexpected type "+type+" / id "+id);
         }
+        
+        private Map<String,? extends BrooklynObject> getMapFor(BrooklynObjectType type) {
+            switch (type) {
+            case CATALOG_ITEM: return catalogItems;
+            case MANAGED_BUNDLE: return bundles;
+            case ENRICHER: return enrichers;
+            case ENTITY: return entities;
+            case FEED: return feeds;
+            case LOCATION: return locations;
+            case POLICY: return policies;
+            case UNKNOWN: return null;
+            }
+            throw new IllegalStateException("Unexpected type "+type);
+        }
+        
         @Override
         public BrooklynObject peek(BrooklynObjectType type, String id) {
             if (type==null) {
@@ -817,16 +827,18 @@ public class XmlMementoSerializerTest {
                 return null;
             }
             
-            switch (type) {
-            case CATALOG_ITEM: return catalogItems.get(id);
-            case ENRICHER: return enrichers.get(id);
-            case ENTITY: return entities.get(id);
-            case FEED: return feeds.get(id);
-            case LOCATION: return locations.get(id);
-            case POLICY: return policies.get(id);
-            case UNKNOWN: return null;
+            Map<String, ? extends BrooklynObject> map = getMapFor(type);
+            if (map==null) return null;
+            return map.get(id);
+        }
+        
+        @SuppressWarnings("unchecked")
+        @VisibleForTesting
+        public LookupContextImpl add(BrooklynObject object) {
+            if (object!=null) {
+                ((Map<String,BrooklynObject>) getMapFor(BrooklynObjectType.of(object))).put(object.getId(), object);
             }
-            throw new IllegalStateException("Unexpected type "+type+" / id "+id);
+            return this;
         }
     };
 

http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/abd0cb8b/core/src/test/java/org/apache/brooklyn/core/mgmt/rebind/ManagementPlaneIdTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/core/mgmt/rebind/ManagementPlaneIdTest.java b/core/src/test/java/org/apache/brooklyn/core/mgmt/rebind/ManagementPlaneIdTest.java
index 22a2371..0fbadff 100644
--- a/core/src/test/java/org/apache/brooklyn/core/mgmt/rebind/ManagementPlaneIdTest.java
+++ b/core/src/test/java/org/apache/brooklyn/core/mgmt/rebind/ManagementPlaneIdTest.java
@@ -76,7 +76,7 @@ public class ManagementPlaneIdTest {
     @Test
     public void testUninitializedThrows() {
         ManagementContext mgmt = new LocalManagementContext(BrooklynProperties.Factory.newEmpty());
-        assertFalse(mgmt.getOptionalManagementPlaneId().isPresent(), "expected managementPlaneId to be absent");
+        assertFalse(mgmt.getManagementPlaneIdMaybe().isPresent(), "expected managementPlaneId to be absent");
     }
     
     @Test
@@ -90,13 +90,13 @@ public class ManagementPlaneIdTest {
         final LocalManagementContext mgmt = createManagementContext(PersistMode.AUTO, HighAvailabilityMode.AUTO);
 
         checkPlaneIdPersisted(mgmt);
-        final String oldPlaneId = mgmt.getOptionalManagementPlaneId().get();
+        final String oldPlaneId = mgmt.getManagementPlaneIdMaybe().get();
         mgmt.setManagementPlaneId(Strings.makeRandomId(8));
-        assertNotEquals(oldPlaneId, mgmt.getOptionalManagementPlaneId().get());
+        assertNotEquals(oldPlaneId, mgmt.getManagementPlaneIdMaybe().get());
         Asserts.succeedsEventually(new Runnable() {
             @Override
             public void run() {
-                assertEquals(oldPlaneId, mgmt.getOptionalManagementPlaneId().get());
+                assertEquals(oldPlaneId, mgmt.getManagementPlaneIdMaybe().get());
             }
         });
     }
@@ -109,7 +109,7 @@ public class ManagementPlaneIdTest {
 
         LocalManagementContext rebindMgmt = createManagementContext(PersistMode.AUTO, HighAvailabilityMode.DISABLED);
 
-        assertEquals(origMgmt.getOptionalManagementPlaneId(), rebindMgmt.getOptionalManagementPlaneId());
+        assertEquals(origMgmt.getManagementPlaneIdMaybe(), rebindMgmt.getManagementPlaneIdMaybe());
     }
 
 
@@ -131,7 +131,7 @@ public class ManagementPlaneIdTest {
         Asserts.succeedsEventually(new Runnable() {
             @Override
             public void run() {
-                assertEquals(origMgmt.getOptionalManagementPlaneId(), rebindMgmt.getOptionalManagementPlaneId());
+                assertEquals(origMgmt.getManagementPlaneIdMaybe(), rebindMgmt.getManagementPlaneIdMaybe());
             }
         });
     }
@@ -144,7 +144,7 @@ public class ManagementPlaneIdTest {
         Asserts.succeedsEventually(new Runnable() {
             @Override
             public void run() {
-                assertEquals(origMgmt.getOptionalManagementPlaneId(), rebindMgmt.getOptionalManagementPlaneId());
+                assertEquals(origMgmt.getManagementPlaneIdMaybe(), rebindMgmt.getManagementPlaneIdMaybe());
             }
         });
 
@@ -160,7 +160,7 @@ public class ManagementPlaneIdTest {
             }
         });
 
-        assertEquals(origMgmt.getOptionalManagementPlaneId(), rebindMgmt.getOptionalManagementPlaneId());
+        assertEquals(origMgmt.getManagementPlaneIdMaybe(), rebindMgmt.getManagementPlaneIdMaybe());
     }
     
     @Test
@@ -171,7 +171,7 @@ public class ManagementPlaneIdTest {
 
         LocalManagementContext rebindMgmt = createManagementContextWithBackups(PersistMode.AUTO, HighAvailabilityMode.AUTO);
 
-        assertEquals(origMgmt.getOptionalManagementPlaneId(), rebindMgmt.getOptionalManagementPlaneId());
+        assertEquals(origMgmt.getManagementPlaneIdMaybe(), rebindMgmt.getManagementPlaneIdMaybe());
 
         String backupContainer = BrooklynServerPaths.newBackupPersistencePathResolver(rebindMgmt).resolve();
         
@@ -186,7 +186,7 @@ public class ManagementPlaneIdTest {
         
         File planeIdFile = new File(promotionFolders[0], BrooklynMementoPersisterToObjectStore.PLANE_ID_FILE_NAME);
         String planeId = readFile(planeIdFile);
-        assertEquals(origMgmt.getOptionalManagementPlaneId().get(), planeId);
+        assertEquals(origMgmt.getManagementPlaneIdMaybe().get(), planeId);
     }
     
     @Test
@@ -235,7 +235,7 @@ public class ManagementPlaneIdTest {
             @Override
             public Void call() throws Exception {
                 String planeId = readFile(planeIdFile);
-                assertEquals(mgmt.getOptionalManagementPlaneId().get(), planeId);
+                assertEquals(mgmt.getManagementPlaneIdMaybe().get(), planeId);
                 return null;
             }
         });

http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/abd0cb8b/core/src/test/java/org/apache/brooklyn/core/mgmt/rebind/RebindTestFixture.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/core/mgmt/rebind/RebindTestFixture.java b/core/src/test/java/org/apache/brooklyn/core/mgmt/rebind/RebindTestFixture.java
index 4ede973..4c63cb1 100644
--- a/core/src/test/java/org/apache/brooklyn/core/mgmt/rebind/RebindTestFixture.java
+++ b/core/src/test/java/org/apache/brooklyn/core/mgmt/rebind/RebindTestFixture.java
@@ -43,7 +43,6 @@ import org.apache.brooklyn.core.entity.StartableApplication;
 import org.apache.brooklyn.core.entity.trait.Startable;
 import org.apache.brooklyn.core.internal.BrooklynProperties;
 import org.apache.brooklyn.core.mgmt.internal.LocalManagementContext;
-import org.apache.brooklyn.core.mgmt.internal.ManagementContextInternal;
 import org.apache.brooklyn.core.mgmt.persist.BrooklynMementoPersisterToObjectStore;
 import org.apache.brooklyn.core.mgmt.persist.FileBasedObjectStore;
 import org.apache.brooklyn.core.mgmt.persist.PersistMode;

http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/abd0cb8b/core/src/test/java/org/apache/brooklyn/core/mgmt/rebind/transformer/CompoundTransformerTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/core/mgmt/rebind/transformer/CompoundTransformerTest.java b/core/src/test/java/org/apache/brooklyn/core/mgmt/rebind/transformer/CompoundTransformerTest.java
index 02dfadb..9f8e582 100644
--- a/core/src/test/java/org/apache/brooklyn/core/mgmt/rebind/transformer/CompoundTransformerTest.java
+++ b/core/src/test/java/org/apache/brooklyn/core/mgmt/rebind/transformer/CompoundTransformerTest.java
@@ -169,7 +169,7 @@ public class CompoundTransformerTest extends RebindTestFixtureWithApp {
 
         // Assert has expected config/fields
         assertEquals(newApp.getId(), origApp.getId());
-        assertEquals(origManagementContext.getOptionalManagementPlaneId(), newManagementContext.getOptionalManagementPlaneId());
+        assertEquals(origManagementContext.getManagementPlaneIdMaybe(), newManagementContext.getManagementPlaneIdMaybe());
     }
     
     @Test

http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/abd0cb8b/core/src/test/java/org/apache/brooklyn/core/plan/XmlPlanToSpecTransformer.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/core/plan/XmlPlanToSpecTransformer.java b/core/src/test/java/org/apache/brooklyn/core/plan/XmlPlanToSpecTransformer.java
index 41b0ff9..404d4f8 100644
--- a/core/src/test/java/org/apache/brooklyn/core/plan/XmlPlanToSpecTransformer.java
+++ b/core/src/test/java/org/apache/brooklyn/core/plan/XmlPlanToSpecTransformer.java
@@ -31,6 +31,7 @@ import org.apache.brooklyn.api.entity.EntitySpec;
 import org.apache.brooklyn.api.internal.AbstractBrooklynObjectSpec;
 import org.apache.brooklyn.api.mgmt.ManagementContext;
 import org.apache.brooklyn.core.mgmt.EntityManagementUtils;
+import org.apache.brooklyn.core.typereg.UnsupportedTypePlanException;
 import org.apache.brooklyn.entity.stock.BasicApplication;
 import org.apache.brooklyn.entity.stock.BasicEntity;
 import org.apache.brooklyn.util.exceptions.Exceptions;
@@ -79,14 +80,14 @@ public class XmlPlanToSpecTransformer implements PlanToSpecTransformer {
     @SuppressWarnings({ "unchecked" })
     @Override
     public <T, SpecT extends AbstractBrooklynObjectSpec<? extends T, SpecT>> SpecT createCatalogSpec(CatalogItem<T, SpecT> item, Set<String> encounteredTypes) {
-        if (item.getPlanYaml()==null) throw new PlanNotRecognizedException("Plan is null");
+        if (item.getPlanYaml()==null) throw new UnsupportedTypePlanException("Plan is null");
         if (item.getCatalogItemType()==CatalogItemType.ENTITY) {
             return (SpecT)toEntitySpec(parseXml(item.getPlanYaml()), 1);
         }
         if (item.getCatalogItemType()==CatalogItemType.TEMPLATE) {
             return (SpecT)toEntitySpec(parseXml(item.getPlanYaml()), 0);
         }
-        throw new PlanNotRecognizedException("Type "+item.getCatalogItemType()+" not supported");
+        throw new UnsupportedTypePlanException("Type "+item.getCatalogItemType()+" not supported");
     }
 
     private Document parseXml(String plan) {
@@ -102,7 +103,7 @@ public class XmlPlanToSpecTransformer implements PlanToSpecTransformer {
             
         } catch (Exception e) {
             Exceptions.propagateIfFatal(e);
-            throw new PlanNotRecognizedException(e);
+            throw new UnsupportedTypePlanException(e);
         }
         return dom;
     }

http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/abd0cb8b/locations/jclouds/src/main/java/org/apache/brooklyn/core/mgmt/persist/jclouds/JcloudsStoreObjectAccessor.java
----------------------------------------------------------------------
diff --git a/locations/jclouds/src/main/java/org/apache/brooklyn/core/mgmt/persist/jclouds/JcloudsStoreObjectAccessor.java b/locations/jclouds/src/main/java/org/apache/brooklyn/core/mgmt/persist/jclouds/JcloudsStoreObjectAccessor.java
index bc64b84..d2af5ae 100644
--- a/locations/jclouds/src/main/java/org/apache/brooklyn/core/mgmt/persist/jclouds/JcloudsStoreObjectAccessor.java
+++ b/locations/jclouds/src/main/java/org/apache/brooklyn/core/mgmt/persist/jclouds/JcloudsStoreObjectAccessor.java
@@ -18,13 +18,12 @@
  */
 package org.apache.brooklyn.core.mgmt.persist.jclouds;
 
-import java.io.ByteArrayOutputStream;
 import java.io.IOException;
-import java.io.InputStream;
 import java.util.Date;
 
 import org.apache.brooklyn.core.mgmt.persist.PersistenceObjectStore;
 import org.apache.brooklyn.util.exceptions.Exceptions;
+import org.apache.brooklyn.util.stream.Streams;
 import org.apache.commons.io.Charsets;
 import org.jclouds.blobstore.BlobStore;
 import org.jclouds.blobstore.domain.Blob;
@@ -32,7 +31,6 @@ import org.jclouds.util.Strings2;
 
 import com.google.common.base.Throwables;
 import com.google.common.io.ByteSource;
-import com.google.common.io.ByteStreams;
 
 /**
  * @author Andrea Turli
@@ -57,11 +55,13 @@ public class JcloudsStoreObjectAccessor implements PersistenceObjectStore.StoreO
     @Override
     public void put(String val) {
         if (val==null) val = "";
-        
+        put(ByteSource.wrap(val.getBytes(Charsets.UTF_8)));
+    }
+    
+    public void put(ByteSource payload) {
         blobStore.createContainerInLocation(null, containerName);
         // seems not needed, at least not w SoftLayer
 //        blobStore.createDirectory(containerName, directoryName);
-        ByteSource payload = ByteSource.wrap(val.getBytes(Charsets.UTF_8));
         Blob blob;
         try {
             blob = blobStore.blobBuilder(blobName).payload(payload)
@@ -104,14 +104,7 @@ public class JcloudsStoreObjectAccessor implements PersistenceObjectStore.StoreO
         try {
             Blob blob = blobStore.getBlob(containerName, blobName);
             if (blob==null) return null;
-            ByteArrayOutputStream out = new ByteArrayOutputStream();
-            InputStream in = blob.getPayload().openStream();
-            try {
-                ByteStreams.copy(in, out);
-                return out.toByteArray();
-            } finally {
-                out.close();
-            }
+            return Streams.readFullyAndClose(blob.getPayload().openStream());
         } catch (IOException e) {
             Exceptions.propagateIfFatal(e);
             throw new IllegalStateException("Error reading blobstore "+containerName+" "+blobName+": "+e, e);

http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/abd0cb8b/rest/rest-resources/src/main/java/org/apache/brooklyn/rest/resources/CatalogResource.java
----------------------------------------------------------------------
diff --git a/rest/rest-resources/src/main/java/org/apache/brooklyn/rest/resources/CatalogResource.java b/rest/rest-resources/src/main/java/org/apache/brooklyn/rest/resources/CatalogResource.java
index 677b84f..24bd47e 100644
--- a/rest/rest-resources/src/main/java/org/apache/brooklyn/rest/resources/CatalogResource.java
+++ b/rest/rest-resources/src/main/java/org/apache/brooklyn/rest/resources/CatalogResource.java
@@ -47,16 +47,14 @@ import org.apache.brooklyn.api.location.LocationSpec;
 import org.apache.brooklyn.api.policy.Policy;
 import org.apache.brooklyn.api.policy.PolicySpec;
 import org.apache.brooklyn.api.typereg.RegisteredType;
-import org.apache.brooklyn.core.BrooklynFeatureEnablement;
 import org.apache.brooklyn.core.catalog.CatalogPredicates;
 import org.apache.brooklyn.core.catalog.internal.BasicBrooklynCatalog;
-import org.apache.brooklyn.core.catalog.internal.CatalogBundleLoader;
 import org.apache.brooklyn.core.catalog.internal.CatalogDto;
 import org.apache.brooklyn.core.catalog.internal.CatalogItemComparator;
 import org.apache.brooklyn.core.catalog.internal.CatalogUtils;
 import org.apache.brooklyn.core.mgmt.entitlement.Entitlements;
 import org.apache.brooklyn.core.mgmt.entitlement.Entitlements.StringAndArgument;
-import org.apache.brooklyn.core.mgmt.internal.LocalManagementContext;
+import org.apache.brooklyn.core.mgmt.internal.ManagementContextInternal;
 import org.apache.brooklyn.core.typereg.BasicManagedBundle;
 import org.apache.brooklyn.core.typereg.RegisteredTypePredicates;
 import org.apache.brooklyn.rest.api.CatalogApi;
@@ -83,7 +81,6 @@ import org.apache.brooklyn.util.yaml.Yamls;
 import org.apache.commons.compress.archivers.zip.ZipArchiveEntry;
 import org.apache.commons.compress.archivers.zip.ZipFile;
 import org.osgi.framework.Bundle;
-import org.osgi.framework.BundleException;
 import org.osgi.framework.Constants;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -232,39 +229,14 @@ public class CatalogResource extends AbstractBrooklynRestResource implements Cat
             BasicManagedBundle bundleMetadata = new BasicManagedBundle(bundleNameInMF, bundleVersionInMF, null);
             Bundle bundle;
             try (FileInputStream f2in = new FileInputStream(f2)) {
-                bundle =
-                    ((LocalManagementContext)mgmt()).getOsgiManager().get().installUploadedBundle(bundleMetadata, f2in);
+                bundle = ((ManagementContextInternal)mgmt()).getOsgiManager().get().installUploadedBundle(bundleMetadata, f2in, false);
             } catch (Exception e) {
                 throw Exceptions.propagate(e);
             }
 
-            Iterable<? extends CatalogItem<?, ?>> catalogItems = MutableList.of();
-            
-            if (!BrooklynFeatureEnablement.isEnabled(BrooklynFeatureEnablement.FEATURE_LOAD_BUNDLE_CATALOG_BOM)) {
-                // if the above feature is not enabled, let's do it manually (as a contract of this method)
-                try {
-                    // TODO improve on this - it ignores the configuration of whitelists, see CatalogBomScanner.
-                    // One way would be to add the CatalogBomScanner to the new Scratchpad area, then retrieving the singleton
-                    // here to get back the predicate from it.
-                    final Predicate<Bundle> applicationsPermitted = Predicates.<Bundle>alwaysTrue();
-
-                    catalogItems = new CatalogBundleLoader(applicationsPermitted, mgmt()).scanForCatalog(bundle);
-                } catch (RuntimeException ex) {
-                    try {
-                        bundle.uninstall();
-                    } catch (BundleException e) {
-                        log.error("Cannot uninstall bundle " + bundle.getSymbolicName() + ":" + bundle.getVersion(), e);
-                    }
-                    throw new IllegalArgumentException("Error installing catalog items", ex);
-                }
-            }
+            Iterable<? extends CatalogItem<?, ?>> catalogItems = MutableList.copyOf( 
+                ((ManagementContextInternal)mgmt()).getOsgiManager().get().loadCatalogBom(bundle) );
 
-            // TODO improve on this - Currently, the added items are returned ONLY if the FEATURE_LOAD_BUNDLE_CATALOG_BOM
-            // is disabled. When enabled, the above code is not executed and the catalog items addition is delegated
-            // to the CatalogBomScanner. The REST API will therefore not know what are the added catalog items and won't
-            // return them.
-            // One way to improved this would be couple agoin the CatalogBomScanner with the CatalogBundleLoader to
-            // retrieve the list of added catalog items per bundle.
             return buildCreateResponse(catalogItems);
         } catch (RuntimeException ex) {
             throw WebResourceUtils.badRequest(ex);

http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/abd0cb8b/utils/common/src/main/java/org/apache/brooklyn/util/stream/Streams.java
----------------------------------------------------------------------
diff --git a/utils/common/src/main/java/org/apache/brooklyn/util/stream/Streams.java b/utils/common/src/main/java/org/apache/brooklyn/util/stream/Streams.java
index 624613b..0f34357 100644
--- a/utils/common/src/main/java/org/apache/brooklyn/util/stream/Streams.java
+++ b/utils/common/src/main/java/org/apache/brooklyn/util/stream/Streams.java
@@ -150,6 +150,17 @@ public class Streams {
             throw Exceptions.propagate(ioe);
         }
     }
+    
+    /** copies and closes both */
+    public static void copyClose(InputStream input, OutputStream output) {
+        try {
+            copy(input, output);
+        } catch (RuntimeException e) {
+            closeQuietly(input);
+            closeQuietly(output);
+            throw e;
+        }
+    }
 
     public static void copy(Reader input, Writer output) {
         try {

http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/abd0cb8b/utils/common/src/main/java/org/apache/brooklyn/util/text/StringShortener.java
----------------------------------------------------------------------
diff --git a/utils/common/src/main/java/org/apache/brooklyn/util/text/StringShortener.java b/utils/common/src/main/java/org/apache/brooklyn/util/text/StringShortener.java
index d531f79..89cd7cc 100644
--- a/utils/common/src/main/java/org/apache/brooklyn/util/text/StringShortener.java
+++ b/utils/common/src/main/java/org/apache/brooklyn/util/text/StringShortener.java
@@ -66,11 +66,11 @@ public class StringShortener {
         return input;
     }
 
-    public StringShortener setAllowedCharacters(String disalowedCharacters) {
+    public StringShortener setAllowedCharacters(String allowedCharacters) {
         this.allowedCharacters = new HashSet<>();
-        for(char c : disalowedCharacters.toCharArray()) {
+        for (char c : allowedCharacters.toCharArray()) {
             this.allowedCharacters.add(c);
-            }
+        }
         return this;
     }
     

http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/abd0cb8b/utils/common/src/test/java/org/apache/brooklyn/util/osgi/OsgiTestResources.java
----------------------------------------------------------------------
diff --git a/utils/common/src/test/java/org/apache/brooklyn/util/osgi/OsgiTestResources.java b/utils/common/src/test/java/org/apache/brooklyn/util/osgi/OsgiTestResources.java
index 39ae99c..e11993a 100644
--- a/utils/common/src/test/java/org/apache/brooklyn/util/osgi/OsgiTestResources.java
+++ b/utils/common/src/test/java/org/apache/brooklyn/util/osgi/OsgiTestResources.java
@@ -26,7 +26,7 @@ package org.apache.brooklyn.util.osgi;
  * Some of these bundles are also used in REST API tests, as that stretches catalog further
  * (using CAMP) and that is one area where OSGi is heavily used. 
  */
-public class OsgiTestResources {
+public interface OsgiTestResources {
 
     /**
      * brooklyn-osgi-test-a_0.1.0 -
@@ -101,5 +101,14 @@ public class OsgiTestResources {
      * at runtime.
      */
     public static final String BROOKLYN_TEST_MORE_ENTITIES_V2_EVIL_TWIN_PATH = "/brooklyn/osgi/" + BROOKLYN_TEST_MORE_ENTITIES_SYMBOLIC_NAME_FINAL_PART + "_evil-twin_0.2.0.jar";
+
+
+    public static final String BROOKLYN_TEST_OSGI_ENTITIES_URL = "classpath:"+OsgiTestResources.BROOKLYN_TEST_OSGI_ENTITIES_PATH;
+
+    public static final String BROOKLYN_TEST_MORE_ENTITIES_V1_URL = "classpath:"+BROOKLYN_TEST_MORE_ENTITIES_V1_PATH;
+    public static final String BROOKLYN_TEST_MORE_ENTITIES_V2_URL = "classpath:"+BROOKLYN_TEST_MORE_ENTITIES_V2_PATH;
+    public static final String BROOKLYN_TEST_MORE_ENTITIES_V2_EVIL_TWIN_URL = "classpath:"+BROOKLYN_TEST_MORE_ENTITIES_V2_EVIL_TWIN_PATH;
     
+    public static final String TEST_VERSION = "0.1.0";
+
 }

http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/abd0cb8b/utils/common/src/test/java/org/apache/brooklyn/util/text/StringShortenerTest.java
----------------------------------------------------------------------
diff --git a/utils/common/src/test/java/org/apache/brooklyn/util/text/StringShortenerTest.java b/utils/common/src/test/java/org/apache/brooklyn/util/text/StringShortenerTest.java
index 201c3e6..592aea7 100644
--- a/utils/common/src/test/java/org/apache/brooklyn/util/text/StringShortenerTest.java
+++ b/utils/common/src/test/java/org/apache/brooklyn/util/text/StringShortenerTest.java
@@ -44,7 +44,7 @@ public class StringShortenerTest {
     }
 
     @Test
-    public void testDisalowedCharactersShortener() {
+    public void testDisallowedCharactersShortener() {
         StringShortener ss = new StringShortener()
                 .setAllowedCharacters(Identifiers.UPPER_CASE_ALPHA+Identifiers.LOWER_CASE_ALPHA+Identifiers.NUMERIC)
                 .separator("-")