You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@brooklyn.apache.org by sv...@apache.org on 2016/07/06 12:33:13 UTC

[1/5] brooklyn-server git commit: Propagate the catalog loading list

Repository: brooklyn-server
Updated Branches:
  refs/heads/master 30573a579 -> 33421d724


Propagate the catalog loading list


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

Branch: refs/heads/master
Commit: 2330de42c92dc725605f50be3ec445121d38d961
Parents: 48abd26
Author: Svetoslav Neykov <sv...@cloudsoftcorp.com>
Authored: Tue Jul 5 12:37:13 2016 +0300
Committer: Svetoslav Neykov <sv...@cloudsoftcorp.com>
Committed: Wed Jul 6 14:58:48 2016 +0300

----------------------------------------------------------------------
 .../spi/creation/CampInternalUtils.java         |  5 +++-
 .../brooklyn/catalog/CatalogYamlEntityTest.java | 24 ++++++++++++++++++++
 2 files changed, 28 insertions(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/2330de42/camp/camp-brooklyn/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/creation/CampInternalUtils.java
----------------------------------------------------------------------
diff --git a/camp/camp-brooklyn/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/creation/CampInternalUtils.java b/camp/camp-brooklyn/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/creation/CampInternalUtils.java
index c2c6c40..8c9bf63 100644
--- a/camp/camp-brooklyn/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/creation/CampInternalUtils.java
+++ b/camp/camp-brooklyn/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/creation/CampInternalUtils.java
@@ -37,6 +37,7 @@ import org.apache.brooklyn.api.objs.SpecParameter;
 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.api.typereg.RegisteredTypeLoadingContext;
 import org.apache.brooklyn.camp.CampPlatform;
 import org.apache.brooklyn.camp.brooklyn.BrooklynCampConstants;
 import org.apache.brooklyn.camp.brooklyn.BrooklynCampReservedKeys;
@@ -47,6 +48,7 @@ import org.apache.brooklyn.camp.spi.pdp.DeploymentPlan;
 import org.apache.brooklyn.core.catalog.internal.BasicBrooklynCatalog;
 import org.apache.brooklyn.core.catalog.internal.BasicBrooklynCatalog.BrooklynLoaderTracker;
 import org.apache.brooklyn.core.objs.BasicSpecParameter;
+import org.apache.brooklyn.core.typereg.RegisteredTypeLoadingContexts;
 import org.apache.brooklyn.entity.stock.BasicApplicationImpl;
 import org.apache.brooklyn.util.collections.MutableMap;
 import org.apache.brooklyn.util.exceptions.Exceptions;
@@ -208,7 +210,8 @@ class CampInternalUtils {
         PolicySpec<? extends Policy> spec;
         RegisteredType item = loader.getManagementContext().getTypeRegistry().get(versionedId);
         if (item != null && !encounteredCatalogTypes.contains(item.getSymbolicName())) {
-            return loader.getManagementContext().getTypeRegistry().createSpec(item, null, PolicySpec.class);
+            RegisteredTypeLoadingContext context = RegisteredTypeLoadingContexts.alreadyEncountered(encounteredCatalogTypes);
+            return loader.getManagementContext().getTypeRegistry().createSpec(item, context, PolicySpec.class);
         } else {
             // TODO-type-registry pass the loader in to the above, and allow it to load with the loader
             spec = PolicySpec.create(loader.loadClass(versionedId, Policy.class));

http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/2330de42/camp/camp-brooklyn/src/test/java/org/apache/brooklyn/camp/brooklyn/catalog/CatalogYamlEntityTest.java
----------------------------------------------------------------------
diff --git a/camp/camp-brooklyn/src/test/java/org/apache/brooklyn/camp/brooklyn/catalog/CatalogYamlEntityTest.java b/camp/camp-brooklyn/src/test/java/org/apache/brooklyn/camp/brooklyn/catalog/CatalogYamlEntityTest.java
index 484c160..60eed64 100644
--- a/camp/camp-brooklyn/src/test/java/org/apache/brooklyn/camp/brooklyn/catalog/CatalogYamlEntityTest.java
+++ b/camp/camp-brooklyn/src/test/java/org/apache/brooklyn/camp/brooklyn/catalog/CatalogYamlEntityTest.java
@@ -868,6 +868,30 @@ public class CatalogYamlEntityTest extends AbstractYamlTest {
         mgmt().getCatalog().deleteCatalogItem(id, version);
     }
 
+    @Test
+    public void testCreateOsgiSpecFromRegistry() throws Exception {
+        TestResourceUnavailableException.throwIfResourceUnavailable(getClass(), OsgiStandaloneTest.BROOKLYN_TEST_OSGI_ENTITIES_PATH);
+
+        String symbolicName = "my.catalog.app.id.registry.spec";
+        addCatalogItems(
+            "brooklyn.catalog:",
+            "  id: " + symbolicName,
+            "  name: My Catalog App",
+            "  description: My description",
+            "  icon_url: classpath://path/to/myicon.jpg",
+            "  version: " + TEST_VERSION,
+            "  libraries:",
+            "  - url: " + OsgiStandaloneTest.BROOKLYN_TEST_OSGI_ENTITIES_URL,
+            "  item: " + SIMPLE_ENTITY_TYPE);
+
+        BrooklynTypeRegistry registry = mgmt().getTypeRegistry();
+        RegisteredType item = registry.get(symbolicName, TEST_VERSION);
+        AbstractBrooklynObjectSpec<?, ?> spec = registry.createSpec(item, null, null);
+        assertEquals(spec.getCatalogItemId(), ver(symbolicName));
+
+        deleteCatalogEntity(symbolicName);
+    }
+
     private void registerAndLaunchAndAssertSimpleEntity(String symbolicName, String serviceType) throws Exception {
         addCatalogOSGiEntity(symbolicName, serviceType);
         String yaml = "name: simple-app-yaml\n" +


[5/5] brooklyn-server git commit: Closes #233

Posted by sv...@apache.org.
Closes #233

Karaf fixes - class loading

* Disables loading `catalog.bom` (can be enabled through a feature flag).
* Moves all `catalog.bom` items to be loaded through `default.catalog.bom`
* Fallback class loading - replace `Class.forName(..)`, `classLoader.loadClass(...)` usages with a centralized logic.

Class loading logic:
  * Supports embedding the bundle's symbolidName and version in the class name (for example `org.apache.brooklyn.core:0.10.0.SNAPHOT:org.apache.brooklyn.core.mgmt.entitlement.PerUserEntitlementManager`
  * try to load from the entity's catalog item libraries
  * Class.forName, using the calling class' class loader
  * mgmt.getCatalogClassLoader.loadClass
  * scanning all bundles matching `org.apache.brooklyn.*:0.10.0-SNAPSHOT` by default. Can be overriden with a system property.


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

Branch: refs/heads/master
Commit: 33421d7247f0b0090e02fce6c176bdc5d5cfd302
Parents: 30573a5 f315476
Author: Svetoslav Neykov <sv...@cloudsoftcorp.com>
Authored: Wed Jul 6 15:32:40 2016 +0300
Committer: Svetoslav Neykov <sv...@cloudsoftcorp.com>
Committed: Wed Jul 6 15:32:40 2016 +0300

----------------------------------------------------------------------
 .../spi/creation/CampInternalUtils.java         |   5 +-
 .../spi/dsl/methods/BrooklynDslCommon.java      |  10 +-
 .../brooklyn/catalog/CatalogYamlEntityTest.java |  24 +
 .../core/BrooklynFeatureEnablement.java         |   8 +
 .../catalog/internal/CatalogBomScanner.java     |  27 +-
 .../brooklyn/core/effector/AddSensor.java       |  15 +-
 .../drivers/ReflectiveEntityDriverFactory.java  |   5 +-
 .../brooklyn/core/location/geo/HostGeoInfo.java |   3 +-
 .../JavaBrooklynClassLoadingContext.java        |  18 +-
 .../core/mgmt/entitlement/Entitlements.java     |   8 +-
 .../internal/AbstractManagementContext.java     |   3 +-
 .../transformer/CompoundTransformerLoader.java  |   3 +-
 .../brooklyn/core/objs/BrooklynTypes.java       |   5 +-
 .../core/sensor/DurationSinceSensor.java        |   7 +-
 .../core/sensor/ssh/SshCommandSensor.java       |   2 +-
 .../location/byon/ByonLocationResolver.java     |   4 +-
 .../location/ssh/SshMachineLocation.java        |   3 +-
 .../brooklyn/util/core/ClassLoaderUtils.java    | 249 +++++++++
 .../brooklyn/util/core/flags/TypeCoercions.java |   9 +-
 .../objs/BasicSpecParameterFromClassTest.java   |   5 +-
 karaf/apache-brooklyn/pom.xml                   |   9 +
 .../src/main/resources/etc/default.catalog.bom  | 416 +++++++++++++--
 karaf/features/src/main/feature/feature.xml     |  17 +-
 .../init/src/main/resources/catalog-classes.bom | 507 +++++++++++++++++++
 .../brooklyn/rest/resources/PolicyResource.java |   7 +-
 .../provider/DelegatingSecurityProvider.java    |  10 +-
 .../HardcodedCatalogEntitySpecResolver.java     |  59 ++-
 .../location/winrm/WinRmMachineLocation.java    |  11 +-
 28 files changed, 1318 insertions(+), 131 deletions(-)
----------------------------------------------------------------------



[2/5] brooklyn-server git commit: Hide bundle catalog.bom loading behind a feature flag

Posted by sv...@apache.org.
Hide bundle catalog.bom loading behind a feature flag


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

Branch: refs/heads/master
Commit: 48abd262099548bb246e1f1d9a7838e5b26958dc
Parents: 30573a5
Author: Svetoslav Neykov <sv...@cloudsoftcorp.com>
Authored: Tue Jul 5 12:36:02 2016 +0300
Committer: Svetoslav Neykov <sv...@cloudsoftcorp.com>
Committed: Wed Jul 6 14:58:48 2016 +0300

----------------------------------------------------------------------
 .../core/BrooklynFeatureEnablement.java         |  8 ++++++
 .../catalog/internal/CatalogBomScanner.java     | 27 +++++++++++++-------
 2 files changed, 26 insertions(+), 9 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/48abd262/core/src/main/java/org/apache/brooklyn/core/BrooklynFeatureEnablement.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/core/BrooklynFeatureEnablement.java b/core/src/main/java/org/apache/brooklyn/core/BrooklynFeatureEnablement.java
index 48418a3..f2e8a0a 100644
--- a/core/src/main/java/org/apache/brooklyn/core/BrooklynFeatureEnablement.java
+++ b/core/src/main/java/org/apache/brooklyn/core/BrooklynFeatureEnablement.java
@@ -112,6 +112,13 @@ public class BrooklynFeatureEnablement {
     public static final String FEATURE_VALIDATE_LOCATION_SSH_KEYS = "brooklyn.validate.locationSshKeys";
 
     /**
+     * Whether to scan newly loaded bundles for catalog.bom and load it.
+     * 
+     * The functionality loads catalog items regardless of the persistence state so best used with persistence disabled.
+     */
+    public static final String FEATURE_LOAD_BUNDLE_CATALOG_BOM = FEATURE_PROPERTY_PREFIX+".osgi.catalog_bom";
+
+    /**
      * Values explicitly set by Java calls.
      */
     private static final Map<String, Boolean> FEATURE_ENABLEMENTS = Maps.newLinkedHashMap();
@@ -146,6 +153,7 @@ public class BrooklynFeatureEnablement {
         setDefault(FEATURE_AUTO_FIX_CATALOG_REF_ON_REBIND, false);
         setDefault(FEATURE_SSH_ASYNC_EXEC, false);
         setDefault(FEATURE_VALIDATE_LOCATION_SSH_KEYS, true);
+        setDefault(FEATURE_LOAD_BUNDLE_CATALOG_BOM, false);
     }
     
     static {

http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/48abd262/core/src/main/java/org/apache/brooklyn/core/catalog/internal/CatalogBomScanner.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/core/catalog/internal/CatalogBomScanner.java b/core/src/main/java/org/apache/brooklyn/core/catalog/internal/CatalogBomScanner.java
index ae2885a..b7e0041 100644
--- a/core/src/main/java/org/apache/brooklyn/core/catalog/internal/CatalogBomScanner.java
+++ b/core/src/main/java/org/apache/brooklyn/core/catalog/internal/CatalogBomScanner.java
@@ -23,6 +23,7 @@ import com.google.common.collect.ImmutableMap;
 import com.google.common.collect.Iterables;
 import org.apache.brooklyn.api.catalog.CatalogItem;
 import org.apache.brooklyn.api.mgmt.ManagementContext;
+import org.apache.brooklyn.core.BrooklynFeatureEnablement;
 import org.apache.brooklyn.util.collections.MutableList;
 import org.apache.brooklyn.util.exceptions.Exceptions;
 import org.apache.brooklyn.util.stream.Streams;
@@ -60,21 +61,29 @@ public class CatalogBomScanner {
     private CatalogPopulator catalogTracker;
 
     public void bind(ServiceReference<ManagementContext> managementContext) throws Exception {
-        LOG.debug("Binding management context with whiteList [{}] and blacklist [{}]",
-            Strings.join(getWhiteList(), "; "),
-            Strings.join(getBlackList(), "; "));
-        catalogTracker = new CatalogPopulator(managementContext);
+        if (isEnabled()) {
+            LOG.debug("Binding management context with whiteList [{}] and blacklist [{}]",
+                Strings.join(getWhiteList(), "; "),
+                Strings.join(getBlackList(), "; "));
+            catalogTracker = new CatalogPopulator(managementContext);
+        }
     }
 
     public void unbind(ServiceReference<ManagementContext> managementContext) throws Exception {
-        LOG.debug("Unbinding management context");
-        if (null != catalogTracker) {
-            CatalogPopulator temp = catalogTracker;
-            catalogTracker = null;
-            temp.close();
+        if (isEnabled()) {
+            LOG.debug("Unbinding management context");
+            if (null != catalogTracker) {
+                CatalogPopulator temp = catalogTracker;
+                catalogTracker = null;
+                temp.close();
+            }
         }
     }
 
+    private boolean isEnabled() {
+        return BrooklynFeatureEnablement.isEnabled(BrooklynFeatureEnablement.FEATURE_LOAD_BUNDLE_CATALOG_BOM);
+    }
+
     private String[] bundleIds(Bundle bundle) {
         return new String[] {
             String.valueOf(bundle.getBundleId()), bundle.getSymbolicName(), bundle.getVersion().toString()


[4/5] brooklyn-server git commit: Centralize class loading and implement fallback bundle scanning

Posted by sv...@apache.org.
Centralize class loading and implement fallback bundle scanning


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

Branch: refs/heads/master
Commit: f31547645060e69bcdc1b96882d0040e9a266333
Parents: 1ecd7fe
Author: Svetoslav Neykov <sv...@cloudsoftcorp.com>
Authored: Tue Jul 5 21:00:53 2016 +0300
Committer: Svetoslav Neykov <sv...@cloudsoftcorp.com>
Committed: Wed Jul 6 15:28:57 2016 +0300

----------------------------------------------------------------------
 .../spi/dsl/methods/BrooklynDslCommon.java      |  10 +-
 .../brooklyn/core/effector/AddSensor.java       |  15 +-
 .../drivers/ReflectiveEntityDriverFactory.java  |   5 +-
 .../brooklyn/core/location/geo/HostGeoInfo.java |   3 +-
 .../JavaBrooklynClassLoadingContext.java        |  18 +-
 .../core/mgmt/entitlement/Entitlements.java     |   8 +-
 .../internal/AbstractManagementContext.java     |   3 +-
 .../transformer/CompoundTransformerLoader.java  |   3 +-
 .../brooklyn/core/objs/BrooklynTypes.java       |   5 +-
 .../core/sensor/DurationSinceSensor.java        |   7 +-
 .../core/sensor/ssh/SshCommandSensor.java       |   2 +-
 .../location/byon/ByonLocationResolver.java     |   4 +-
 .../location/ssh/SshMachineLocation.java        |   3 +-
 .../brooklyn/util/core/ClassLoaderUtils.java    | 249 +++++++++++++++++++
 .../brooklyn/util/core/flags/TypeCoercions.java |   9 +-
 .../objs/BasicSpecParameterFromClassTest.java   |   5 +-
 .../brooklyn/rest/resources/PolicyResource.java |   7 +-
 .../provider/DelegatingSecurityProvider.java    |  10 +-
 .../HardcodedCatalogEntitySpecResolver.java     |  59 +++--
 .../location/winrm/WinRmMachineLocation.java    |  11 +-
 20 files changed, 366 insertions(+), 70 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/f3154764/camp/camp-brooklyn/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/dsl/methods/BrooklynDslCommon.java
----------------------------------------------------------------------
diff --git a/camp/camp-brooklyn/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/dsl/methods/BrooklynDslCommon.java b/camp/camp-brooklyn/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/dsl/methods/BrooklynDslCommon.java
index b1db078..a67d89e 100644
--- a/camp/camp-brooklyn/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/dsl/methods/BrooklynDslCommon.java
+++ b/camp/camp-brooklyn/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/dsl/methods/BrooklynDslCommon.java
@@ -45,6 +45,7 @@ import org.apache.brooklyn.core.mgmt.internal.ManagementContextInternal;
 import org.apache.brooklyn.core.mgmt.persist.DeserializingClassRenamesProvider;
 import org.apache.brooklyn.core.sensor.DependentConfiguration;
 import org.apache.brooklyn.util.collections.MutableMap;
+import org.apache.brooklyn.util.core.ClassLoaderUtils;
 import org.apache.brooklyn.util.core.config.ConfigBag;
 import org.apache.brooklyn.util.core.flags.ClassCoercionException;
 import org.apache.brooklyn.util.core.flags.FlagUtils;
@@ -129,9 +130,10 @@ public class BrooklynDslCommon {
     @SuppressWarnings({ "unchecked", "rawtypes" })
     public static Sensor<?> sensor(String clazzName, String sensorName) {
         try {
-            // TODO Should use catalog's classloader, rather than Class.forName; how to get that? Should we return a future?!
+            // TODO Should use catalog's classloader, rather than ClassLoaderUtils; how to get that? Should we return a future?!
+            //      Should have the catalog's loader at this point in a thread local
             String mappedClazzName = DeserializingClassRenamesProvider.findMappedName(clazzName);
-            Class<?> clazz = Class.forName(mappedClazzName);
+            Class<?> clazz = new ClassLoaderUtils(BrooklynDslCommon.class).loadClass(mappedClazzName);
             
             Sensor<?> sensor;
             if (Entity.class.isAssignableFrom(clazz)) {
@@ -170,9 +172,9 @@ public class BrooklynDslCommon {
         Map<String,Object> objectFields = (Map<String, Object>) config.getStringKeyMaybe("object.fields").or(MutableMap.of());
         Map<String,Object> brooklynConfig = (Map<String, Object>) config.getStringKeyMaybe(BrooklynCampReservedKeys.BROOKLYN_CONFIG).or(MutableMap.of());
         try {
-            // TODO Should use catalog's classloader, rather than Class.forName; how to get that? Should we return a future?!
+            // TODO Should use catalog's classloader, rather than ClassLoaderUtils; how to get that? Should we return a future?!
             String mappedTypeName = DeserializingClassRenamesProvider.findMappedName(typeName);
-            Class<?> type = Class.forName(mappedTypeName);
+            Class<?> type = new ClassLoaderUtils(BrooklynDslCommon.class).loadClass(mappedTypeName);
             
             if (!Reflections.hasNoArgConstructor(type)) {
                 throw new IllegalStateException(String.format("Cannot construct %s bean: No public no-arg constructor available", type));

http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/f3154764/core/src/main/java/org/apache/brooklyn/core/effector/AddSensor.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/core/effector/AddSensor.java b/core/src/main/java/org/apache/brooklyn/core/effector/AddSensor.java
index d35068f..ba8d679 100644
--- a/core/src/main/java/org/apache/brooklyn/core/effector/AddSensor.java
+++ b/core/src/main/java/org/apache/brooklyn/core/effector/AddSensor.java
@@ -20,6 +20,7 @@ package org.apache.brooklyn.core.effector;
 
 import java.util.Map;
 
+import org.apache.brooklyn.api.entity.Entity;
 import org.apache.brooklyn.api.entity.EntityInitializer;
 import org.apache.brooklyn.api.entity.EntityLocal;
 import org.apache.brooklyn.api.sensor.AttributeSensor;
@@ -27,6 +28,7 @@ import org.apache.brooklyn.config.ConfigKey;
 import org.apache.brooklyn.core.config.ConfigKeys;
 import org.apache.brooklyn.core.entity.EntityInternal;
 import org.apache.brooklyn.core.sensor.Sensors;
+import org.apache.brooklyn.util.core.ClassLoaderUtils;
 import org.apache.brooklyn.util.core.config.ConfigBag;
 import org.apache.brooklyn.util.guava.Maybe;
 import org.apache.brooklyn.util.javalang.Boxing;
@@ -54,7 +56,7 @@ public class AddSensor<T> implements EntityInitializer {
     protected final String name;
     protected final Duration period;
     protected final String type;
-    protected final AttributeSensor<T> sensor;
+    protected AttributeSensor<T> sensor;
 
     public AddSensor(Map<String, String> params) {
         this(ConfigBag.newInstance(params));
@@ -64,27 +66,28 @@ public class AddSensor<T> implements EntityInitializer {
         this.name = Preconditions.checkNotNull(params.get(SENSOR_NAME), "Name must be supplied when defining a sensor");
         this.period = params.get(SENSOR_PERIOD);
         this.type = params.get(SENSOR_TYPE);
-        this.sensor = newSensor();
     }
 
     @Override
     public void apply(EntityLocal entity) {
+        sensor = newSensor(entity);
         ((EntityInternal) entity).getMutableEntityType().addSensor(sensor);
     }
 
-    private AttributeSensor<T> newSensor() {
+    private AttributeSensor<T> newSensor(Entity entity) {
         String className = getFullClassName(type);
-        Class<T> clazz = getType(className);
+        Class<T> clazz = getType(entity, className);
         return Sensors.newSensor(clazz, name);
     }
 
     @SuppressWarnings("unchecked")
-    protected Class<T> getType(String className) {
+    protected Class<T> getType(Entity entity, String className) {
         try {
             // TODO use OSGi loader (low priority however); also ensure that allows primitives
             Maybe<Class<?>> primitive = Boxing.getPrimitiveType(className);
             if (primitive.isPresent()) return (Class<T>) primitive.get();
-            return (Class<T>) Class.forName(className);
+            
+            return (Class<T>) new ClassLoaderUtils(this, entity).loadClass(className);
         } catch (ClassNotFoundException e) {
             if (!className.contains(".")) {
                 // could be assuming "java.lang" package; try again with that

http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/f3154764/core/src/main/java/org/apache/brooklyn/core/entity/drivers/ReflectiveEntityDriverFactory.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/core/entity/drivers/ReflectiveEntityDriverFactory.java b/core/src/main/java/org/apache/brooklyn/core/entity/drivers/ReflectiveEntityDriverFactory.java
index f9cf5a7..a2d6722 100644
--- a/core/src/main/java/org/apache/brooklyn/core/entity/drivers/ReflectiveEntityDriverFactory.java
+++ b/core/src/main/java/org/apache/brooklyn/core/entity/drivers/ReflectiveEntityDriverFactory.java
@@ -26,12 +26,14 @@ import java.util.Map;
 import org.apache.brooklyn.api.entity.drivers.DriverDependentEntity;
 import org.apache.brooklyn.api.entity.drivers.EntityDriver;
 import org.apache.brooklyn.api.location.Location;
+import org.apache.brooklyn.core.BrooklynVersion;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.apache.brooklyn.location.paas.PaasLocation;
 import org.apache.brooklyn.location.ssh.SshMachineLocation;
 import org.apache.brooklyn.util.collections.MutableList;
 import org.apache.brooklyn.util.collections.MutableMap;
+import org.apache.brooklyn.util.core.ClassLoaderUtils;
 import org.apache.brooklyn.util.exceptions.Exceptions;
 import org.apache.brooklyn.util.exceptions.ReferenceWithError;
 import org.apache.brooklyn.util.text.Strings;
@@ -193,7 +195,8 @@ public class ReflectiveEntityDriverFactory {
             String driverInterfaceName = driverInterface.getName();
             // TODO: use a proper registry later on
             try {
-                if (!Class.forName("org.apache.brooklyn.location.winrm.WinRmMachineLocation").isInstance(location)) return null;
+                Class<?> winRmLocationClass = new ClassLoaderUtils(this, entity).loadClass("org.apache.brooklyn.software-winrm", BrooklynVersion.get(), "org.apache.brooklyn.location.winrm.WinRmMachineLocation");
+                if (!winRmLocationClass.isInstance(location)) return null;
             } catch (ClassNotFoundException ex) {
                 return null;
             }

http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/f3154764/core/src/main/java/org/apache/brooklyn/core/location/geo/HostGeoInfo.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/core/location/geo/HostGeoInfo.java b/core/src/main/java/org/apache/brooklyn/core/location/geo/HostGeoInfo.java
index f99b41d..ced6b7c 100644
--- a/core/src/main/java/org/apache/brooklyn/core/location/geo/HostGeoInfo.java
+++ b/core/src/main/java/org/apache/brooklyn/core/location/geo/HostGeoInfo.java
@@ -28,6 +28,7 @@ import org.apache.brooklyn.api.location.AddressableLocation;
 import org.apache.brooklyn.api.location.Location;
 import org.apache.brooklyn.core.location.AbstractLocation;
 import org.apache.brooklyn.core.location.LocationConfigKeys;
+import org.apache.brooklyn.util.core.ClassLoaderUtils;
 import org.apache.brooklyn.util.core.flags.TypeCoercions;
 import org.apache.brooklyn.util.exceptions.Exceptions;
 import org.apache.brooklyn.util.guava.Maybe;
@@ -164,7 +165,7 @@ public class HostGeoInfo implements Serializable {
             return new UtraceHostGeoLookup();
         }
         if (type.isEmpty()) return null;
-        return (HostGeoLookup) Class.forName(type).newInstance();
+        return (HostGeoLookup) new ClassLoaderUtils(HostGeoInfo.class).loadClass(type).newInstance();
     }
 
     public static HostGeoInfo fromEntity(Entity e) {

http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/f3154764/core/src/main/java/org/apache/brooklyn/core/mgmt/classloading/JavaBrooklynClassLoadingContext.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/core/mgmt/classloading/JavaBrooklynClassLoadingContext.java b/core/src/main/java/org/apache/brooklyn/core/mgmt/classloading/JavaBrooklynClassLoadingContext.java
index 064ba03..e89501e 100644
--- a/core/src/main/java/org/apache/brooklyn/core/mgmt/classloading/JavaBrooklynClassLoadingContext.java
+++ b/core/src/main/java/org/apache/brooklyn/core/mgmt/classloading/JavaBrooklynClassLoadingContext.java
@@ -29,6 +29,7 @@ import java.util.Enumeration;
 import org.apache.brooklyn.api.mgmt.ManagementContext;
 import org.apache.brooklyn.core.entity.AbstractEntity;
 import org.apache.brooklyn.core.mgmt.persist.DeserializingClassRenamesProvider;
+import org.apache.brooklyn.util.core.ClassLoaderUtils;
 import org.apache.brooklyn.util.exceptions.Exceptions;
 import org.apache.brooklyn.util.guava.Maybe;
 import org.slf4j.Logger;
@@ -81,9 +82,24 @@ public class JavaBrooklynClassLoadingContext extends AbstractBrooklynClassLoadin
         if (mgmt!=null) return mgmt.getCatalogClassLoader();
         return JavaBrooklynClassLoadingContext.class.getClassLoader();
     }
-    
+
     @SuppressWarnings({ "rawtypes", "unchecked" })
     public Maybe<Class<?>> tryLoadClass(String className) {
+        Maybe<Class<?>> cls = tryLoadClass0(className);
+        if (cls.isPresent()) {
+            return cls;
+        }
+        try {
+            return (Maybe) Maybe.of(new ClassLoaderUtils(this, mgmt).loadClass(className));
+        } catch (Exception e) {
+            Exceptions.propagateIfFatal(e);
+            // return original error
+            return cls;
+        }
+    }
+
+    @SuppressWarnings({ "rawtypes", "unchecked" })
+    private Maybe<Class<?>> tryLoadClass0(String className) {
         try {
             className = DeserializingClassRenamesProvider.findMappedName(className);
             return (Maybe) Maybe.of(getClassLoader().loadClass(className));

http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/f3154764/core/src/main/java/org/apache/brooklyn/core/mgmt/entitlement/Entitlements.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/core/mgmt/entitlement/Entitlements.java b/core/src/main/java/org/apache/brooklyn/core/mgmt/entitlement/Entitlements.java
index 7199267..e867c76 100644
--- a/core/src/main/java/org/apache/brooklyn/core/mgmt/entitlement/Entitlements.java
+++ b/core/src/main/java/org/apache/brooklyn/core/mgmt/entitlement/Entitlements.java
@@ -21,7 +21,6 @@ package org.apache.brooklyn.core.mgmt.entitlement;
 import java.util.Arrays;
 import java.util.List;
 
-import javax.annotation.Nonnull;
 import javax.annotation.Nullable;
 
 import org.apache.brooklyn.api.entity.Entity;
@@ -35,8 +34,8 @@ import org.apache.brooklyn.core.config.ConfigKeys;
 import org.apache.brooklyn.core.config.Sanitizer;
 import org.apache.brooklyn.core.internal.BrooklynProperties;
 import org.apache.brooklyn.core.mgmt.BrooklynTaskTags;
-import org.apache.brooklyn.core.mgmt.internal.ManagementContextInternal;
 import org.apache.brooklyn.core.mgmt.persist.DeserializingClassRenamesProvider;
+import org.apache.brooklyn.util.core.ClassLoaderUtils;
 import org.apache.brooklyn.util.core.task.Tasks;
 import org.apache.brooklyn.util.exceptions.Exceptions;
 import org.apache.brooklyn.util.javalang.Reflections;
@@ -455,10 +454,7 @@ public class Entitlements {
         }
         if (Strings.isNonBlank(type)) {
             try {
-                ClassLoader cl = mgmt != null
-                        ? mgmt.getCatalogClassLoader()
-                        : Entitlements.class.getClassLoader();
-                Class<?> clazz = cl.loadClass(DeserializingClassRenamesProvider.findMappedName(type));
+                Class<?> clazz = new ClassLoaderUtils(Entitlements.class, mgmt).loadClass(DeserializingClassRenamesProvider.findMappedName(type));
                 return (EntitlementManager) instantiate(clazz, ImmutableList.of(
                         new Object[] {mgmt, brooklynProperties},
                         new Object[] {mgmt},

http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/f3154764/core/src/main/java/org/apache/brooklyn/core/mgmt/internal/AbstractManagementContext.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/core/mgmt/internal/AbstractManagementContext.java b/core/src/main/java/org/apache/brooklyn/core/mgmt/internal/AbstractManagementContext.java
index da2f30c..67bcd11 100644
--- a/core/src/main/java/org/apache/brooklyn/core/mgmt/internal/AbstractManagementContext.java
+++ b/core/src/main/java/org/apache/brooklyn/core/mgmt/internal/AbstractManagementContext.java
@@ -73,6 +73,7 @@ import org.apache.brooklyn.core.mgmt.rebind.RebindManagerImpl;
 import org.apache.brooklyn.core.typereg.BasicBrooklynTypeRegistry;
 import org.apache.brooklyn.util.collections.MutableList;
 import org.apache.brooklyn.util.collections.MutableMap;
+import org.apache.brooklyn.util.core.ClassLoaderUtils;
 import org.apache.brooklyn.util.core.ResourceUtils;
 import org.apache.brooklyn.util.core.config.ConfigBag;
 import org.apache.brooklyn.util.core.task.BasicExecutionContext;
@@ -99,7 +100,7 @@ public abstract class AbstractManagementContext implements ManagementContextInte
         Class<?> clazz;
         try{
             //todo: which classloader should we use?
-            clazz = LocalManagementContext.class.getClassLoader().loadClass(clazzName);
+            clazz = new ClassLoaderUtils(AbstractManagementContext.class).loadClass(clazzName);
         }catch(ClassNotFoundException e){
             throw new IllegalStateException(format("Could not load class [%s]",clazzName),e);
         }

http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/f3154764/core/src/main/java/org/apache/brooklyn/core/mgmt/rebind/transformer/CompoundTransformerLoader.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/core/mgmt/rebind/transformer/CompoundTransformerLoader.java b/core/src/main/java/org/apache/brooklyn/core/mgmt/rebind/transformer/CompoundTransformerLoader.java
index 7965327..37f2cae 100644
--- a/core/src/main/java/org/apache/brooklyn/core/mgmt/rebind/transformer/CompoundTransformerLoader.java
+++ b/core/src/main/java/org/apache/brooklyn/core/mgmt/rebind/transformer/CompoundTransformerLoader.java
@@ -23,6 +23,7 @@ import java.util.Map;
 import java.util.Map.Entry;
 
 import org.apache.brooklyn.core.mgmt.rebind.transformer.CompoundTransformer.Builder;
+import org.apache.brooklyn.util.core.ClassLoaderUtils;
 import org.apache.brooklyn.util.core.ResourceUtils;
 import org.apache.brooklyn.util.core.text.TemplateProcessor;
 import org.apache.brooklyn.util.exceptions.Exceptions;
@@ -89,7 +90,7 @@ public class CompoundTransformerLoader {
         } else if (name.equals("rawDataTransformer")) {
             String type = (String) args.get("type");
             try {
-                Class<?> clazz = CompoundTransformerLoader.class.getClassLoader().loadClass(type);
+                Class<?> clazz = new ClassLoaderUtils(CompoundTransformer.class).loadClass(type);
                 builder.rawDataTransformer((RawDataTransformer) clazz.newInstance());
             } catch (Exception e) {
                 throw Exceptions.propagate(e);

http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/f3154764/core/src/main/java/org/apache/brooklyn/core/objs/BrooklynTypes.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/core/objs/BrooklynTypes.java b/core/src/main/java/org/apache/brooklyn/core/objs/BrooklynTypes.java
index 4170613..fa8d607 100644
--- a/core/src/main/java/org/apache/brooklyn/core/objs/BrooklynTypes.java
+++ b/core/src/main/java/org/apache/brooklyn/core/objs/BrooklynTypes.java
@@ -30,6 +30,7 @@ import org.apache.brooklyn.config.ConfigKey;
 import org.apache.brooklyn.core.enricher.EnricherDynamicType;
 import org.apache.brooklyn.core.entity.EntityDynamicType;
 import org.apache.brooklyn.core.policy.PolicyDynamicType;
+import org.apache.brooklyn.util.core.ClassLoaderUtils;
 import org.apache.brooklyn.util.exceptions.Exceptions;
 
 import com.google.common.collect.Maps;
@@ -110,7 +111,7 @@ public class BrooklynTypes {
     @SuppressWarnings("unchecked")
     public static Map<String, ConfigKey<?>> getDefinedConfigKeys(String brooklynTypeName) {
         try {
-            return getDefinedConfigKeys((Class<? extends BrooklynObject>) Class.forName(brooklynTypeName));
+            return getDefinedConfigKeys((Class<? extends BrooklynObject>) new ClassLoaderUtils(BrooklynTypes.class).loadClass(brooklynTypeName));
         } catch (ClassNotFoundException e) {
             throw Exceptions.propagate(e);
         }
@@ -123,7 +124,7 @@ public class BrooklynTypes {
     @SuppressWarnings("unchecked")
     public static Map<String, Sensor<?>> getDefinedSensors(String entityTypeName) {
         try {
-            return getDefinedSensors((Class<? extends Entity>) Class.forName(entityTypeName));
+            return getDefinedSensors((Class<? extends Entity>) new ClassLoaderUtils(BrooklynTypes.class).loadClass(entityTypeName));
         } catch (ClassNotFoundException e) {
             throw Exceptions.propagate(e);
         }

http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/f3154764/core/src/main/java/org/apache/brooklyn/core/sensor/DurationSinceSensor.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/core/sensor/DurationSinceSensor.java b/core/src/main/java/org/apache/brooklyn/core/sensor/DurationSinceSensor.java
index 4be57d8..b26af56 100644
--- a/core/src/main/java/org/apache/brooklyn/core/sensor/DurationSinceSensor.java
+++ b/core/src/main/java/org/apache/brooklyn/core/sensor/DurationSinceSensor.java
@@ -39,6 +39,7 @@ public class DurationSinceSensor extends AddSensor<Duration> {
 
     private static final Supplier<Long> CURRENT_TIME_SUPPLIER = new CurrentTimeSupplier();
 
+    @SuppressWarnings("serial")
     public static final ConfigKey<Supplier<Long>> EPOCH_SUPPLIER = ConfigKeys.builder(new TypeToken<Supplier<Long>>() {})
             .name("duration.since.epochsupplier")
             .description("The source of time from which durations are measured. Defaults to System.currentTimeMillis when " +
@@ -46,6 +47,7 @@ public class DurationSinceSensor extends AddSensor<Duration> {
             .defaultValue(CURRENT_TIME_SUPPLIER)
             .build();
 
+    @SuppressWarnings("serial")
     public static final ConfigKey<Supplier<Long>> TIME_SUPPLIER = ConfigKeys.builder(new TypeToken<Supplier<Long>>() {})
             .name("duration.since.timesupplier")
             .description("The source of the current time. Defaults to System.currentTimeMillis if unconfigured or the " +
@@ -55,19 +57,20 @@ public class DurationSinceSensor extends AddSensor<Duration> {
 
     private final Supplier<Long> epochSupplier;
     private final Supplier<Long> timeSupplier;
-    private final AttributeSensor<Long> epochSensor;
+    private AttributeSensor<Long> epochSensor;
 
     public DurationSinceSensor(ConfigBag params) {
         super(params);
         epochSupplier = params.get(EPOCH_SUPPLIER);
         timeSupplier = params.get(TIME_SUPPLIER);
-        epochSensor = Sensors.newLongSensor(sensor.getName() + ".epoch");
     }
 
     @Override
     public void apply(final EntityLocal entity) {
         super.apply(entity);
 
+        epochSensor = Sensors.newLongSensor(sensor.getName() + ".epoch");
+
         if (entity.sensors().get(epochSensor) == null) {
             Long epoch = epochSupplier.get();
             if (epoch == null) {

http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/f3154764/core/src/main/java/org/apache/brooklyn/core/sensor/ssh/SshCommandSensor.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/core/sensor/ssh/SshCommandSensor.java b/core/src/main/java/org/apache/brooklyn/core/sensor/ssh/SshCommandSensor.java
index 839448e..25ae2b5 100644
--- a/core/src/main/java/org/apache/brooklyn/core/sensor/ssh/SshCommandSensor.java
+++ b/core/src/main/java/org/apache/brooklyn/core/sensor/ssh/SshCommandSensor.java
@@ -105,7 +105,7 @@ public final class SshCommandSensor<T> extends AddSensor<T> {
                 .onSuccess(Functions.compose(new Function<String, T>() {
                         @Override
                         public T apply(String input) {
-                            return TypeCoercions.coerce(Strings.trimEnd(input), getType(type));
+                            return TypeCoercions.coerce(Strings.trimEnd(input), getType(entity, type));
                         }}, SshValueFunctions.stdout()));
 
         SshFeed.builder()

http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/f3154764/core/src/main/java/org/apache/brooklyn/location/byon/ByonLocationResolver.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/location/byon/ByonLocationResolver.java b/core/src/main/java/org/apache/brooklyn/location/byon/ByonLocationResolver.java
index 58b4989..ca478fd 100644
--- a/core/src/main/java/org/apache/brooklyn/location/byon/ByonLocationResolver.java
+++ b/core/src/main/java/org/apache/brooklyn/location/byon/ByonLocationResolver.java
@@ -35,6 +35,7 @@ import org.apache.brooklyn.core.config.Sanitizer;
 import org.apache.brooklyn.core.location.AbstractLocationResolver;
 import org.apache.brooklyn.core.mgmt.internal.LocalLocationManager;
 import org.apache.brooklyn.util.collections.MutableMap;
+import org.apache.brooklyn.util.core.ClassLoaderUtils;
 import org.apache.brooklyn.util.core.config.ConfigBag;
 import org.apache.brooklyn.util.core.flags.TypeCoercions;
 import org.apache.brooklyn.util.net.UserAndHostAndPort;
@@ -212,7 +213,8 @@ public class ByonLocationResolver extends AbstractLocationResolver {
     private Class<? extends MachineLocation> getLocationClass(String osFamily) {
         try {
             if (osFamily != null) {
-                return Class.forName(OS_TO_MACHINE_LOCATION_TYPE.get(osFamily.toLowerCase(Locale.ENGLISH))).asSubclass(MachineLocation.class);
+                String className = OS_TO_MACHINE_LOCATION_TYPE.get(osFamily.toLowerCase(Locale.ENGLISH));
+                return new ClassLoaderUtils(this, managementContext).loadClass(className).asSubclass(MachineLocation.class);
             }
         } catch (ClassNotFoundException ex) {}
         return null;

http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/f3154764/core/src/main/java/org/apache/brooklyn/location/ssh/SshMachineLocation.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/location/ssh/SshMachineLocation.java b/core/src/main/java/org/apache/brooklyn/location/ssh/SshMachineLocation.java
index b66c94c..de7b7a8 100644
--- a/core/src/main/java/org/apache/brooklyn/location/ssh/SshMachineLocation.java
+++ b/core/src/main/java/org/apache/brooklyn/location/ssh/SshMachineLocation.java
@@ -72,6 +72,7 @@ import org.apache.brooklyn.core.location.access.PortForwardManagerLocationResolv
 import org.apache.brooklyn.core.mgmt.BrooklynTaskTags;
 import org.apache.brooklyn.core.mgmt.internal.LocalLocationManager;
 import org.apache.brooklyn.util.collections.MutableMap;
+import org.apache.brooklyn.util.core.ClassLoaderUtils;
 import org.apache.brooklyn.util.core.ResourceUtils;
 import org.apache.brooklyn.util.core.config.ConfigBag;
 import org.apache.brooklyn.util.core.crypto.SecureKeys;
@@ -688,7 +689,7 @@ public class SshMachineLocation extends AbstractLocation implements MachineLocat
                 }
             }
             if (sshToolClass==null) sshToolClass = SshjTool.class.getName();
-            SshTool ssh = (SshTool) Class.forName(sshToolClass).getConstructor(Map.class).newInstance(args.getAllConfig());
+            SshTool ssh = (SshTool) new ClassLoaderUtils(this, getManagementContext()).loadClass(sshToolClass).getConstructor(Map.class).newInstance(args.getAllConfig());
 
             if (LOG.isTraceEnabled()) LOG.trace("using ssh-tool {} (of type {}); props ", ssh, sshToolClass);
 

http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/f3154764/core/src/main/java/org/apache/brooklyn/util/core/ClassLoaderUtils.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/util/core/ClassLoaderUtils.java b/core/src/main/java/org/apache/brooklyn/util/core/ClassLoaderUtils.java
new file mode 100644
index 0000000..5bbce8d
--- /dev/null
+++ b/core/src/main/java/org/apache/brooklyn/util/core/ClassLoaderUtils.java
@@ -0,0 +1,249 @@
+/*
+ * Copyright 2016 The Apache Software Foundation.
+ *
+ * Licensed 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.util.core;
+
+import java.util.List;
+import java.util.regex.Pattern;
+
+import javax.annotation.Nullable;
+
+import org.apache.brooklyn.api.catalog.CatalogItem;
+import org.apache.brooklyn.api.entity.Entity;
+import org.apache.brooklyn.api.mgmt.ManagementContext;
+import org.apache.brooklyn.api.mgmt.classloading.BrooklynClassLoadingContext;
+import org.apache.brooklyn.core.BrooklynVersion;
+import org.apache.brooklyn.core.catalog.internal.CatalogUtils;
+import org.apache.brooklyn.core.entity.EntityInternal;
+import org.apache.brooklyn.core.mgmt.ha.OsgiManager;
+import org.apache.brooklyn.core.mgmt.internal.ManagementContextInternal;
+import org.apache.brooklyn.util.core.osgi.Osgis;
+import org.apache.brooklyn.util.core.osgi.SystemFrameworkLoader;
+import org.apache.brooklyn.util.exceptions.Exceptions;
+import org.apache.brooklyn.util.guava.Maybe;
+import org.apache.brooklyn.util.osgi.SystemFramework;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.FrameworkUtil;
+import org.osgi.framework.launch.Framework;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.base.Predicate;
+
+public class ClassLoaderUtils {
+    /**
+     * White list format should be 
+     * <bundle symbolic name regex>[:<bundle version regex in dotted format (X.X.X.SNAPSHOT, instead of X.X.X-SNAPSHOT)>]
+     */
+    private static final String WHITE_LIST_DEFAULT = "org\\.apache\\.brooklyn\\..*:" + BrooklynVersion.get().replaceFirst("-", ".");
+    private static final String WHITE_LIST_KEY = "org.apache.brooklyn.classloader.fallback.bundles";
+    private static final String CLASS_NAME_DELIMITER = ":";
+    private static final Logger log = LoggerFactory.getLogger(ClassLoaderUtils.class);
+
+    // Class.forName gets the class loader from the calling class.
+    // We don't have access to the same reflection API so need to pass it explicitly.
+    private final Class<?> callingClass;
+    private final Entity entity;
+    private final ManagementContext mgmt;
+
+    public ClassLoaderUtils(Object callingObj, Entity entity) {
+        this(callingObj.getClass(), entity);
+    }
+    public ClassLoaderUtils(Object callingObj, @Nullable ManagementContext mgmt) {
+        this(callingObj.getClass(), mgmt);
+    }
+
+    public ClassLoaderUtils(Class<?> callingClass) {
+        this.callingClass = callingClass;
+        this.entity = null;
+        this.mgmt = null;
+    }
+
+    public ClassLoaderUtils(Class<?> callingClass, Entity entity) {
+        this.callingClass = callingClass;
+        this.entity = entity;
+        this.mgmt = ((EntityInternal)entity).getManagementContext();
+    }
+
+    public ClassLoaderUtils(Class<?> callingClass, @Nullable ManagementContext mgmt) {
+        this.callingClass = callingClass;
+        this.entity = null;
+        this.mgmt = mgmt;
+    }
+
+    public Class<?> loadClass(String name) throws ClassNotFoundException {
+        if (looksLikeBundledClassName(name)) {
+            String[] arr = name.split(CLASS_NAME_DELIMITER);
+            String symbolicName;
+            String version;
+            String className;
+            if (arr.length > 3) {
+                throw new IllegalStateException("'" + name + "' doesn't look like a class name and contains too many colons to be parsed as bundle:version:class triple.");
+            } else if (arr.length == 3) {
+                symbolicName = arr[0];
+                version = arr[1];
+                className = arr[2];
+            } else if (arr.length == 2) {
+                symbolicName = arr[0];
+                version = null;
+                className = arr[1];
+            } else {
+                throw new IllegalStateException("'" + name + "' contains a bundle:version:class delimiter, but only one of those specified");
+            }
+            return loadClass(symbolicName, version, className);
+        }
+
+        if (entity != null && mgmt != null) {
+            String catalogItemId = entity.getCatalogItemId();
+            if (catalogItemId != null) {
+                CatalogItem<?, ?> item = CatalogUtils.getCatalogItemOptionalVersion(mgmt, catalogItemId);
+                if (item != null) {
+                    BrooklynClassLoadingContext loader = CatalogUtils.newClassLoadingContext(mgmt, item);
+                    try {
+                        return loader.loadClass(name);
+                    } catch (IllegalStateException e) {
+                        ClassNotFoundException cnfe = Exceptions.getFirstThrowableOfType(e, ClassNotFoundException.class);
+                        NoClassDefFoundError ncdfe = Exceptions.getFirstThrowableOfType(e, NoClassDefFoundError.class);
+                        if (cnfe == null && ncdfe == null) {
+                            throw e;
+                        } else {
+                            // ignore, fall back to Class.forName(...)
+                        }
+                    }
+                } else {
+                    log.warn("Entity " + entity + " refers to non-existent catalog item " + catalogItemId + ". Trying to load class " + name);
+                }
+            }
+        }
+
+        try {
+            // Used instead of callingClass.getClassLoader() as it could be null (only for bootstrap classes)
+            return Class.forName(name, true, callingClass.getClassLoader());
+        } catch (ClassNotFoundException e) {
+        }
+
+        if (mgmt != null) {
+            try {
+                return mgmt.getCatalogClassLoader().loadClass(name);
+            } catch (ClassNotFoundException e) {
+            }
+        }
+
+        Class<?> cls = tryLoadFromBundleWhiteList(name);
+        if (cls != null) {
+            return cls;
+        } else {
+            throw new ClassNotFoundException("Class " + name + " not found on the application class path, nor in the bundle white list.");
+        }
+    }
+
+    public Class<?> loadClass(String symbolicName, @Nullable String version, String className) throws ClassNotFoundException {
+        Framework framework = getFramework();
+        if (framework != null) {
+            Maybe<Bundle> bundle = Osgis.bundleFinder(framework)
+                .symbolicName(symbolicName)
+                .version(version)
+                .find();
+            if (bundle.isAbsent() && version != null) {
+                bundle = Osgis.bundleFinder(framework)
+                    .symbolicName(symbolicName)
+                    // Convert X.X.X-SNAPSHOT to X.X.X.SNAPSHOT. Any better way to do it?
+                    .version(version.replace("-", "."))
+                    .find();
+            }
+            if (bundle.isAbsent()) {
+                throw new IllegalStateException("Bundle " + symbolicName + ":" + (version != null ? version : "any") + " not found to load class " + className);
+            }
+            return SystemFrameworkLoader.get().loadClassFromBundle(className, bundle.get());
+        } else {
+            return Class.forName(className);
+        }
+    }
+
+    protected Framework getFramework() {
+        if (mgmt != null) {
+            Maybe<OsgiManager> osgiManager = ((ManagementContextInternal)mgmt).getOsgiManager();
+            if (osgiManager.isPresent()) {
+                OsgiManager osgi = osgiManager.get();
+                return osgi.getFramework();
+            }
+        }
+
+        // Requires that caller code is executed AFTER loading bundle brooklyn-core
+        Bundle bundle = FrameworkUtil.getBundle(ClassLoaderUtils.class);
+        if (bundle != null) {
+            BundleContext bundleContext = bundle.getBundleContext();
+            return (Framework) bundleContext.getBundle(0);
+        } else {
+            return null;
+        }
+    }
+
+    private boolean looksLikeBundledClassName(String name) {
+        return name.indexOf(CLASS_NAME_DELIMITER) != -1;
+    }
+
+
+    private static class WhiteListBundlePredicate implements Predicate<Bundle> {
+        private Pattern symbolicName;
+        private Pattern version;
+
+        private WhiteListBundlePredicate(String symbolicName, String version) {
+            this.symbolicName = Pattern.compile(symbolicName);
+            this.version = version != null ? Pattern.compile(version) : null;
+        }
+
+        @Override
+        public boolean apply(Bundle input) {
+            return symbolicName.matcher(input.getSymbolicName()).matches() &&
+                    (version == null || version.matcher(input.getVersion().toString()).matches());
+        }
+    
+    }
+
+    private Class<?> tryLoadFromBundleWhiteList(String name) {
+        Framework framework = getFramework();
+        if (framework == null) {
+            return null;
+        }
+        List<Bundle> bundles = Osgis.bundleFinder(framework)
+            .satisfying(createBundleMatchingPredicate())
+            .findAll();
+        SystemFramework bundleLoader = SystemFrameworkLoader.get();
+        for (Bundle b : bundles) {
+            try {
+                return bundleLoader.loadClassFromBundle(name, b);
+            } catch (Exception e) {
+                Exceptions.propagateIfFatal(e);
+            }
+        }
+        return null;
+    }
+
+    protected WhiteListBundlePredicate createBundleMatchingPredicate() {
+        String whiteList = System.getProperty(WHITE_LIST_KEY, WHITE_LIST_DEFAULT);
+        String[] arr = whiteList.split(":");
+        String symbolicName = arr[0];
+        String version = null;
+        if (arr.length > 2) {
+            throw new IllegalStateException("Class loading fallback bundle white list '" + whiteList + "' not in the expected format <symbolic name regex>[:<version regex>].");
+        } else if (arr.length == 2) {
+            version = arr[1];
+        }
+        return new WhiteListBundlePredicate(symbolicName, version);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/f3154764/core/src/main/java/org/apache/brooklyn/util/core/flags/TypeCoercions.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/util/core/flags/TypeCoercions.java b/core/src/main/java/org/apache/brooklyn/util/core/flags/TypeCoercions.java
index 65f85d6..94a0991 100644
--- a/core/src/main/java/org/apache/brooklyn/util/core/flags/TypeCoercions.java
+++ b/core/src/main/java/org/apache/brooklyn/util/core/flags/TypeCoercions.java
@@ -18,9 +18,6 @@
  */
 package org.apache.brooklyn.util.core.flags;
 
-import groovy.lang.Closure;
-import groovy.time.TimeDuration;
-
 import java.lang.reflect.Constructor;
 import java.lang.reflect.Method;
 import java.lang.reflect.Modifier;
@@ -56,6 +53,7 @@ import org.apache.brooklyn.util.JavaGroovyEquivalents;
 import org.apache.brooklyn.util.collections.MutableSet;
 import org.apache.brooklyn.util.collections.QuorumCheck;
 import org.apache.brooklyn.util.collections.QuorumCheck.QuorumChecks;
+import org.apache.brooklyn.util.core.ClassLoaderUtils;
 import org.apache.brooklyn.util.core.task.Tasks;
 import org.apache.brooklyn.util.exceptions.Exceptions;
 import org.apache.brooklyn.util.guava.Maybe;
@@ -89,6 +87,9 @@ import com.google.common.net.HostAndPort;
 import com.google.common.primitives.Primitives;
 import com.google.common.reflect.TypeToken;
 
+import groovy.lang.Closure;
+import groovy.time.TimeDuration;
+
 @SuppressWarnings("rawtypes")
 public class TypeCoercions {
 
@@ -773,7 +774,7 @@ public class TypeCoercions {
             @Override
             public Class apply(final String input) {
                 try {
-                    return Class.forName(input);
+                    return new ClassLoaderUtils(this.getClass()).loadClass(input);
                 } catch (ClassNotFoundException e) {
                     throw Exceptions.propagate(e);
                 }

http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/f3154764/core/src/test/java/org/apache/brooklyn/core/objs/BasicSpecParameterFromClassTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/core/objs/BasicSpecParameterFromClassTest.java b/core/src/test/java/org/apache/brooklyn/core/objs/BasicSpecParameterFromClassTest.java
index be91c27..13c3977 100644
--- a/core/src/test/java/org/apache/brooklyn/core/objs/BasicSpecParameterFromClassTest.java
+++ b/core/src/test/java/org/apache/brooklyn/core/objs/BasicSpecParameterFromClassTest.java
@@ -23,7 +23,6 @@ import static org.testng.Assert.assertNotNull;
 
 import java.util.List;
 import java.util.Map;
-import java.util.Set;
 
 import org.apache.brooklyn.api.catalog.CatalogConfig;
 import org.apache.brooklyn.api.entity.Entity;
@@ -35,9 +34,9 @@ import org.apache.brooklyn.core.config.ConfigKeys;
 import org.apache.brooklyn.core.entity.AbstractEntity;
 import org.apache.brooklyn.core.entity.BrooklynConfigKeys;
 import org.apache.brooklyn.core.test.entity.LocalManagementContextForTests;
+import org.apache.brooklyn.util.core.ClassLoaderUtils;
 import org.testng.annotations.BeforeMethod;
 import org.testng.annotations.Test;
-import org.testng.collections.Sets;
 
 import com.google.common.base.Predicate;
 import com.google.common.collect.ImmutableMap;
@@ -94,7 +93,7 @@ public class BasicSpecParameterFromClassTest {
     
     @Test
     public void testDebug() throws ClassNotFoundException {
-        System.out.println(BasicSpecParameter.fromClass(mgmt,  Class.forName("org.apache.brooklyn.entity.stock.BasicApplication")));
+        System.out.println(BasicSpecParameter.fromClass(mgmt,  new ClassLoaderUtils(this.getClass()).loadClass("org.apache.brooklyn.entity.stock.BasicApplication")));
     }
 
     @Test

http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/f3154764/rest/rest-resources/src/main/java/org/apache/brooklyn/rest/resources/PolicyResource.java
----------------------------------------------------------------------
diff --git a/rest/rest-resources/src/main/java/org/apache/brooklyn/rest/resources/PolicyResource.java b/rest/rest-resources/src/main/java/org/apache/brooklyn/rest/resources/PolicyResource.java
index 2696440..0b8d2c2 100644
--- a/rest/rest-resources/src/main/java/org/apache/brooklyn/rest/resources/PolicyResource.java
+++ b/rest/rest-resources/src/main/java/org/apache/brooklyn/rest/resources/PolicyResource.java
@@ -21,7 +21,9 @@ package org.apache.brooklyn.rest.resources;
 import java.util.List;
 import java.util.Map;
 
+import javax.ws.rs.core.Context;
 import javax.ws.rs.core.Response;
+import javax.ws.rs.core.UriInfo;
 
 import org.apache.brooklyn.api.entity.Entity;
 import org.apache.brooklyn.api.policy.Policy;
@@ -35,6 +37,7 @@ import org.apache.brooklyn.rest.filter.HaHotStateRequired;
 import org.apache.brooklyn.rest.transform.ApplicationTransformer;
 import org.apache.brooklyn.rest.transform.PolicyTransformer;
 import org.apache.brooklyn.rest.util.WebResourceUtils;
+import org.apache.brooklyn.util.core.ClassLoaderUtils;
 import org.apache.brooklyn.util.exceptions.Exceptions;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -42,8 +45,6 @@ import org.slf4j.LoggerFactory;
 import com.google.common.base.Function;
 import com.google.common.collect.FluentIterable;
 import com.google.common.collect.Maps;
-import javax.ws.rs.core.Context;
-import javax.ws.rs.core.UriInfo;
 
 @HaHotStateRequired
 public class PolicyResource extends AbstractBrooklynRestResource implements PolicyApi {
@@ -86,7 +87,7 @@ public class PolicyResource extends AbstractBrooklynRestResource implements Poli
         Entity entity = brooklyn().getEntity(application, entityToken);
         Class<? extends Policy> policyType;
         try {
-            policyType = (Class<? extends Policy>) Class.forName(policyTypeName);
+            policyType = (Class<? extends Policy>) new ClassLoaderUtils(this, mgmt()).loadClass(policyTypeName);
         } catch (ClassNotFoundException e) {
             throw WebResourceUtils.badRequest("No policy with type %s found", policyTypeName);
         } catch (ClassCastException e) {

http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/f3154764/rest/rest-resources/src/main/java/org/apache/brooklyn/rest/security/provider/DelegatingSecurityProvider.java
----------------------------------------------------------------------
diff --git a/rest/rest-resources/src/main/java/org/apache/brooklyn/rest/security/provider/DelegatingSecurityProvider.java b/rest/rest-resources/src/main/java/org/apache/brooklyn/rest/security/provider/DelegatingSecurityProvider.java
index ca7fdf1..b374189 100644
--- a/rest/rest-resources/src/main/java/org/apache/brooklyn/rest/security/provider/DelegatingSecurityProvider.java
+++ b/rest/rest-resources/src/main/java/org/apache/brooklyn/rest/security/provider/DelegatingSecurityProvider.java
@@ -24,13 +24,14 @@ import java.util.concurrent.atomic.AtomicLong;
 
 import javax.servlet.http.HttpSession;
 
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
 import org.apache.brooklyn.api.mgmt.ManagementContext;
 import org.apache.brooklyn.config.StringConfigMap;
 import org.apache.brooklyn.core.internal.BrooklynProperties;
 import org.apache.brooklyn.rest.BrooklynWebConfig;
+import org.apache.brooklyn.util.core.ClassLoaderUtils;
 import org.apache.brooklyn.util.text.Strings;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 public class DelegatingSecurityProvider implements SecurityProvider {
 
@@ -85,15 +86,16 @@ public class DelegatingSecurityProvider implements SecurityProvider {
         log.info("REST using security provider " + className);
 
         try {
+            ClassLoaderUtils clu = new ClassLoaderUtils(this, mgmt);
             Class<? extends SecurityProvider> clazz;
             try {
-                clazz = (Class<? extends SecurityProvider>) Class.forName(className);
+                clazz = (Class<? extends SecurityProvider>) clu.loadClass(className);
             } catch (Exception e) {
                 String oldPackage = "brooklyn.web.console.security.";
                 if (className.startsWith(oldPackage)) {
                     className = Strings.removeFromStart(className, oldPackage);
                     className = DelegatingSecurityProvider.class.getPackage().getName() + "." + className;
-                    clazz = (Class<? extends SecurityProvider>) Class.forName(className);
+                    clazz = (Class<? extends SecurityProvider>) clu.loadClass(className);
                     log.warn("Deprecated package " + oldPackage + " detected; please update security provider to point to " + className);
                 } else throw e;
             }

http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/f3154764/software/base/src/main/java/org/apache/brooklyn/entity/resolve/HardcodedCatalogEntitySpecResolver.java
----------------------------------------------------------------------
diff --git a/software/base/src/main/java/org/apache/brooklyn/entity/resolve/HardcodedCatalogEntitySpecResolver.java b/software/base/src/main/java/org/apache/brooklyn/entity/resolve/HardcodedCatalogEntitySpecResolver.java
index 7d48643..e5a8b92 100644
--- a/software/base/src/main/java/org/apache/brooklyn/entity/resolve/HardcodedCatalogEntitySpecResolver.java
+++ b/software/base/src/main/java/org/apache/brooklyn/entity/resolve/HardcodedCatalogEntitySpecResolver.java
@@ -24,12 +24,14 @@ import java.util.Set;
 import org.apache.brooklyn.api.entity.Entity;
 import org.apache.brooklyn.api.entity.EntitySpec;
 import org.apache.brooklyn.api.mgmt.classloading.BrooklynClassLoadingContext;
+import org.apache.brooklyn.core.BrooklynVersion;
 import org.apache.brooklyn.core.resolve.entity.AbstractEntitySpecResolver;
 import org.apache.brooklyn.entity.brooklynnode.BrooklynNode;
 import org.apache.brooklyn.entity.group.DynamicCluster;
 import org.apache.brooklyn.entity.group.DynamicRegionsFabric;
 import org.apache.brooklyn.entity.java.VanillaJavaApp;
 import org.apache.brooklyn.entity.software.base.VanillaSoftwareProcess;
+import org.apache.brooklyn.util.core.ClassLoaderUtils;
 
 import com.google.common.base.CaseFormat;
 import com.google.common.base.Converter;
@@ -38,14 +40,17 @@ import com.google.common.collect.ImmutableMap;
 public class HardcodedCatalogEntitySpecResolver extends AbstractEntitySpecResolver {
     private static final String RESOLVER_NAME = "catalog";
 
-    private static final Map<String, String> CATALOG_TYPES = ImmutableMap.<String, String>builder()
-            .put("cluster", DynamicCluster.class.getName())
-            .put("fabric", DynamicRegionsFabric.class.getName())
-            .put("vanilla", VanillaSoftwareProcess.class.getName())
-            .put("software-process", VanillaSoftwareProcess.class.getName())
-            .put("java-app", VanillaJavaApp.class.getName())
-            .put("brooklyn-node", BrooklynNode.class.getName())
-            .put("web-app-cluster","org.apache.brooklyn.entity.webapp.ControlledDynamicWebAppCluster")
+    private static final Map<String, Class<? extends Entity>> CATALOG_CLASS_TYPES = ImmutableMap.<String, Class<? extends Entity>>builder()
+            .put("cluster", DynamicCluster.class)
+            .put("fabric", DynamicRegionsFabric.class)
+            .put("vanilla", VanillaSoftwareProcess.class)
+            .put("software-process", VanillaSoftwareProcess.class)
+            .put("java-app", VanillaJavaApp.class)
+            .put("brooklyn-node", BrooklynNode.class)
+            .build();
+
+    private static final Map<String, String> CATALOG_STRING_TYPES = ImmutableMap.<String, String>builder()
+            .put("web-app-cluster","org.apache.brooklyn.software-webapp:" + BrooklynVersion.get() + ":org.apache.brooklyn.entity.webapp.ControlledDynamicWebAppCluster")
             .build();
 
     // Allow catalog-type or CatalogType as service type string
@@ -58,39 +63,47 @@ public class HardcodedCatalogEntitySpecResolver extends AbstractEntitySpecResolv
     @Override
     protected boolean canResolve(String type, BrooklynClassLoadingContext loader) {
         String localType = getLocalType(type);
-        String specType = getImplementation(localType);
-        return specType != null;
+        return getImplementation(CATALOG_CLASS_TYPES, localType) != null ||
+                getImplementation(CATALOG_STRING_TYPES, localType) != null;
     }
 
     @Override
     public EntitySpec<?> resolve(String type, BrooklynClassLoadingContext loader, Set<String> encounteredTypes) {
         String localType = getLocalType(type);
-        String specType = getImplementation(localType);
-        if (specType != null) {
-            return buildSpec(specType);
-        } else {
-            return null;
+        Class<? extends Entity> specClassType = getImplementation(CATALOG_CLASS_TYPES, localType);
+        if (specClassType != null) {
+            return buildSpec(specClassType);
         }
+        String specStringType = getImplementation(CATALOG_STRING_TYPES, localType);
+        if (specStringType != null) {
+            return buildSpec(specStringType);
+        }
+        return null;
     }
 
-    private String getImplementation(String type) {
-        String specType = CATALOG_TYPES.get(type);
+    private <T> T getImplementation(Map<String, T> types, String type) {
+        T specType = types.get(type);
         if (specType != null) {
             return specType;
         } else {
-            return CATALOG_TYPES.get(FMT.convert(type));
+            return types.get(FMT.convert(type));
         }
     }
 
-    private EntitySpec<?> buildSpec(String specType) {
+    private EntitySpec<?> buildSpec(String specTypName) {
         // TODO is this hardcoded list deprecated? If so log a warning.
         try {
-            @SuppressWarnings("unchecked")
-            Class<Entity> specClass = (Class<Entity>)mgmt.getCatalogClassLoader().loadClass(specType);
-            return EntitySpec.create(specClass);
+            Class<?> specType = new ClassLoaderUtils(this.getClass()).loadClass(specTypName);
+            return buildSpec(specType);
         } catch (ClassNotFoundException e) {
-            throw new IllegalStateException("Unable to load hardcoded catalog type " + specType, e);
+            throw new IllegalStateException("Unable to load hardcoded catalog type " + specTypName, e);
         }
     }
 
+    protected EntitySpec<?> buildSpec(Class<?> specType) {
+        @SuppressWarnings("unchecked")
+        Class<Entity> specClass = (Class<Entity>)specType;
+        return EntitySpec.create(specClass);
+    }
+
 }

http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/f3154764/software/winrm/src/main/java/org/apache/brooklyn/location/winrm/WinRmMachineLocation.java
----------------------------------------------------------------------
diff --git a/software/winrm/src/main/java/org/apache/brooklyn/location/winrm/WinRmMachineLocation.java b/software/winrm/src/main/java/org/apache/brooklyn/location/winrm/WinRmMachineLocation.java
index 7a5b638..8d537ac 100644
--- a/software/winrm/src/main/java/org/apache/brooklyn/location/winrm/WinRmMachineLocation.java
+++ b/software/winrm/src/main/java/org/apache/brooklyn/location/winrm/WinRmMachineLocation.java
@@ -18,6 +18,9 @@
  */
 package org.apache.brooklyn.location.winrm;
 
+import static org.apache.brooklyn.core.config.ConfigKeys.newConfigKeyWithPrefix;
+import static org.apache.brooklyn.core.config.ConfigKeys.newStringConfigKey;
+
 import java.io.File;
 import java.io.FileInputStream;
 import java.io.FileNotFoundException;
@@ -29,7 +32,6 @@ import java.util.Set;
 
 import javax.annotation.Nullable;
 
-import com.google.common.annotations.Beta;
 import org.apache.brooklyn.api.location.MachineDetails;
 import org.apache.brooklyn.api.location.MachineLocation;
 import org.apache.brooklyn.api.location.OsDetails;
@@ -42,6 +44,7 @@ import org.apache.brooklyn.core.entity.BrooklynConfigKeys;
 import org.apache.brooklyn.core.location.AbstractLocation;
 import org.apache.brooklyn.core.location.access.PortForwardManager;
 import org.apache.brooklyn.core.location.access.PortForwardManagerLocationResolver;
+import org.apache.brooklyn.util.core.ClassLoaderUtils;
 import org.apache.brooklyn.util.core.config.ConfigBag;
 import org.apache.brooklyn.util.core.internal.ssh.SshTool;
 import org.apache.brooklyn.util.core.internal.winrm.WinRmTool;
@@ -55,6 +58,7 @@ import org.apache.commons.codec.binary.Base64;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import com.google.common.annotations.Beta;
 import com.google.common.base.Charsets;
 import com.google.common.base.Function;
 import com.google.common.base.Joiner;
@@ -66,9 +70,6 @@ import com.google.common.collect.Iterables;
 import com.google.common.net.HostAndPort;
 import com.google.common.reflect.TypeToken;
 
-import static org.apache.brooklyn.core.config.ConfigKeys.newConfigKeyWithPrefix;
-import static org.apache.brooklyn.core.config.ConfigKeys.newStringConfigKey;
-
 public class WinRmMachineLocation extends AbstractLocation implements MachineLocation {
 
     private static final Logger LOG = LoggerFactory.getLogger(WinRmMachineLocation.class);
@@ -353,7 +354,7 @@ public class WinRmMachineLocation extends AbstractLocation implements MachineLoc
             // look up tool class
             String toolClass = args.get(WINRM_TOOL_CLASS);
             if (toolClass == null) toolClass = Winrm4jTool.class.getName();
-            WinRmTool tool = (WinRmTool) Class.forName(toolClass).getConstructor(Map.class).newInstance(args.getAllConfig());
+            WinRmTool tool = (WinRmTool) new ClassLoaderUtils(this, getManagementContext()).loadClass(toolClass).getConstructor(Map.class).newInstance(args.getAllConfig());
 
             if (LOG.isTraceEnabled()) LOG.trace("using ssh-tool {} (of type {}); props ", tool, toolClass);
 


[3/5] brooklyn-server git commit: Replicate catalog.bom using standard default.catalog.bom

Posted by sv...@apache.org.
Replicate catalog.bom using standard default.catalog.bom

Loading catalog.bom from bundles is disabled due to not interacting with persistence nicely. Load same catalog items through the default.catalog.bom mechanism instead.


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

Branch: refs/heads/master
Commit: 1ecd7fe4626098cc85ea3ff3297e570c36372ba6
Parents: 2330de4
Author: Svetoslav Neykov <sv...@cloudsoftcorp.com>
Authored: Tue Jul 5 12:39:45 2016 +0300
Committer: Svetoslav Neykov <sv...@cloudsoftcorp.com>
Committed: Wed Jul 6 15:28:54 2016 +0300

----------------------------------------------------------------------
 karaf/apache-brooklyn/pom.xml                   |   9 +
 .../src/main/resources/etc/default.catalog.bom  | 416 +++++++++++++--
 karaf/features/src/main/feature/feature.xml     |  17 +-
 .../init/src/main/resources/catalog-classes.bom | 507 +++++++++++++++++++
 4 files changed, 898 insertions(+), 51 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/1ecd7fe4/karaf/apache-brooklyn/pom.xml
----------------------------------------------------------------------
diff --git a/karaf/apache-brooklyn/pom.xml b/karaf/apache-brooklyn/pom.xml
index 1851e3f..d1d23be 100755
--- a/karaf/apache-brooklyn/pom.xml
+++ b/karaf/apache-brooklyn/pom.xml
@@ -90,6 +90,15 @@
 
     <plugins>
       <plugin>
+          <groupId>org.apache.rat</groupId>
+          <artifactId>apache-rat-plugin</artifactId>
+          <configuration>
+              <excludes combine.children="append">
+                  <exclude>**/*.bom</exclude>
+              </excludes>
+          </configuration>
+      </plugin>
+      <plugin>
         <groupId>org.apache.karaf.tooling</groupId>
         <artifactId>karaf-maven-plugin</artifactId>
         <version>${karaf.version}</version>

http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/1ecd7fe4/karaf/apache-brooklyn/src/main/resources/etc/default.catalog.bom
----------------------------------------------------------------------
diff --git a/karaf/apache-brooklyn/src/main/resources/etc/default.catalog.bom b/karaf/apache-brooklyn/src/main/resources/etc/default.catalog.bom
index 6902a1f..8184c6e 100644
--- a/karaf/apache-brooklyn/src/main/resources/etc/default.catalog.bom
+++ b/karaf/apache-brooklyn/src/main/resources/etc/default.catalog.bom
@@ -1,54 +1,370 @@
-# 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.
 
+# this catalog bom is an illustration supplying a few useful sample items
+# and templates to get started using Brooklyn
 
 brooklyn.catalog:
-    version: "0.10.0-SNAPSHOT" # BROOKLYN_VERSION
-    items:
-    - id: server-template
-      itemType: template
-      name: "Template: Server"
-      description: |
-        Sample YAML to provision a server in a cloud with illustrative VM properties
-      item:
-        name: Server (Brooklyn Example)
-
-        # this basic example shows how Brooklyn can provision a single raw VM
-        # in the cloud or location of your choice
-
-        services:
-        - type:           org.apache.brooklyn.entity.software.base.EmptySoftwareProcess
-          name:           My VM
-
-        # location can be e.g. `softlayer` or `jclouds:openstack-nova:https://9.9.9.9:9999/v2.0/`,
-        # or `localhost` or `byon:(hosts="10.9.1.1,10.9.1.2,produser2@10.9.2.{10,11,20-29}")`
-        location:
-          jclouds:aws-ec2:
-            # edit these to use your credential (or delete if credentials specified in brooklyn.properties)
-            identity:     <REPLACE>
-            credential:   <REPLACE>
-
-            region:       eu-central-1
-
-            # we want Ubuntu, with a lot of RAM
-            osFamily:     ubuntu
-            minRam:       8gb
-
-            # set up this user and password (default is to authorize a public key)
-            user:         sample
-            password:     s4mpl3
+  version: "0.10.0-SNAPSHOT" # BROOKLYN_VERSION
+  items:
+  - brooklyn.libraries:
+    - name: org.apache.brooklyn.karaf-init
+      version: 0.10.0.SNAPSHOT # BROOKLYN_VERSION
+    include: classpath://catalog-classes.bom
 
+  - id: server
+    itemType: entity
+    description: |
+      Provision a server, with customizable provisioning.properties and credentials installed, 
+      but no other special software process or scripts executed.
+    item:
+      type: org.apache.brooklyn.entity.software.base.EmptySoftwareProcess
+      name: Server
+
+  - id: vanilla-bash-server
+    itemType: entity
+    description: |
+      Provision a server, with customizable provisioning.properties and credentials installed, 
+      but no other special software process or scripts executed.
+      The script should be supplied in "launch.command" as per docs on
+      org.apache.brooklyn.entity.software.base.VanillaSoftwareProcess.
+    item:
+      type: org.apache.brooklyn.entity.software.base.VanillaSoftwareProcess
+      name: Server with Launch Script (bash)
+
+  - id: load-balancer
+    itemType: entity
+    description: |
+      Create a load balancer which will point at members in the group entity
+      referred to by the config key "serverPool". 
+      The sensor advertising the port can be configured with the "member.sensor.portNumber" config key,
+      defaulting to `http.port`; all member entities which have published "service.up" will then be picked up.
+    item:
+      type: org.apache.brooklyn.entity.proxy.nginx.NginxController
+      name: Load Balancer (nginx)
+
+  - id: cluster
+    itemType: entity
+    description: |
+      Create a cluster of entities, resizable, with starting size "initialSize",
+      and using a spec supplied in the "memberSpec" key.
+    item:
+      type: org.apache.brooklyn.entity.group.DynamicCluster
+
+  - id: 1-server-template
+    itemType: template
+    name: "Template 1: Server"
+    description: |
+      Sample YAML to provision a server in a cloud with illustrative VM properties
+    item:
+      name: Server (Brooklyn Example)
+      
+      # this basic example shows how Brooklyn can provision a single raw VM
+      # in the cloud or location of your choice
+      
+      services:
+      - type:           server
+        name:           My VM
+      
+      # location can be e.g. `softlayer` or `jclouds:openstack-nova:https://9.9.9.9:9999/v2.0/`,
+      # or `localhost` or `byon:(hosts="10.9.1.1,10.9.1.2,produser2@10.9.2.{10,11,20-29}")` 
+      location:
+        jclouds:aws-ec2:
+          # edit these to use your credential (or delete if credentials specified in brooklyn.properties)      
+          identity:     <REPLACE>
+          credential:   <REPLACE>
+          
+          region:       eu-central-1
+          
+          # we want Ubuntu, with a lot of RAM
+          osFamily:     ubuntu
+          minRam:       8gb
+          
+          # set up this user and password (default is to authorize a public key)
+          user:         sample
+          password:     s4mpl3
+
+  - id: 2-bash-web-server-template
+    itemType: template
+    name: "Template 2: Bash Web Server"
+    description: |
+      Sample YAML building on Template 1, 
+      adding bash commands to launch a Python-based web server
+      on port 8020
+    item:
+      name: Python Web Server (Brooklyn Example)
+      
+      # this example builds on the previous one, 
+      # adding some scripts to initialize the VM
+      
+      services:
+      - type:           vanilla-bash-server
+        name:           My Bash Web Server VM
+        brooklyn.config:
+          install.command: |
+            # install python if not present
+            which python || \
+              { sudo apt-get update && sudo apt-get install python ; } || \
+              { sudo yum update && sudo yum install python ; } || \
+              { echo WARNING: cannot install python && exit 1 ; }
+
+          customize.command: |
+            # create the web page to serve
+            cat > index.html << EOF
+            
+            Hello world.
+            <p>
+            I am ${ENTITY_INFO}, ${MESSAGE:-a Brooklyn sample}.
+            <p>
+            Created at: `date`
+            <p>
+            I am running at ${HOSTNAME}, with on-box IP configuration:
+            <pre>
+            `ifconfig | grep inet`
+            </pre>
+            
+            EOF
+
+          launch.command: |
+            # launch in background (ensuring no streams open), and record PID to file
+            nohup python -m SimpleHTTPServer ${PORT:-8020} < /dev/null > output.txt 2>&1 &
+            echo $! > ${PID_FILE:-pid.txt}
+            sleep 5
+            ps -p `cat ${PID_FILE:-pid.txt}`
+            if [ $? -ne 0 ] ; then
+              cat output.txt
+              echo WARNING: python web server not running
+              exit 1
+            fi
+            
+          shell.env:
+            HOSTNAME:     $brooklyn:attributeWhenReady("host.name")
+            PORT:         $brooklyn:config("my.app.port")
+            ENTITY_INFO:  $brooklyn:component("this", "")
+            MESSAGE:      $brooklyn:config("my.message")
+            
+          # custom 
+          my.app.port:  8020
+          my.message:   "good to meet you"
+        
+        brooklyn.enrichers:
+        # publish the URL as a sensor; the GUI will pick this up (main.uri)
+        - type: org.apache.brooklyn.enricher.stock.Transformer
+          brooklyn.config:
+            uniqueTag: url-generator
+            enricher.sourceSensor: host.subnet.hostname
+            # use the definition from Attributes class, as it has a RendererHint so GUI makes it a link
+            enricher.targetSensor: $brooklyn:sensor("org.apache.brooklyn.core.entity.Attributes", "main.uri")
+            enricher.targetValue: 
+              $brooklyn:formatString:
+              - "http://%s:%s/" 
+              - $brooklyn:attributeWhenReady("host.subnet.hostname")
+              - $brooklyn:config("my.app.port")
+      
+      location:
+        jclouds:aws-ec2:
+          region:       eu-central-1
+          # edit these (or delete if credentials specified in brooklyn.properties)      
+          identity:     <REPLACE>
+          credential:   <REPLACE>
+        
+  - id: 3-bash-web-and-riak-template
+    itemType: template
+    name: "Template 3: Bash Web Server and Scaling Riak Cluster"
+    description: |
+      Sample YAML building on Template 2, 
+      composing that blueprint with a Riak cluster and injecting the URL
+    item:
+      name: Bash Web Server and Riak Cluster (Brooklyn Example)
+    
+      # this example *references* the previous one, 
+      # combining it with a stock blueprint for a Riak cluster,
+      # and shows how a sensor from the latter can be injected
+      
+      services:
+      
+      # reference template 2, overriding message to point at riak 
+      - type:           2-bash-web-server-template
+        brooklyn.config:
+          my.message:   $brooklyn:formatString("connected to Riak at %s",
+                            $brooklyn:entity("riak-cluster").attributeWhenReady("main.uri"))
+        # and clear the location defined there so it is taken from this template
+        locations:      []
+                            
+      # use the off-the-shelf Riak cluster
+      - type:           org.apache.brooklyn.entity.nosql.riak.RiakCluster
+        id:             riak-cluster
+        initialSize:    3
+        # and add a policy to scale based on ops per minute
+        brooklyn.policies:
+        - type: org.apache.brooklyn.policy.autoscaling.AutoScalerPolicy
+          brooklyn.config:
+            metric: riak.node.ops.1m.perNode
+            # more than 100 ops per second (6k/min) scales out, less than 50 scales back
+            # up to a max of 8 riak nodes here (can be changed in GUI / REST API afterwards)
+            metricLowerBound: 3000
+            metricUpperBound: 6000
+            minPoolSize: 3
+            maxPoolSize: 8
+            resizeUpStabilizationDelay: 30s
+            resizeDownStabilizationDelay: 5m
+          
+      location:
+        jclouds:aws-ec2:
+          region:       eu-central-1
+          # edit these (or delete if credentials specified in brooklyn.properties)      
+          identity:     <REPLACE>
+          credential:   <REPLACE>
+
+  - id: 4-resilient-bash-web-cluster-template
+    itemType: template
+    name: "Template 4: Resilient Load-Balanced Bash Web Cluster with Sensors"
+    description: |
+      Sample YAML to provision a cluster of the bash/python web server nodes,
+      with sensors configured, and a load balancer pointing at them,
+      and resilience policies for node replacement and scaling
+    item:
+      name: Resilient Load-Balanced Bash Web Cluster (Brooklyn Example)
+      
+      # this final example shows some of the advanced functionality:
+      # defining custom sensors, and a cluster with a "spec", 
+      # policies for resilience and scaling based on that sensor,
+      # and wiring a load balancer in front of the cluster
+      
+      # combining this with the riak cluster in the previous example
+      # is left as a suggested exercise for the user
+      
+      services:
+      
+      # define a cluster of the web nodes
+      - type:           cluster
+        name:           Cluster of Bash Web Nodes
+        id:             my-web-cluster
+        brooklyn.config:
+          initialSize:  1
+          memberSpec:
+            $brooklyn:entitySpec:
+              # template 2 is used as the spec for items in this cluster
+              # with a new message overwriting the previous,
+              # and a lot of sensors defined
+              type:           2-bash-web-server-template
+              name:           My Bash Web Server VM with Sensors
+              # and clear the location defined there so it is taken from this template
+              locations:      []
+              
+              brooklyn.config:
+                my.message:   "part of the cluster"
+              
+              brooklyn.initializers:
+              # make a simple request-count sensor, by counting the number of 200 responses in output.txt
+              - type: org.apache.brooklyn.core.sensor.ssh.SshCommandSensor
+                brooklyn.config:
+                  name: reqs.count
+                  targetType: int
+                  period: 5s
+                  command: "cat output.txt | grep HTTP | grep 200 | wc | awk '{print $1}'"
+              # and publish the port as a sensor so the load-balancer can pick it up
+              - type:           org.apache.brooklyn.core.sensor.StaticSensor
+                brooklyn.config:
+                  name:         app.port
+                  targetType:   int
+                  static.value: $brooklyn:config("my.app.port")
+              
+              brooklyn.enrichers:
+              # derive reqs.per_sec from reqs.count
+              - type: org.apache.brooklyn.enricher.stock.YamlTimeWeightedDeltaEnricher
+                brooklyn.config:
+                  enricher.sourceSensor: reqs.count
+                  enricher.targetSensor: reqs.per_sec
+                  enricher.delta.period: 1s
+              # and take an average over 30s for reqs.per_sec into reqs.per_sec.windowed_30s
+              - type: org.apache.brooklyn.enricher.stock.YamlRollingTimeWindowMeanEnricher
+                brooklyn.config:
+                  enricher.sourceSensor: reqs.per_sec
+                  enricher.targetSensor: reqs.per_sec.windowed_30s
+                  enricher.window.duration: 30s
+              
+              # emit failure sensor if a failure connecting to the service is sustained for 30s
+              - type: org.apache.brooklyn.policy.ha.ServiceFailureDetector
+                brooklyn.config:
+                  entityFailed.stabilizationDelay: 30s
+            
+              brooklyn.policies:
+              # restart if a failure is detected (with a max of one restart in 2m, sensor will propagate otherwise) 
+              - type: org.apache.brooklyn.policy.ha.ServiceRestarter
+                brooklyn.config:
+                  failOnRecurringFailuresInThisDuration: 2m
+        
+        # back at the cluster, create a total per-sec and some per-node average
+        brooklyn.enrichers:
+        - type: org.apache.brooklyn.enricher.stock.Aggregator
+          brooklyn.config:
+            enricher.sourceSensor: reqs.per_sec
+            enricher.targetSensor: reqs.per_sec
+            transformation: sum
+        - type: org.apache.brooklyn.enricher.stock.Aggregator
+          brooklyn.config:
+            enricher.sourceSensor: reqs.per_sec
+            enricher.targetSensor: reqs.per_sec.per_node
+            transformation: average
+        - type: org.apache.brooklyn.enricher.stock.Aggregator
+          brooklyn.config:
+            enricher.sourceSensor: reqs.per_sec.windowed_30s
+            enricher.targetSensor: reqs.per_sec.windowed_30s.per_node
+            transformation: average
+              
+        brooklyn.policies:
+        # resilience: if a per-node restart policy fails,
+        # just throw that node away and create a new one
+        - type: org.apache.brooklyn.policy.ha.ServiceReplacer
+        
+        # and scale based on reqs/sec
+        - type: org.apache.brooklyn.policy.autoscaling.AutoScalerPolicy
+          brooklyn.config:
+            # scale based on reqs/sec (though in a real-world situation, 
+            # reqs.per_sec.windowed_30s.per_node might be a better choice) 
+            metric: reqs.per_sec.per_node
+            
+            # really low numbers, so you can trigger a scale-out just by hitting reload a lot
+            metricUpperBound: 3
+            metricLowerBound: 1
+            
+            # sustain 3 reqs/sec for 2s and it will scale out
+            resizeUpStabilizationDelay: 2s
+            # only scale down when sustained for 1m
+            resizeDownStabilizationDelay: 1m
+      
+            maxPoolSize: 10
+            
+      # and add a load-balancer pointing at the cluster
+      - type:           load-balancer
+        id:             load-bal
+        brooklyn.config:
+          # point this load balancer at the cluster, specifying port to forward to
+          loadbalancer.serverpool:  $brooklyn:entity("my-web-cluster")
+          member.sensor.portNumber: app.port
+          # disable sticky sessions to allow easy validation of balancing via browser refresh
+          nginx.sticky: false
+      
+      brooklyn.enrichers:
+      # publish a few useful info sensors and KPI's to the root of the app
+      - type: org.apache.brooklyn.enricher.stock.Propagator
+        brooklyn.config:
+          uniqueTag:    propagate-load-balancer-url
+          producer:     $brooklyn:entity("load-bal")
+          propagating:
+          - main.uri
+      - type: org.apache.brooklyn.enricher.stock.Propagator
+        brooklyn.config:
+          uniqueTag:    propagate-reqs-per-sec
+          producer:     $brooklyn:entity("my-web-cluster")
+          propagating:
+          - reqs.per_sec
+          - reqs.per_sec.windowed_30s.per_node
+      
+      location:
+        jclouds:aws-ec2:
+          # edit these (or delete if credentials specified in brooklyn.properties)      
+          identity:     <REPLACE>
+          credential:   <REPLACE>
+          
+          region:       eu-central-1
+          minRam:       2gb

http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/1ecd7fe4/karaf/features/src/main/feature/feature.xml
----------------------------------------------------------------------
diff --git a/karaf/features/src/main/feature/feature.xml b/karaf/features/src/main/feature/feature.xml
index b1d7923..5473151 100644
--- a/karaf/features/src/main/feature/feature.xml
+++ b/karaf/features/src/main/feature/feature.xml
@@ -332,9 +332,24 @@
         <bundle dependency="true">mvn:com.google.guava/guava/${guava.version}</bundle>
     </feature>
 
+    <!-- Don't load all bundles out of the box in the long run. Let users cherry pick what they need. -->
+    <feature name="brooklyn-software-all" version="${project.version}" description="Brooklyn All Software Entities">
+        <feature>brooklyn-software-base</feature>
+        <feature>brooklyn-jmxmp-agent</feature>
+        <feature>brooklyn-jmxrmi-agent</feature>
+        <feature>brooklyn-software-network</feature>
+        <feature>brooklyn-software-cm</feature>
+        <feature>brooklyn-software-osgi</feature>
+        <feature>brooklyn-software-database</feature>
+        <feature>brooklyn-software-webapp</feature>
+        <feature>brooklyn-software-messaging</feature>
+        <feature>brooklyn-software-nosql</feature>
+        <feature>brooklyn-software-monitoring</feature>
+    </feature>
+
     <feature name="brooklyn-osgi-launcher" version="${project.version}" description="Brooklyn init">
         <feature>brooklyn-core</feature>
-        <feature>brooklyn-software-base</feature>
+        <feature>brooklyn-software-all</feature>
         <feature>brooklyn-locations-jclouds</feature>
         <bundle>mvn:org.apache.brooklyn/brooklyn-launcher-common/${project.version}</bundle>
         <bundle start-level="90">mvn:org.apache.brooklyn/brooklyn-karaf-init/${project.version}</bundle>

http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/1ecd7fe4/karaf/init/src/main/resources/catalog-classes.bom
----------------------------------------------------------------------
diff --git a/karaf/init/src/main/resources/catalog-classes.bom b/karaf/init/src/main/resources/catalog-classes.bom
new file mode 100644
index 0000000..82a4b95
--- /dev/null
+++ b/karaf/init/src/main/resources/catalog-classes.bom
@@ -0,0 +1,507 @@
+# 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.
+#
+brooklyn.catalog:
+  version: "0.10.0-SNAPSHOT" # BROOKLYN_VERSION
+  items:
+  - brooklyn.libraries:
+    - name: org.apache.brooklyn.core
+      version: "0.10.0.SNAPSHOT" # BROOKLYN_VERSION
+    itemType: entity
+    items:
+     - id: org.apache.brooklyn.entity.group.QuarantineGroup
+       item:
+         type: org.apache.brooklyn.entity.group.QuarantineGroup
+     - id: org.apache.brooklyn.entity.group.BasicGroup
+       item:
+         type: org.apache.brooklyn.entity.group.BasicGroup
+     - id: org.apache.brooklyn.entity.stock.BasicEntity
+       item:
+         type: org.apache.brooklyn.entity.stock.BasicEntity
+     - id: org.apache.brooklyn.entity.stock.DataEntity
+       item:
+         type: org.apache.brooklyn.entity.stock.DataEntity
+     - id: org.apache.brooklyn.entity.group.DynamicGroup
+       item:
+         type: org.apache.brooklyn.entity.group.DynamicGroup
+     - id: org.apache.brooklyn.entity.stock.DelegateEntity
+       item:
+         type: org.apache.brooklyn.entity.stock.DelegateEntity
+     - id: org.apache.brooklyn.entity.group.DynamicRegionsFabric
+       item:
+         type: org.apache.brooklyn.entity.group.DynamicRegionsFabric
+     - id: org.apache.brooklyn.core.server.entity.BrooklynMetrics
+       item:
+         type: org.apache.brooklyn.core.server.entity.BrooklynMetrics
+     - id: org.apache.brooklyn.entity.stock.BasicApplication
+       item:
+         type: org.apache.brooklyn.entity.stock.BasicApplication
+     - id: org.apache.brooklyn.entity.stock.BasicStartable
+       item:
+         type: org.apache.brooklyn.entity.stock.BasicStartable
+     - id: org.apache.brooklyn.entity.group.DynamicCluster
+       item:
+         type: org.apache.brooklyn.entity.group.DynamicCluster
+     - id: org.apache.brooklyn.entity.group.DynamicMultiGroup
+       item:
+         type: org.apache.brooklyn.entity.group.DynamicMultiGroup
+     - id: org.apache.brooklyn.entity.group.DynamicFabric
+       item:
+         type: org.apache.brooklyn.entity.group.DynamicFabric
+
+  - brooklyn.libraries:
+    - name: org.apache.brooklyn.policy
+      version: "0.10.0.SNAPSHOT" # BROOKLYN_VERSION
+    items:
+    - id: org.apache.brooklyn.policy.ha.ConnectionFailureDetector
+      itemType: policy
+      item:
+        type: org.apache.brooklyn.policy.ha.ConnectionFailureDetector
+        name: Connection Failure Detector
+        description: HA policy for monitoring a host:port, 
+    - id: org.apache.brooklyn.policy.ha.ServiceRestarter
+      itemType: policy
+      item:
+        type: org.apache.brooklyn.policy.ha.ServiceRestarter
+        name: Service Restarter
+        description: HA policy for restarting a service automatically, 
+    - id: org.apache.brooklyn.policy.ha.SshMachineFailureDetector
+      itemType: policy
+      item:
+        type: org.apache.brooklyn.policy.ha.SshMachineFailureDetector
+        name: Ssh Connectivity Failure Detector
+        description: HA policy for monitoring an SshMachine, 
+#    removed from catalog because it cannot currently be configured via catalog mechanisms
+#    - id: org.apache.brooklyn.policy.followthesun.FollowTheSunPool
+#      item:
+#        type: org.apache.brooklyn.policy.followthesun.FollowTheSunPool
+    - id: org.apache.brooklyn.policy.loadbalancing.BalanceableWorkerPool
+      itemType: entity
+      item:
+        type: org.apache.brooklyn.policy.loadbalancing.BalanceableWorkerPool
+    - id: org.apache.brooklyn.policy.ha.ServiceReplacer
+      itemType: policy
+      item:
+        type: org.apache.brooklyn.policy.ha.ServiceReplacer
+        name: Service Replacer
+        description: HA policy for replacing a failed member of a group
+    - id: org.apache.brooklyn.policy.loadbalancing.ItemsInContainersGroup
+      itemType: entity
+      item:
+        type: org.apache.brooklyn.policy.loadbalancing.ItemsInContainersGroup
+    - id: org.apache.brooklyn.policy.autoscaling.AutoScalerPolicy
+      itemType: policy
+      item:
+        type: org.apache.brooklyn.policy.autoscaling.AutoScalerPolicy
+        name: Auto-scaler
+        description: Policy that is attached to a Resizable entity and dynamically 
+
+  - brooklyn.libraries:
+    - name: org.apache.brooklyn.software-base
+      version: "0.10.0.SNAPSHOT" # BROOKLYN_VERSION
+    itemType: entity
+    items:
+    - id: org.apache.brooklyn.entity.machine.MachineEntity
+      item:
+        type: org.apache.brooklyn.entity.machine.MachineEntity
+        name: Machine Entity
+        description: Represents a machine, providing metrics about it (e.g. obtained from ssh)
+    - id: org.apache.brooklyn.entity.software.base.SameServerEntity
+      item:
+        type: org.apache.brooklyn.entity.software.base.SameServerEntity
+    - id: org.apache.brooklyn.entity.chef.ChefEntity
+      item:
+        type: org.apache.brooklyn.entity.chef.ChefEntity
+    - id: org.apache.brooklyn.entity.brooklynnode.BrooklynEntityMirror
+      item:
+        type: org.apache.brooklyn.entity.brooklynnode.BrooklynEntityMirror
+        name: Brooklyn Entity Mirror
+        description: Provides an entity which can sit in one brooklyn 
+    - id: org.apache.brooklyn.entity.software.base.EmptySoftwareProcess
+      item:
+        type: org.apache.brooklyn.entity.software.base.EmptySoftwareProcess
+    - id: org.apache.brooklyn.entity.software.base.EmptyWindowsProcess
+      item:
+        type: org.apache.brooklyn.entity.software.base.EmptyWindowsProcess
+    - id: org.apache.brooklyn.entity.software.base.VanillaWindowsProcess
+      item:
+        type: org.apache.brooklyn.entity.software.base.VanillaWindowsProcess
+        name: Vanilla Windows Process
+        description: A basic Windows entity configured with scripts, e.g. for launch, check-running and stop
+    - id: org.apache.brooklyn.entity.java.VanillaJavaApp
+      item:
+        type: org.apache.brooklyn.entity.java.VanillaJavaApp
+    - id: org.apache.brooklyn.entity.brooklynnode.BrooklynNode
+      item:
+        type: org.apache.brooklyn.entity.brooklynnode.BrooklynNode
+        name: Brooklyn Node
+        description: Deploys a Brooklyn management server
+    - id: org.apache.brooklyn.entity.brooklynnode.BrooklynCluster
+      item:
+        type: org.apache.brooklyn.entity.brooklynnode.BrooklynCluster
+    - id: org.apache.brooklyn.entity.brooklynnode.LocalBrooklynNode
+      item:
+        type: org.apache.brooklyn.entity.brooklynnode.LocalBrooklynNode
+    - id: org.apache.brooklyn.entity.software.base.VanillaSoftwareProcess
+      item:
+        type: org.apache.brooklyn.entity.software.base.VanillaSoftwareProcess
+        name: Vanilla Software Process
+        description: A software process configured with scripts, e.g. for launch, check-running and stop
+    - id: org.apache.brooklyn.entity.machine.pool.ServerPool
+      item:
+        type: org.apache.brooklyn.entity.machine.pool.ServerPool
+        name: Server Pool
+        description: Creates a pre-allocated server pool, which other applications can deploy to
+
+  - brooklyn.libraries:
+    - name: org.apache.brooklyn.software-webapp
+      version: "0.10.0.SNAPSHOT" # BROOKLYN_VERSION
+    itemType: entity
+    items:
+    - id: org.apache.brooklyn.entity.webapp.nodejs.NodeJsWebAppService
+      item:
+        type: org.apache.brooklyn.entity.webapp.nodejs.NodeJsWebAppService
+        name: Node.JS Application
+    - id: org.apache.brooklyn.entity.webapp.jboss.JBoss7Server
+      item:
+        type: org.apache.brooklyn.entity.webapp.jboss.JBoss7Server
+        name: JBoss Application Server 7
+        description: AS7 - an open source Java application server from JBoss
+    - id: org.apache.brooklyn.entity.proxy.nginx.UrlMapping
+      item:
+        type: org.apache.brooklyn.entity.proxy.nginx.UrlMapping
+    - id: org.apache.brooklyn.entity.webapp.DynamicWebAppFabric
+      item:
+        type: org.apache.brooklyn.entity.webapp.DynamicWebAppFabric
+    - id: org.apache.brooklyn.entity.proxy.nginx.NginxController
+      item:
+        type: org.apache.brooklyn.entity.proxy.nginx.NginxController
+        name: Nginx Server
+        description: A single Nginx server. Provides HTTP and reverse proxy services
+    - id: org.apache.brooklyn.entity.webapp.jboss.JBoss6Server
+      item:
+        type: org.apache.brooklyn.entity.webapp.jboss.JBoss6Server
+        name: JBoss Application Server 6
+        description: AS6 -  an open source Java application server from JBoss
+    - id: org.apache.brooklyn.entity.webapp.tomcat.Tomcat8Server
+      item:
+        type: org.apache.brooklyn.entity.webapp.tomcat.Tomcat8Server
+        name: Tomcat Server
+    - id: org.apache.brooklyn.entity.proxy.LoadBalancerCluster
+      item:
+        type: org.apache.brooklyn.entity.proxy.LoadBalancerCluster
+    - id: org.apache.brooklyn.entity.webapp.jetty.Jetty6Server
+      item:
+        type: org.apache.brooklyn.entity.webapp.jetty.Jetty6Server
+        name: Jetty6 Server
+        description: Old version (v6 @ Mortbay) of the popular Jetty webapp container
+    - id: org.apache.brooklyn.entity.webapp.DynamicWebAppCluster
+      item:
+        type: org.apache.brooklyn.entity.webapp.DynamicWebAppCluster
+        name: Dynamic Web-app Cluster
+        description: A cluster of web-apps, which can be dynamically re-sized; this does not include a load-balancer
+    - id: org.apache.brooklyn.entity.webapp.tomcat.TomcatServer
+      item:
+        type: org.apache.brooklyn.entity.webapp.tomcat.TomcatServer
+        name: Tomcat Server
+    - id: org.apache.brooklyn.entity.dns.geoscaling.GeoscalingDnsService
+      item:
+        type: org.apache.brooklyn.entity.dns.geoscaling.GeoscalingDnsService
+    - id: org.apache.brooklyn.entity.webapp.ControlledDynamicWebAppCluster
+      item:
+        type: org.apache.brooklyn.entity.webapp.ControlledDynamicWebAppCluster
+        name: Controlled Dynamic Web-app Cluster
+        description: A cluster of load-balanced web-apps, which can be dynamically re-sized
+
+  - brooklyn.libraries:
+    - name: org.apache.brooklyn.software-osgi
+      version: "0.10.0.SNAPSHOT" # BROOKLYN_VERSION
+    itemType: entity
+    items:
+    - id: org.apache.brooklyn.entity.osgi.karaf.KarafContainer
+      item:
+        type: org.apache.brooklyn.entity.osgi.karaf.KarafContainer
+        name: Karaf
+        description: Apache Karaf is a small OSGi based runtime which provides a lightweight container onto which various components and applications can be deployed.
+
+  - brooklyn.libraries:
+    - name: org.apache.brooklyn.software-nosql
+      version: "0.10.0.SNAPSHOT" # BROOKLYN_VERSION
+    itemType: entity
+    items:
+    - id: org.apache.brooklyn.entity.nosql.redis.RedisStore
+      item:
+        type: org.apache.brooklyn.entity.nosql.redis.RedisStore
+        name: Redis Server
+        description: Redis is an open-source, networked, in-memory, key-value data store with optional durability
+    - id: org.apache.brooklyn.entity.nosql.mongodb.sharding.MongoDBRouterCluster
+      item:
+        type: org.apache.brooklyn.entity.nosql.mongodb.sharding.MongoDBRouterCluster
+    - id: org.apache.brooklyn.entity.nosql.cassandra.CassandraDatacenter
+      item:
+        type: org.apache.brooklyn.entity.nosql.cassandra.CassandraDatacenter
+        name: Apache Cassandra Datacenter Cluster
+        description: Cassandra is a highly scalable, eventually 
+    - id: org.apache.brooklyn.entity.nosql.solr.SolrServer
+      item:
+        type: org.apache.brooklyn.entity.nosql.solr.SolrServer
+        name: Apache Solr Node
+        description: Solr is the popular, blazing fast open source enterprise search 
+    - id: org.apache.brooklyn.entity.nosql.couchdb.CouchDBNode
+      item:
+        type: org.apache.brooklyn.entity.nosql.couchdb.CouchDBNode
+        name: CouchDB Node
+    - id: org.apache.brooklyn.entity.nosql.redis.RedisShard
+      item:
+        type: org.apache.brooklyn.entity.nosql.redis.RedisShard
+    - id: org.apache.brooklyn.entity.nosql.redis.RedisCluster
+      item:
+        type: org.apache.brooklyn.entity.nosql.redis.RedisCluster
+        name: Redis Cluster
+        description: Redis is an open-source, networked, in-memory, key-value data store with optional durability
+    - id: org.apache.brooklyn.entity.nosql.hazelcast.HazelcastCluster
+      item:
+        type: org.apache.brooklyn.entity.nosql.hazelcast.HazelcastCluster
+        name: Hazelcast Cluster
+        description: Hazelcast is a clustering and highly scalable data distribution platform for Java.
+    - id: org.apache.brooklyn.entity.nosql.couchdb.CouchDBCluster
+      item:
+        type: org.apache.brooklyn.entity.nosql.couchdb.CouchDBCluster
+    - id: org.apache.brooklyn.entity.nosql.couchbase.CouchbaseNode
+      item:
+        type: org.apache.brooklyn.entity.nosql.couchbase.CouchbaseNode
+        name: CouchBase Node
+        description: Couchbase Server is an open source, distributed (shared-nothing architecture) 
+    - id: org.apache.brooklyn.entity.nosql.mongodb.sharding.MongoDBShardedDeployment
+      item:
+        type: org.apache.brooklyn.entity.nosql.mongodb.sharding.MongoDBShardedDeployment
+        name: MongoDB Sharded Deployment
+    - id: org.apache.brooklyn.entity.nosql.cassandra.CassandraNode
+      item:
+        type: org.apache.brooklyn.entity.nosql.cassandra.CassandraNode
+        name: Apache Cassandra Node
+        description: Cassandra is a highly scalable, eventually 
+    - id: org.apache.brooklyn.entity.nosql.riak.RiakNode
+      item:
+        type: org.apache.brooklyn.entity.nosql.riak.RiakNode
+        name: Riak Node
+        description: Riak is a distributed NoSQL key-value data store that offers 
+    - id: org.apache.brooklyn.entity.nosql.mongodb.sharding.MongoDBConfigServerCluster
+      item:
+        type: org.apache.brooklyn.entity.nosql.mongodb.sharding.MongoDBConfigServerCluster
+    - id: org.apache.brooklyn.entity.nosql.mongodb.MongoDBServer
+      item:
+        type: org.apache.brooklyn.entity.nosql.mongodb.MongoDBServer
+        name: MongoDB Server
+    - id: org.apache.brooklyn.entity.nosql.mongodb.sharding.MongoDBRouter
+      item:
+        type: org.apache.brooklyn.entity.nosql.mongodb.sharding.MongoDBRouter
+        name: MongoDB Router
+    - id: org.apache.brooklyn.entity.nosql.mongodb.MongoDBReplicaSet
+      item:
+        type: org.apache.brooklyn.entity.nosql.mongodb.MongoDBReplicaSet
+    - id: org.apache.brooklyn.entity.nosql.mongodb.sharding.MongoDBShardCluster
+      item:
+        type: org.apache.brooklyn.entity.nosql.mongodb.sharding.MongoDBShardCluster
+    - id: org.apache.brooklyn.entity.nosql.mongodb.MongoDBClient
+      item:
+        type: org.apache.brooklyn.entity.nosql.mongodb.MongoDBClient
+    - id: org.apache.brooklyn.entity.nosql.elasticsearch.ElasticSearchNode
+      item:
+        type: org.apache.brooklyn.entity.nosql.elasticsearch.ElasticSearchNode
+        name: Elastic Search Node
+        description: Elasticsearch is an open-source search server based on Lucene. 
+    - id: org.apache.brooklyn.entity.nosql.cassandra.CassandraFabric
+      item:
+        type: org.apache.brooklyn.entity.nosql.cassandra.CassandraFabric
+        name: Apache Cassandra Database Fabric
+        description: Cassandra is a highly scalable, eventually 
+    - id: org.apache.brooklyn.entity.nosql.elasticsearch.ElasticSearchCluster
+      item:
+        type: org.apache.brooklyn.entity.nosql.elasticsearch.ElasticSearchCluster
+        name: Elastic Search Cluster
+        description: Elasticsearch is an open-source search server based on Lucene. 
+    - id: org.apache.brooklyn.entity.nosql.cassandra.CassandraCluster
+      item:
+        type: org.apache.brooklyn.entity.nosql.cassandra.CassandraCluster
+    - id: org.apache.brooklyn.entity.nosql.redis.RedisSlave
+      item:
+        type: org.apache.brooklyn.entity.nosql.redis.RedisSlave
+    - id: org.apache.brooklyn.entity.nosql.mongodb.sharding.MongoDBConfigServer
+      item:
+        type: org.apache.brooklyn.entity.nosql.mongodb.sharding.MongoDBConfigServer
+    - id: org.apache.brooklyn.entity.nosql.couchbase.CouchbaseCluster
+      item:
+        type: org.apache.brooklyn.entity.nosql.couchbase.CouchbaseCluster
+        name: CouchBase Cluster
+        description: Couchbase is an open source, distributed (shared-nothing architecture) 
+    - id: org.apache.brooklyn.entity.nosql.couchbase.CouchbaseSyncGateway
+      item:
+        type: org.apache.brooklyn.entity.nosql.couchbase.CouchbaseSyncGateway
+    - id: org.apache.brooklyn.entity.nosql.hazelcast.HazelcastNode
+      item:
+        type: org.apache.brooklyn.entity.nosql.hazelcast.HazelcastNode
+        name: Hazelcast Node
+        description: Hazelcast is a clustering and highly scalable data distribution platform for Java.
+    - id: org.apache.brooklyn.entity.nosql.riak.RiakCluster
+      item:
+        type: org.apache.brooklyn.entity.nosql.riak.RiakCluster
+        name: Riak Cluster
+        description: Riak is a distributed NoSQL key-value data store that offers 
+    - id: org.apache.brooklyn.entity.nosql.mongodb.sharding.CoLocatedMongoDBRouter
+      item:
+        type: org.apache.brooklyn.entity.nosql.mongodb.sharding.CoLocatedMongoDBRouter
+
+  - brooklyn.libraries:
+    - name: org.apache.brooklyn.software-network
+      version: "0.10.0.SNAPSHOT" # BROOKLYN_VERSION
+    itemType: entity
+    items:
+    - id: org.apache.brooklyn.entity.network.bind.BindDnsServer
+      description: BIND is an Internet Domain Name Server.
+      item:
+        type: org.apache.brooklyn.entity.network.bind.BindDnsServer
+        name: BIND
+
+  - brooklyn.libraries:
+    - name: org.apache.brooklyn.software-monitoring
+      version: "0.10.0.SNAPSHOT" # BROOKLYN_VERSION
+    itemType: entity
+    items:
+    - id: org.apache.brooklyn.entity.monitoring.monit.MonitNode
+      item:
+        type: org.apache.brooklyn.entity.monitoring.monit.MonitNode
+        name: Monit Node
+        description: Monit is a free open source utility for managing and monitoring, processes, programs, files, directories and filesystems on a UNIX system
+
+  - brooklyn.libraries:
+    - name: org.apache.brooklyn.software-messaging
+      version: "0.10.0.SNAPSHOT" # BROOKLYN_VERSION
+    itemType: entity
+    items:
+    - id: org.apache.brooklyn.entity.messaging.activemq.ActiveMQBroker
+      item:
+        type: org.apache.brooklyn.entity.messaging.activemq.ActiveMQBroker
+        name: ActiveMQ Broker
+        description: ActiveMQ is an open source message broker which fully implements the Java Message Service 1.1 (JMS)
+    - id: org.apache.brooklyn.entity.messaging.qpid.QpidBroker
+      item:
+        type: org.apache.brooklyn.entity.messaging.qpid.QpidBroker
+        name: Qpid Broker
+        description: Apache Qpid is an open-source messaging system, implementing the Advanced Message Queuing Protocol (AMQP)
+    - id: org.apache.brooklyn.entity.messaging.storm.Storm
+      item:
+        type: org.apache.brooklyn.entity.messaging.storm.Storm
+        name: Storm Node
+        description: Apache Storm is a distributed realtime computation system. 
+    - id: org.apache.brooklyn.entity.messaging.kafka.KafkaCluster
+      item:
+        type: org.apache.brooklyn.entity.messaging.kafka.KafkaCluster
+        name: Kafka
+        description: Apache Kafka is a distributed publish-subscribe messaging system
+    - id: org.apache.brooklyn.entity.messaging.activemq.ActiveMQQueue
+      item:
+        type: org.apache.brooklyn.entity.messaging.activemq.ActiveMQQueue
+    - id: org.apache.brooklyn.entity.zookeeper.ZooKeeperEnsemble
+      item:
+        type: org.apache.brooklyn.entity.zookeeper.ZooKeeperEnsemble
+        name: ZooKeeper ensemble
+        description: A cluster of ZooKeeper servers. 
+    - id: org.apache.brooklyn.entity.messaging.kafka.KafkaZooKeeper
+      item:
+        type: org.apache.brooklyn.entity.messaging.kafka.KafkaZooKeeper
+    - id: org.apache.brooklyn.entity.messaging.activemq.ActiveMQTopic
+      item:
+        type: org.apache.brooklyn.entity.messaging.activemq.ActiveMQTopic
+    - id: org.apache.brooklyn.entity.messaging.qpid.QpidQueue
+      item:
+        type: org.apache.brooklyn.entity.messaging.qpid.QpidQueue
+    - id: org.apache.brooklyn.entity.zookeeper.ZooKeeperNode
+      item:
+        type: org.apache.brooklyn.entity.zookeeper.ZooKeeperNode
+        name: ZooKeeper Node
+        description: Apache ZooKeeper is a server which enables 
+    - id: org.apache.brooklyn.entity.messaging.rabbit.RabbitBroker
+      item:
+        type: org.apache.brooklyn.entity.messaging.rabbit.RabbitBroker
+        name: RabbitMQ Broker
+        description: RabbitMQ is an open source message broker software (i.e. message-oriented middleware) that implements the Advanced Message Queuing Protocol (AMQP) standard
+    - id: org.apache.brooklyn.entity.messaging.kafka.KafkaBroker
+      item:
+        type: org.apache.brooklyn.entity.messaging.kafka.KafkaBroker
+    - id: org.apache.brooklyn.entity.messaging.qpid.QpidTopic
+      item:
+        type: org.apache.brooklyn.entity.messaging.qpid.QpidTopic
+    - id: org.apache.brooklyn.entity.messaging.storm.StormDeployment
+      item:
+        type: org.apache.brooklyn.entity.messaging.storm.StormDeployment
+        name: Storm Deployment
+        description: A Storm cluster. Apache Storm is a distributed realtime computation system. 
+
+  - brooklyn.libraries:
+    - name: org.apache.brooklyn.software-database
+      version: "0.10.0.SNAPSHOT" # BROOKLYN_VERSION
+    itemType: entity
+    items:
+    - id: org.apache.brooklyn.entity.database.crate.CrateNode
+      item:
+        type: org.apache.brooklyn.entity.database.crate.CrateNode
+    - id: org.apache.brooklyn.entity.database.mysql.MySqlNode
+      item:
+        type: org.apache.brooklyn.entity.database.mysql.MySqlNode
+        name: MySql Node
+        description: MySql is an open source relational database management system (RDBMS)
+    - id: org.apache.brooklyn.entity.database.mysql.MySqlCluster
+      item:
+        type: org.apache.brooklyn.entity.database.mysql.MySqlCluster
+        name: MySql Master-Slave cluster
+        description: Sets up a cluster of MySQL nodes using master-slave relation and binary logging
+    - id: org.apache.brooklyn.entity.database.postgresql.PostgreSqlNode
+      item:
+        type: org.apache.brooklyn.entity.database.postgresql.PostgreSqlNode
+        name: PostgreSQL Node
+        description: PostgreSQL is an object-relational database management system (ORDBMS)
+    - id: org.apache.brooklyn.entity.database.rubyrep.RubyRepNode
+      item:
+        type: org.apache.brooklyn.entity.database.rubyrep.RubyRepNode
+    - id: org.apache.brooklyn.entity.database.mariadb.MariaDbNode
+      item:
+        type: org.apache.brooklyn.entity.database.mariadb.MariaDbNode
+        name: MariaDB Node
+        description: MariaDB is an open source relational database management system (RDBMS)
+
+  - brooklyn.libraries:
+    - name: org.apache.brooklyn.software-cm-salt
+      version: "0.10.0.SNAPSHOT" # BROOKLYN_VERSION
+    itemType: entity
+    items:
+    - id: org.apache.brooklyn.entity.cm.salt.SaltEntity
+      item:
+        type: org.apache.brooklyn.entity.cm.salt.SaltEntity
+        name: SaltEntity
+        description: Software managed by Salt CM
+
+  - brooklyn.libraries:
+    - name: org.apache.brooklyn.software-cm-ansible
+      version: "0.10.0.SNAPSHOT" # BROOKLYN_VERSION
+    itemType: entity
+    items:
+    - id: org.apache.brooklyn.entity.cm.ansible.AnsibleEntity
+      item:
+        type: org.apache.brooklyn.entity.cm.ansible.AnsibleEntity
+        name: AnsibleEntity
+        description: Software managed by Ansible CM