You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@brooklyn.apache.org by sj...@apache.org on 2015/10/15 16:02:34 UTC

[13/16] incubator-brooklyn git commit: Rename entity resolvers to better match their functionality, now that they are CAMP independent

Rename entity resolvers to better match their functionality, now that they are CAMP independent


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

Branch: refs/heads/master
Commit: 1db88751e131011ff96625753e50e8942825dbcc
Parents: 5fe288f
Author: Svetoslav Neykov <sv...@cloudsoftcorp.com>
Authored: Thu Oct 15 13:01:07 2015 +0300
Committer: Svetoslav Neykov <sv...@cloudsoftcorp.com>
Committed: Thu Oct 15 13:32:59 2015 +0300

----------------------------------------------------------------------
 .../resolve/AbstractServiceSpecResolver.java    |  65 ----------
 .../resolve/CatalogServiceSpecResolver.java     | 101 ---------------
 .../resolve/DelegatingServiceSpecResolver.java  | 127 -------------------
 .../core/resolve/JavaServiceSpecResolver.java   |  91 -------------
 .../core/resolve/ServiceSpecResolver.java       |  67 ----------
 .../entity/AbstractEntitySpecResolver.java      |  65 ++++++++++
 .../entity/CatalogEntitySpecResolver.java       |  99 +++++++++++++++
 .../entity/DelegatingEntitySpecResolver.java    | 127 +++++++++++++++++++
 .../core/resolve/entity/EntitySpecResolver.java |  67 ++++++++++
 .../resolve/entity/JavaEntitySpecResolver.java  |  91 +++++++++++++
 ...he.brooklyn.core.resolve.ServiceSpecResolver |  20 ---
 ...oklyn.core.resolve.entity.EntitySpecResolver |  20 +++
 .../entity/resolve/ChefEntitySpecResolver.java  |  42 ++++++
 .../entity/resolve/ChefServiceSpecResolver.java |  42 ------
 .../HardcodedCatalogEntitySpecResolver.java     |  96 ++++++++++++++
 .../HardcodedCatalogServiceSpecResolver.java    |  96 --------------
 ...he.brooklyn.core.resolve.ServiceSpecResolver |  20 ---
 ...oklyn.core.resolve.entity.EntitySpecResolver |  20 +++
 .../BrooklynComponentTemplateResolver.java      |   8 +-
 .../camp/brooklyn/spi/creation/CampUtils.java   |   2 +-
 .../service/BrooklynServiceTypeResolver.java    |   4 +-
 .../service/CampServiceSpecResolver.java        |  14 +-
 .../creation/service/ServiceTypeResolver.java   |   4 +-
 .../service/ServiceTypeResolverAdaptor.java     |   8 +-
 .../service/UrlServiceSpecResolver.java         |   4 +-
 25 files changed, 649 insertions(+), 651 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/1db88751/core/src/main/java/org/apache/brooklyn/core/resolve/AbstractServiceSpecResolver.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/core/resolve/AbstractServiceSpecResolver.java b/core/src/main/java/org/apache/brooklyn/core/resolve/AbstractServiceSpecResolver.java
deleted file mode 100644
index 78c796a..0000000
--- a/core/src/main/java/org/apache/brooklyn/core/resolve/AbstractServiceSpecResolver.java
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.brooklyn.core.resolve;
-
-import java.util.Set;
-
-import org.apache.brooklyn.api.entity.EntitySpec;
-import org.apache.brooklyn.api.mgmt.ManagementContext;
-import org.apache.brooklyn.core.mgmt.classloading.BrooklynClassLoadingContext;
-import org.apache.brooklyn.util.text.Strings;
-
-public abstract class AbstractServiceSpecResolver implements ServiceSpecResolver {
-    private static final String PREFIX_DELIMITER = ":";
-    protected final String name;
-    protected final String prefix;
-    protected ManagementContext mgmt;
-
-    public AbstractServiceSpecResolver(String name) {
-        this.name = name;
-        this.prefix = name + PREFIX_DELIMITER;
-    }
-
-    @Override
-    public String getName() {
-        return name;
-    }
-
-    @Override
-    public boolean accepts(String type, BrooklynClassLoadingContext loader) {
-        return type.startsWith(prefix) && canResolve(type, loader);
-    }
-
-    protected boolean canResolve(String type, BrooklynClassLoadingContext loader) {
-        return true;
-    }
-
-    protected String getLocalType(String type) {
-        return Strings.removeFromStart(type, prefix).trim();
-    }
-
-    @Override
-    public void injectManagementContext(ManagementContext mgmt) {
-        this.mgmt = mgmt;
-    }
-
-    @Override
-    public abstract EntitySpec<?> resolve(String type, BrooklynClassLoadingContext loader, Set<String> encounteredTypes);
-
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/1db88751/core/src/main/java/org/apache/brooklyn/core/resolve/CatalogServiceSpecResolver.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/core/resolve/CatalogServiceSpecResolver.java b/core/src/main/java/org/apache/brooklyn/core/resolve/CatalogServiceSpecResolver.java
deleted file mode 100644
index ded4ed3..0000000
--- a/core/src/main/java/org/apache/brooklyn/core/resolve/CatalogServiceSpecResolver.java
+++ /dev/null
@@ -1,101 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.brooklyn.core.resolve;
-
-import java.util.Set;
-
-import org.apache.brooklyn.api.catalog.CatalogItem;
-import org.apache.brooklyn.api.entity.Entity;
-import org.apache.brooklyn.api.entity.EntitySpec;
-import org.apache.brooklyn.api.internal.AbstractBrooklynObjectSpec;
-import org.apache.brooklyn.api.mgmt.ManagementContext;
-import org.apache.brooklyn.core.catalog.internal.CatalogUtils;
-import org.apache.brooklyn.core.mgmt.EntityManagementUtils;
-import org.apache.brooklyn.core.mgmt.classloading.BrooklynClassLoadingContext;
-import org.apache.brooklyn.core.mgmt.persist.DeserializingClassRenamesProvider;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import com.google.common.collect.ImmutableSet;
-
-public class CatalogServiceSpecResolver extends AbstractServiceSpecResolver {
-    private static final Logger log = LoggerFactory.getLogger(CatalogServiceSpecResolver.class);
-
-    private static final String RESOLVER_NAME = "catalog";
-
-    public CatalogServiceSpecResolver() {
-        super(RESOLVER_NAME);
-    }
-
-    @Override
-    protected boolean canResolve(String type, BrooklynClassLoadingContext loader) {
-        String localType = getLocalType(type);
-        CatalogItem<Entity, EntitySpec<?>> item = getCatalogItem(mgmt, localType);
-        if (item != null) {
-            try {
-                //Keeps behaviour of previous functionality, but probably should throw instead when using disabled items.
-                checkUsable(item);
-                return true;
-            } catch (IllegalStateException e) {
-                return false;
-            }
-        } else {
-            return false;
-        }
-    }
-
-    @Override
-    public EntitySpec<?> resolve(String type, BrooklynClassLoadingContext loader, Set<String> parentEncounteredTypes) {
-        String localType = getLocalType(type);
-        CatalogItem<Entity, EntitySpec<?>> item = getCatalogItem(mgmt, localType);
-
-        if (item == null) return null;
-        checkUsable(item);
-
-        //Take the symbolicName part of the catalog item only for recursion detection to prevent
-        //cross referencing of different versions. Not interested in non-catalog item types.
-        //Prevent catalog items self-referencing even if explicitly different version.
-        boolean nonRecursiveCall = !parentEncounteredTypes.contains(item.getSymbolicName());
-        if (nonRecursiveCall) {
-            // CatalogItem generics are just getting in the way, better get rid of them, we
-            // are casting anyway.
-            @SuppressWarnings({ "rawtypes" })
-            CatalogItem rawItem = item;
-            @SuppressWarnings({ "rawtypes", "unchecked" })
-            AbstractBrooklynObjectSpec rawSpec = EntityManagementUtils.createCatalogSpec(mgmt, rawItem, parentEncounteredTypes);
-            return (EntitySpec<?>) rawSpec;
-        } else {
-            return null;
-        }
-    }
-
-    private void checkUsable(CatalogItem<Entity, EntitySpec<?>> item) {
-        if (item.isDisabled()) {
-            throw new IllegalStateException("Illegal use of disabled catalog item "+item.getSymbolicName()+":"+item.getVersion());
-        } else if (item.isDeprecated()) {
-            log.warn("Use of deprecated catalog item "+item.getSymbolicName()+":"+item.getVersion());
-        }
-    }
-
-    protected CatalogItem<Entity,EntitySpec<?>> getCatalogItem(ManagementContext mgmt, String brooklynType) {
-        brooklynType = DeserializingClassRenamesProvider.findMappedName(brooklynType);
-        return CatalogUtils.getCatalogItemOptionalVersion(mgmt, Entity.class,  brooklynType);
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/1db88751/core/src/main/java/org/apache/brooklyn/core/resolve/DelegatingServiceSpecResolver.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/core/resolve/DelegatingServiceSpecResolver.java b/core/src/main/java/org/apache/brooklyn/core/resolve/DelegatingServiceSpecResolver.java
deleted file mode 100644
index 6dc7b87..0000000
--- a/core/src/main/java/org/apache/brooklyn/core/resolve/DelegatingServiceSpecResolver.java
+++ /dev/null
@@ -1,127 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.brooklyn.core.resolve;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.List;
-import java.util.ServiceLoader;
-import java.util.Set;
-
-import javax.annotation.Nonnull;
-
-import org.apache.brooklyn.api.entity.EntitySpec;
-import org.apache.brooklyn.core.mgmt.classloading.BrooklynClassLoadingContext;
-import org.apache.brooklyn.util.exceptions.Exceptions;
-import org.apache.brooklyn.util.exceptions.PropagatedRuntimeException;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import com.google.common.collect.ImmutableList;
-
-public class DelegatingServiceSpecResolver extends AbstractServiceSpecResolver {
-    private static final String RESOLVER_PREFIX_CATALOG = "catalog:";
-
-    private static final String RESOLVER_PREFIX_JAVA = "java:";
-
-    private static final Logger log = LoggerFactory.getLogger(DelegatingServiceSpecResolver.class);
-
-    private static final String RESOLVER_NAME = "brooklyn";
-
-    private Collection<ServiceSpecResolver> resolvers;
-
-    public DelegatingServiceSpecResolver(@Nonnull List<ServiceSpecResolver> resolvers) {
-        super(RESOLVER_NAME);
-        this.resolvers = resolvers;
-    }
-
-    protected static ImmutableList<ServiceSpecResolver> getRegisteredResolvers() {
-        return ImmutableList.copyOf(ServiceLoader.load(ServiceSpecResolver.class));
-    }
-
-    @Override
-    public boolean accepts(String type, BrooklynClassLoadingContext loader) {
-        return accepts("", type, loader) ||
-                accepts(RESOLVER_PREFIX_CATALOG, type, loader) ||
-                accepts(RESOLVER_PREFIX_JAVA, type, loader);
-    }
-
-    private boolean accepts(String prefix, String type, BrooklynClassLoadingContext loader) {
-        for (ServiceSpecResolver resolver : resolvers) {
-            String localType = getLocalType(type);
-            if (resolver.accepts(prefix + localType, loader)) {
-                return true;
-            }
-        }
-        return false;
-    }
-
-    @Override
-    public EntitySpec<?> resolve(String type, BrooklynClassLoadingContext loader, Set<String> encounteredTypes) {
-        String localType = getLocalType(type);
-
-        EntitySpec<?> spec = resolve(resolvers, localType, loader, encounteredTypes);
-        if (spec != null) {
-            return spec;
-        }
-        spec = resolve(resolvers, RESOLVER_PREFIX_CATALOG + localType, loader, encounteredTypes);
-        if (spec != null) {
-            return spec;
-        }
-        return resolve(resolvers, RESOLVER_PREFIX_JAVA + localType, loader, encounteredTypes);
-    }
-
-    private EntitySpec<?> resolve(
-            Collection<ServiceSpecResolver> resolvers,
-            String localType,
-            BrooklynClassLoadingContext loader,
-            Set<String> encounteredTypes) {
-        Collection<String> resolversWhoDontSupport = new ArrayList<String>();
-        Collection<Exception> otherProblemsFromResolvers = new ArrayList<Exception>();
-
-        for (ServiceSpecResolver resolver : resolvers) {
-            if (resolver.accepts(localType, loader)) {
-                try {
-                    EntitySpec<?> spec = resolver.resolve(localType, loader, encounteredTypes);
-                    if (spec != null) {
-                        return spec;
-                    } else {
-                        resolversWhoDontSupport.add(resolver.getName() + " (returned null)");
-                    }
-                } catch (Exception e) {
-                    otherProblemsFromResolvers.add(new PropagatedRuntimeException("Transformer for "+resolver.getName()+" gave an error creating this plan: "+
-                            Exceptions.collapseText(e), e));
-                }
-            }
-        }
-        if (!otherProblemsFromResolvers.isEmpty()) {
-            // at least one thought he could do it
-            log.debug("Type " + localType + " could not be resolved; failure will be propagated (other transformers tried = "+resolversWhoDontSupport+"): "+otherProblemsFromResolvers);
-            throw otherProblemsFromResolvers.size()==1 ? Exceptions.create(null, otherProblemsFromResolvers) :
-                Exceptions.create("ServiceSpecResolvers all failed", otherProblemsFromResolvers);
-        }
-        return null;
-    }
-
-    @Override
-    public String toString() {
-        return this.getClass() + "[" + resolvers + "]";
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/1db88751/core/src/main/java/org/apache/brooklyn/core/resolve/JavaServiceSpecResolver.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/core/resolve/JavaServiceSpecResolver.java b/core/src/main/java/org/apache/brooklyn/core/resolve/JavaServiceSpecResolver.java
deleted file mode 100644
index af5ee5f..0000000
--- a/core/src/main/java/org/apache/brooklyn/core/resolve/JavaServiceSpecResolver.java
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.brooklyn.core.resolve;
-
-import java.util.List;
-import java.util.Set;
-
-import org.apache.brooklyn.api.entity.Application;
-import org.apache.brooklyn.api.entity.Entity;
-import org.apache.brooklyn.api.entity.EntitySpec;
-import org.apache.brooklyn.core.catalog.internal.CatalogUtils;
-import org.apache.brooklyn.core.mgmt.classloading.BrooklynClassLoadingContext;
-import org.apache.brooklyn.util.guava.Maybe;
-import org.apache.brooklyn.util.javalang.Reflections;
-
-public class JavaServiceSpecResolver extends AbstractServiceSpecResolver{
-    private static final String RESOLVER_NAME = "java";
-
-    public JavaServiceSpecResolver() {
-        super(RESOLVER_NAME);
-    }
-
-    @Override
-    protected boolean canResolve(String type, BrooklynClassLoadingContext loader) {
-        String localType = getLocalType(type);
-        Maybe<?> javaType = tryLoadJavaType(localType, loader);
-        return javaType.isPresent();
-    }
-
-    @Override
-    public EntitySpec<?> resolve(String type, BrooklynClassLoadingContext loader, Set<String> encounteredTypes) {
-        String localType = getLocalType(type);
-        try {
-            return resolveInternal(localType, loader);
-        } catch (Exception e) {
-            boolean firstOccurrence = encounteredTypes.add(localType);
-            boolean recursiveButTryJava = !firstOccurrence;
-            if (recursiveButTryJava) {
-                throw new IllegalStateException("Recursive reference to " + localType + " (and cannot be resolved as a Java type)", e);
-            } else {
-                throw e;
-            }
-        }
-    }
-
-    private EntitySpec<?> resolveInternal(String localType, BrooklynClassLoadingContext loader) {
-        Maybe<Class<? extends Entity>> javaTypeMaybe = tryLoadJavaType(localType, loader);
-        if (javaTypeMaybe.isAbsent())
-            throw new IllegalStateException("Could not find "+localType, ((Maybe.Absent<?>)javaTypeMaybe).getException());
-        Class<? extends Entity> javaType = javaTypeMaybe.get();
-
-        EntitySpec<? extends Entity> spec;
-        if (javaType.isInterface()) {
-            spec = EntitySpec.create(javaType);
-        } else {
-            // If this is a concrete class, particularly for an Application class, we want the proxy
-            // to expose all interfaces it implements.
-            Class<? extends Entity> interfaceclazz = (Application.class.isAssignableFrom(javaType)) ? Application.class : Entity.class;
-            List<Class<?>> additionalInterfaceClazzes = Reflections.getAllInterfaces(javaType);
-            @SuppressWarnings({ "rawtypes", "unchecked" })
-            EntitySpec<?> rawSpec = EntitySpec.create(interfaceclazz)
-                .impl((Class) javaType)
-                .additionalInterfaces(additionalInterfaceClazzes);
-            spec = rawSpec;
-        }
-        spec.catalogItemId(CatalogUtils.getCatalogItemIdFromLoader(loader));
-
-        return spec;
-    }
-
-    private Maybe<Class<? extends Entity>> tryLoadJavaType(String localType, BrooklynClassLoadingContext loader) {
-        return loader.tryLoadClass(localType, Entity.class);
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/1db88751/core/src/main/java/org/apache/brooklyn/core/resolve/ServiceSpecResolver.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/core/resolve/ServiceSpecResolver.java b/core/src/main/java/org/apache/brooklyn/core/resolve/ServiceSpecResolver.java
deleted file mode 100644
index 64a6c66..0000000
--- a/core/src/main/java/org/apache/brooklyn/core/resolve/ServiceSpecResolver.java
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.brooklyn.core.resolve;
-
-import java.util.ServiceLoader;
-import java.util.Set;
-
-import javax.annotation.Nullable;
-
-import org.apache.brooklyn.api.entity.EntitySpec;
-import org.apache.brooklyn.core.mgmt.ManagementContextInjectable;
-import org.apache.brooklyn.core.mgmt.classloading.BrooklynClassLoadingContext;
-
-/**
- * Resolves and decorates {@link EntitySpec entity specifications} based on the {@code serviceType} in a template.
- * <p>
- * The resolver implementation will use the rest of the local part of the service type information
- * to create and decorate an appropriate {@link EntitySpec entity}.
- * <p>
- * The resolvers are loaded using the {@link ServiceLoader} mechanism, allowing external libraries
- * to add extra service type implementations that will be picked up at runtime.
- */
-public interface ServiceSpecResolver extends ManagementContextInjectable {
-    /**
-     * Uniquely identifies the resolver, can be used to address the same resolver at a later point in time.
-     * For implementations: this usually matches the service type prefix, but not required.
-     */
-    String getName();
-
-    /**
-     * @return if the resolver can create a spec for the service type
-     */
-    boolean accepts(String type, BrooklynClassLoadingContext loader);
-
-    /**
-     * Create a spec for the service type
-     * 
-     * @param type - the string representation which should be converted to an EntitySpec
-     * @param loader - use it to load any Java classes
-     * @param encounteredTypes - an immutable set of the items which are currently being resolved up the stack,
-     *        used to prevent cycles. Implementations should not try to resolve the type if the symbolicName is
-     *        already contained in here. When resolving a type add it to a copy of the list before
-     *        passing the new instance down the stack. See {@link CatalogServiceSpecResolver} for example usage.
-     *
-     * @return The {@link EntitySpec} corresponding to the passed {@code type} argument, possibly pre-configured
-     *         based on the information contained in {@code type}. Return {@code null} value to indicate that
-     *         the implementation doesn't know how to convert {@code type} to an {@link EntitySpec}. Throw an
-     *         exception if {@code type} looks like a supported value, but can't be loaded.
-     */
-    @Nullable EntitySpec<?> resolve(String type, BrooklynClassLoadingContext loader, Set<String> encounteredTypes);
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/1db88751/core/src/main/java/org/apache/brooklyn/core/resolve/entity/AbstractEntitySpecResolver.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/core/resolve/entity/AbstractEntitySpecResolver.java b/core/src/main/java/org/apache/brooklyn/core/resolve/entity/AbstractEntitySpecResolver.java
new file mode 100644
index 0000000..ae3ddb2
--- /dev/null
+++ b/core/src/main/java/org/apache/brooklyn/core/resolve/entity/AbstractEntitySpecResolver.java
@@ -0,0 +1,65 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.brooklyn.core.resolve.entity;
+
+import java.util.Set;
+
+import org.apache.brooklyn.api.entity.EntitySpec;
+import org.apache.brooklyn.api.mgmt.ManagementContext;
+import org.apache.brooklyn.core.mgmt.classloading.BrooklynClassLoadingContext;
+import org.apache.brooklyn.util.text.Strings;
+
+public abstract class AbstractEntitySpecResolver implements EntitySpecResolver {
+    private static final String PREFIX_DELIMITER = ":";
+    protected final String name;
+    protected final String prefix;
+    protected ManagementContext mgmt;
+
+    public AbstractEntitySpecResolver(String name) {
+        this.name = name;
+        this.prefix = name + PREFIX_DELIMITER;
+    }
+
+    @Override
+    public String getName() {
+        return name;
+    }
+
+    @Override
+    public boolean accepts(String type, BrooklynClassLoadingContext loader) {
+        return type.startsWith(prefix) && canResolve(type, loader);
+    }
+
+    protected boolean canResolve(String type, BrooklynClassLoadingContext loader) {
+        return true;
+    }
+
+    protected String getLocalType(String type) {
+        return Strings.removeFromStart(type, prefix).trim();
+    }
+
+    @Override
+    public void injectManagementContext(ManagementContext mgmt) {
+        this.mgmt = mgmt;
+    }
+
+    @Override
+    public abstract EntitySpec<?> resolve(String type, BrooklynClassLoadingContext loader, Set<String> encounteredTypes);
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/1db88751/core/src/main/java/org/apache/brooklyn/core/resolve/entity/CatalogEntitySpecResolver.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/core/resolve/entity/CatalogEntitySpecResolver.java b/core/src/main/java/org/apache/brooklyn/core/resolve/entity/CatalogEntitySpecResolver.java
new file mode 100644
index 0000000..399f9dc
--- /dev/null
+++ b/core/src/main/java/org/apache/brooklyn/core/resolve/entity/CatalogEntitySpecResolver.java
@@ -0,0 +1,99 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.brooklyn.core.resolve.entity;
+
+import java.util.Set;
+
+import org.apache.brooklyn.api.catalog.CatalogItem;
+import org.apache.brooklyn.api.entity.Entity;
+import org.apache.brooklyn.api.entity.EntitySpec;
+import org.apache.brooklyn.api.internal.AbstractBrooklynObjectSpec;
+import org.apache.brooklyn.api.mgmt.ManagementContext;
+import org.apache.brooklyn.core.catalog.internal.CatalogUtils;
+import org.apache.brooklyn.core.mgmt.EntityManagementUtils;
+import org.apache.brooklyn.core.mgmt.classloading.BrooklynClassLoadingContext;
+import org.apache.brooklyn.core.mgmt.persist.DeserializingClassRenamesProvider;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class CatalogEntitySpecResolver extends AbstractEntitySpecResolver {
+    private static final Logger log = LoggerFactory.getLogger(CatalogEntitySpecResolver.class);
+
+    private static final String RESOLVER_NAME = "catalog";
+
+    public CatalogEntitySpecResolver() {
+        super(RESOLVER_NAME);
+    }
+
+    @Override
+    protected boolean canResolve(String type, BrooklynClassLoadingContext loader) {
+        String localType = getLocalType(type);
+        CatalogItem<Entity, EntitySpec<?>> item = getCatalogItem(mgmt, localType);
+        if (item != null) {
+            try {
+                //Keeps behaviour of previous functionality, but probably should throw instead when using disabled items.
+                checkUsable(item);
+                return true;
+            } catch (IllegalStateException e) {
+                return false;
+            }
+        } else {
+            return false;
+        }
+    }
+
+    @Override
+    public EntitySpec<?> resolve(String type, BrooklynClassLoadingContext loader, Set<String> parentEncounteredTypes) {
+        String localType = getLocalType(type);
+        CatalogItem<Entity, EntitySpec<?>> item = getCatalogItem(mgmt, localType);
+
+        if (item == null) return null;
+        checkUsable(item);
+
+        //Take the symbolicName part of the catalog item only for recursion detection to prevent
+        //cross referencing of different versions. Not interested in non-catalog item types.
+        //Prevent catalog items self-referencing even if explicitly different version.
+        boolean nonRecursiveCall = !parentEncounteredTypes.contains(item.getSymbolicName());
+        if (nonRecursiveCall) {
+            // CatalogItem generics are just getting in the way, better get rid of them, we
+            // are casting anyway.
+            @SuppressWarnings({ "rawtypes" })
+            CatalogItem rawItem = item;
+            @SuppressWarnings({ "rawtypes", "unchecked" })
+            AbstractBrooklynObjectSpec rawSpec = EntityManagementUtils.createCatalogSpec(mgmt, rawItem, parentEncounteredTypes);
+            return (EntitySpec<?>) rawSpec;
+        } else {
+            return null;
+        }
+    }
+
+    private void checkUsable(CatalogItem<Entity, EntitySpec<?>> item) {
+        if (item.isDisabled()) {
+            throw new IllegalStateException("Illegal use of disabled catalog item "+item.getSymbolicName()+":"+item.getVersion());
+        } else if (item.isDeprecated()) {
+            log.warn("Use of deprecated catalog item "+item.getSymbolicName()+":"+item.getVersion());
+        }
+    }
+
+    protected CatalogItem<Entity,EntitySpec<?>> getCatalogItem(ManagementContext mgmt, String brooklynType) {
+        brooklynType = DeserializingClassRenamesProvider.findMappedName(brooklynType);
+        return CatalogUtils.getCatalogItemOptionalVersion(mgmt, Entity.class,  brooklynType);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/1db88751/core/src/main/java/org/apache/brooklyn/core/resolve/entity/DelegatingEntitySpecResolver.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/core/resolve/entity/DelegatingEntitySpecResolver.java b/core/src/main/java/org/apache/brooklyn/core/resolve/entity/DelegatingEntitySpecResolver.java
new file mode 100644
index 0000000..2ccc468
--- /dev/null
+++ b/core/src/main/java/org/apache/brooklyn/core/resolve/entity/DelegatingEntitySpecResolver.java
@@ -0,0 +1,127 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.brooklyn.core.resolve.entity;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+import java.util.ServiceLoader;
+import java.util.Set;
+
+import javax.annotation.Nonnull;
+
+import org.apache.brooklyn.api.entity.EntitySpec;
+import org.apache.brooklyn.core.mgmt.classloading.BrooklynClassLoadingContext;
+import org.apache.brooklyn.util.exceptions.Exceptions;
+import org.apache.brooklyn.util.exceptions.PropagatedRuntimeException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.collect.ImmutableList;
+
+public class DelegatingEntitySpecResolver extends AbstractEntitySpecResolver {
+    private static final String RESOLVER_PREFIX_CATALOG = "catalog:";
+
+    private static final String RESOLVER_PREFIX_JAVA = "java:";
+
+    private static final Logger log = LoggerFactory.getLogger(DelegatingEntitySpecResolver.class);
+
+    private static final String RESOLVER_NAME = "brooklyn";
+
+    private Collection<EntitySpecResolver> resolvers;
+
+    public DelegatingEntitySpecResolver(@Nonnull List<EntitySpecResolver> resolvers) {
+        super(RESOLVER_NAME);
+        this.resolvers = resolvers;
+    }
+
+    protected static ImmutableList<EntitySpecResolver> getRegisteredResolvers() {
+        return ImmutableList.copyOf(ServiceLoader.load(EntitySpecResolver.class));
+    }
+
+    @Override
+    public boolean accepts(String type, BrooklynClassLoadingContext loader) {
+        return accepts("", type, loader) ||
+                accepts(RESOLVER_PREFIX_CATALOG, type, loader) ||
+                accepts(RESOLVER_PREFIX_JAVA, type, loader);
+    }
+
+    private boolean accepts(String prefix, String type, BrooklynClassLoadingContext loader) {
+        for (EntitySpecResolver resolver : resolvers) {
+            String localType = getLocalType(type);
+            if (resolver.accepts(prefix + localType, loader)) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    @Override
+    public EntitySpec<?> resolve(String type, BrooklynClassLoadingContext loader, Set<String> encounteredTypes) {
+        String localType = getLocalType(type);
+
+        EntitySpec<?> spec = resolve(resolvers, localType, loader, encounteredTypes);
+        if (spec != null) {
+            return spec;
+        }
+        spec = resolve(resolvers, RESOLVER_PREFIX_CATALOG + localType, loader, encounteredTypes);
+        if (spec != null) {
+            return spec;
+        }
+        return resolve(resolvers, RESOLVER_PREFIX_JAVA + localType, loader, encounteredTypes);
+    }
+
+    private EntitySpec<?> resolve(
+            Collection<EntitySpecResolver> resolvers,
+            String localType,
+            BrooklynClassLoadingContext loader,
+            Set<String> encounteredTypes) {
+        Collection<String> resolversWhoDontSupport = new ArrayList<String>();
+        Collection<Exception> otherProblemsFromResolvers = new ArrayList<Exception>();
+
+        for (EntitySpecResolver resolver : resolvers) {
+            if (resolver.accepts(localType, loader)) {
+                try {
+                    EntitySpec<?> spec = resolver.resolve(localType, loader, encounteredTypes);
+                    if (spec != null) {
+                        return spec;
+                    } else {
+                        resolversWhoDontSupport.add(resolver.getName() + " (returned null)");
+                    }
+                } catch (Exception e) {
+                    otherProblemsFromResolvers.add(new PropagatedRuntimeException("Transformer for "+resolver.getName()+" gave an error creating this plan: "+
+                            Exceptions.collapseText(e), e));
+                }
+            }
+        }
+        if (!otherProblemsFromResolvers.isEmpty()) {
+            // at least one thought he could do it
+            log.debug("Type " + localType + " could not be resolved; failure will be propagated (other transformers tried = "+resolversWhoDontSupport+"): "+otherProblemsFromResolvers);
+            throw otherProblemsFromResolvers.size()==1 ? Exceptions.create(null, otherProblemsFromResolvers) :
+                Exceptions.create("ServiceSpecResolvers all failed", otherProblemsFromResolvers);
+        }
+        return null;
+    }
+
+    @Override
+    public String toString() {
+        return this.getClass() + "[" + resolvers + "]";
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/1db88751/core/src/main/java/org/apache/brooklyn/core/resolve/entity/EntitySpecResolver.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/core/resolve/entity/EntitySpecResolver.java b/core/src/main/java/org/apache/brooklyn/core/resolve/entity/EntitySpecResolver.java
new file mode 100644
index 0000000..83e0fab
--- /dev/null
+++ b/core/src/main/java/org/apache/brooklyn/core/resolve/entity/EntitySpecResolver.java
@@ -0,0 +1,67 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.brooklyn.core.resolve.entity;
+
+import java.util.ServiceLoader;
+import java.util.Set;
+
+import javax.annotation.Nullable;
+
+import org.apache.brooklyn.api.entity.EntitySpec;
+import org.apache.brooklyn.core.mgmt.ManagementContextInjectable;
+import org.apache.brooklyn.core.mgmt.classloading.BrooklynClassLoadingContext;
+
+/**
+ * Resolves and decorates {@link EntitySpec entity specifications} based on the {@code serviceType} in a template.
+ * <p>
+ * The resolver implementation will use the rest of the local part of the service type information
+ * to create and decorate an appropriate {@link EntitySpec entity}.
+ * <p>
+ * The resolvers are loaded using the {@link ServiceLoader} mechanism, allowing external libraries
+ * to add extra service type implementations that will be picked up at runtime.
+ */
+public interface EntitySpecResolver extends ManagementContextInjectable {
+    /**
+     * Uniquely identifies the resolver, can be used to address the same resolver at a later point in time.
+     * For implementations: this usually matches the service type prefix, but not required.
+     */
+    String getName();
+
+    /**
+     * @return if the resolver can create a spec for the service type
+     */
+    boolean accepts(String type, BrooklynClassLoadingContext loader);
+
+    /**
+     * Create a spec for the service type
+     * 
+     * @param type - the string representation which should be converted to an EntitySpec
+     * @param loader - use it to load any Java classes
+     * @param encounteredTypes - an immutable set of the items which are currently being resolved up the stack,
+     *        used to prevent cycles. Implementations should not try to resolve the type if the symbolicName is
+     *        already contained in here. When resolving a type add it to a copy of the list before
+     *        passing the new instance down the stack. See {@link CatalogEntitySpecResolver} for example usage.
+     *
+     * @return The {@link EntitySpec} corresponding to the passed {@code type} argument, possibly pre-configured
+     *         based on the information contained in {@code type}. Return {@code null} value to indicate that
+     *         the implementation doesn't know how to convert {@code type} to an {@link EntitySpec}. Throw an
+     *         exception if {@code type} looks like a supported value, but can't be loaded.
+     */
+    @Nullable EntitySpec<?> resolve(String type, BrooklynClassLoadingContext loader, Set<String> encounteredTypes);
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/1db88751/core/src/main/java/org/apache/brooklyn/core/resolve/entity/JavaEntitySpecResolver.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/core/resolve/entity/JavaEntitySpecResolver.java b/core/src/main/java/org/apache/brooklyn/core/resolve/entity/JavaEntitySpecResolver.java
new file mode 100644
index 0000000..b8ce013
--- /dev/null
+++ b/core/src/main/java/org/apache/brooklyn/core/resolve/entity/JavaEntitySpecResolver.java
@@ -0,0 +1,91 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.brooklyn.core.resolve.entity;
+
+import java.util.List;
+import java.util.Set;
+
+import org.apache.brooklyn.api.entity.Application;
+import org.apache.brooklyn.api.entity.Entity;
+import org.apache.brooklyn.api.entity.EntitySpec;
+import org.apache.brooklyn.core.catalog.internal.CatalogUtils;
+import org.apache.brooklyn.core.mgmt.classloading.BrooklynClassLoadingContext;
+import org.apache.brooklyn.util.guava.Maybe;
+import org.apache.brooklyn.util.javalang.Reflections;
+
+public class JavaEntitySpecResolver extends AbstractEntitySpecResolver{
+    private static final String RESOLVER_NAME = "java";
+
+    public JavaEntitySpecResolver() {
+        super(RESOLVER_NAME);
+    }
+
+    @Override
+    protected boolean canResolve(String type, BrooklynClassLoadingContext loader) {
+        String localType = getLocalType(type);
+        Maybe<?> javaType = tryLoadJavaType(localType, loader);
+        return javaType.isPresent();
+    }
+
+    @Override
+    public EntitySpec<?> resolve(String type, BrooklynClassLoadingContext loader, Set<String> encounteredTypes) {
+        String localType = getLocalType(type);
+        try {
+            return resolveInternal(localType, loader);
+        } catch (Exception e) {
+            boolean firstOccurrence = encounteredTypes.add(localType);
+            boolean recursiveButTryJava = !firstOccurrence;
+            if (recursiveButTryJava) {
+                throw new IllegalStateException("Recursive reference to " + localType + " (and cannot be resolved as a Java type)", e);
+            } else {
+                throw e;
+            }
+        }
+    }
+
+    private EntitySpec<?> resolveInternal(String localType, BrooklynClassLoadingContext loader) {
+        Maybe<Class<? extends Entity>> javaTypeMaybe = tryLoadJavaType(localType, loader);
+        if (javaTypeMaybe.isAbsent())
+            throw new IllegalStateException("Could not find "+localType, ((Maybe.Absent<?>)javaTypeMaybe).getException());
+        Class<? extends Entity> javaType = javaTypeMaybe.get();
+
+        EntitySpec<? extends Entity> spec;
+        if (javaType.isInterface()) {
+            spec = EntitySpec.create(javaType);
+        } else {
+            // If this is a concrete class, particularly for an Application class, we want the proxy
+            // to expose all interfaces it implements.
+            Class<? extends Entity> interfaceclazz = (Application.class.isAssignableFrom(javaType)) ? Application.class : Entity.class;
+            List<Class<?>> additionalInterfaceClazzes = Reflections.getAllInterfaces(javaType);
+            @SuppressWarnings({ "rawtypes", "unchecked" })
+            EntitySpec<?> rawSpec = EntitySpec.create(interfaceclazz)
+                .impl((Class) javaType)
+                .additionalInterfaces(additionalInterfaceClazzes);
+            spec = rawSpec;
+        }
+        spec.catalogItemId(CatalogUtils.getCatalogItemIdFromLoader(loader));
+
+        return spec;
+    }
+
+    private Maybe<Class<? extends Entity>> tryLoadJavaType(String localType, BrooklynClassLoadingContext loader) {
+        return loader.tryLoadClass(localType, Entity.class);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/1db88751/core/src/main/resources/META-INF/services/org.apache.brooklyn.core.resolve.ServiceSpecResolver
----------------------------------------------------------------------
diff --git a/core/src/main/resources/META-INF/services/org.apache.brooklyn.core.resolve.ServiceSpecResolver b/core/src/main/resources/META-INF/services/org.apache.brooklyn.core.resolve.ServiceSpecResolver
deleted file mode 100644
index df57859..0000000
--- a/core/src/main/resources/META-INF/services/org.apache.brooklyn.core.resolve.ServiceSpecResolver
+++ /dev/null
@@ -1,20 +0,0 @@
-#
-# 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.
-#
-org.apache.brooklyn.core.resolve.CatalogServiceSpecResolver
-org.apache.brooklyn.core.resolve.JavaServiceSpecResolver

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/1db88751/core/src/main/resources/META-INF/services/org.apache.brooklyn.core.resolve.entity.EntitySpecResolver
----------------------------------------------------------------------
diff --git a/core/src/main/resources/META-INF/services/org.apache.brooklyn.core.resolve.entity.EntitySpecResolver b/core/src/main/resources/META-INF/services/org.apache.brooklyn.core.resolve.entity.EntitySpecResolver
new file mode 100644
index 0000000..b3f8a51
--- /dev/null
+++ b/core/src/main/resources/META-INF/services/org.apache.brooklyn.core.resolve.entity.EntitySpecResolver
@@ -0,0 +1,20 @@
+#
+# 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.
+#
+org.apache.brooklyn.core.resolve.entity.CatalogEntitySpecResolver
+org.apache.brooklyn.core.resolve.entity.JavaEntitySpecResolver

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/1db88751/software/base/src/main/java/org/apache/brooklyn/entity/resolve/ChefEntitySpecResolver.java
----------------------------------------------------------------------
diff --git a/software/base/src/main/java/org/apache/brooklyn/entity/resolve/ChefEntitySpecResolver.java b/software/base/src/main/java/org/apache/brooklyn/entity/resolve/ChefEntitySpecResolver.java
new file mode 100644
index 0000000..07d4342
--- /dev/null
+++ b/software/base/src/main/java/org/apache/brooklyn/entity/resolve/ChefEntitySpecResolver.java
@@ -0,0 +1,42 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.brooklyn.entity.resolve;
+
+import java.util.Set;
+
+import org.apache.brooklyn.api.entity.EntitySpec;
+import org.apache.brooklyn.core.mgmt.classloading.BrooklynClassLoadingContext;
+import org.apache.brooklyn.core.resolve.entity.AbstractEntitySpecResolver;
+import org.apache.brooklyn.entity.chef.ChefConfig;
+import org.apache.brooklyn.entity.chef.ChefEntity;
+
+public class ChefEntitySpecResolver extends AbstractEntitySpecResolver {
+    private static final String RESOLVER_NAME = "chef";
+
+    public ChefEntitySpecResolver() {
+        super(RESOLVER_NAME);
+    }
+
+    @Override
+    public EntitySpec<?> resolve(String type, BrooklynClassLoadingContext loader, Set<String> encounteredTypes) {
+        return EntitySpec.create(ChefEntity.class)
+                .configure(ChefConfig.CHEF_COOKBOOK_PRIMARY_NAME, getLocalType(type));
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/1db88751/software/base/src/main/java/org/apache/brooklyn/entity/resolve/ChefServiceSpecResolver.java
----------------------------------------------------------------------
diff --git a/software/base/src/main/java/org/apache/brooklyn/entity/resolve/ChefServiceSpecResolver.java b/software/base/src/main/java/org/apache/brooklyn/entity/resolve/ChefServiceSpecResolver.java
deleted file mode 100644
index ea774c1..0000000
--- a/software/base/src/main/java/org/apache/brooklyn/entity/resolve/ChefServiceSpecResolver.java
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.brooklyn.entity.resolve;
-
-import java.util.Set;
-
-import org.apache.brooklyn.api.entity.EntitySpec;
-import org.apache.brooklyn.core.mgmt.classloading.BrooklynClassLoadingContext;
-import org.apache.brooklyn.core.resolve.AbstractServiceSpecResolver;
-import org.apache.brooklyn.entity.chef.ChefConfig;
-import org.apache.brooklyn.entity.chef.ChefEntity;
-
-public class ChefServiceSpecResolver extends AbstractServiceSpecResolver {
-    private static final String RESOLVER_NAME = "chef";
-
-    public ChefServiceSpecResolver() {
-        super(RESOLVER_NAME);
-    }
-
-    @Override
-    public EntitySpec<?> resolve(String type, BrooklynClassLoadingContext loader, Set<String> encounteredTypes) {
-        return EntitySpec.create(ChefEntity.class)
-                .configure(ChefConfig.CHEF_COOKBOOK_PRIMARY_NAME, getLocalType(type));
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/1db88751/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
new file mode 100644
index 0000000..5541996
--- /dev/null
+++ b/software/base/src/main/java/org/apache/brooklyn/entity/resolve/HardcodedCatalogEntitySpecResolver.java
@@ -0,0 +1,96 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.brooklyn.entity.resolve;
+
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.brooklyn.api.entity.Entity;
+import org.apache.brooklyn.api.entity.EntitySpec;
+import org.apache.brooklyn.core.mgmt.classloading.BrooklynClassLoadingContext;
+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 com.google.common.base.CaseFormat;
+import com.google.common.base.Converter;
+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")
+            .build();
+
+    // Allow catalog-type or CatalogType as service type string
+    private static final Converter<String, String> FMT = CaseFormat.UPPER_CAMEL.converterTo(CaseFormat.LOWER_HYPHEN);
+
+    public HardcodedCatalogEntitySpecResolver() {
+        super(RESOLVER_NAME);
+    }
+
+    @Override
+    protected boolean canResolve(String type, BrooklynClassLoadingContext loader) {
+        String localType = getLocalType(type);
+        String specType = getImplementation(localType);
+        return specType != 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;
+        }
+    }
+
+    private String getImplementation(String type) {
+        String specType = CATALOG_TYPES.get(type);
+        if (specType != null) {
+            return specType;
+        } else {
+            return CATALOG_TYPES.get(FMT.convert(type));
+        }
+    }
+
+    private EntitySpec<?> buildSpec(String specType) {
+        // 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);
+        } catch (ClassNotFoundException e) {
+            throw new IllegalStateException("Unable to load hardcoded catalog type " + specType, e);
+        }
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/1db88751/software/base/src/main/java/org/apache/brooklyn/entity/resolve/HardcodedCatalogServiceSpecResolver.java
----------------------------------------------------------------------
diff --git a/software/base/src/main/java/org/apache/brooklyn/entity/resolve/HardcodedCatalogServiceSpecResolver.java b/software/base/src/main/java/org/apache/brooklyn/entity/resolve/HardcodedCatalogServiceSpecResolver.java
deleted file mode 100644
index 7a073de..0000000
--- a/software/base/src/main/java/org/apache/brooklyn/entity/resolve/HardcodedCatalogServiceSpecResolver.java
+++ /dev/null
@@ -1,96 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.brooklyn.entity.resolve;
-
-import java.util.Map;
-import java.util.Set;
-
-import org.apache.brooklyn.api.entity.Entity;
-import org.apache.brooklyn.api.entity.EntitySpec;
-import org.apache.brooklyn.core.mgmt.classloading.BrooklynClassLoadingContext;
-import org.apache.brooklyn.core.resolve.AbstractServiceSpecResolver;
-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 com.google.common.base.CaseFormat;
-import com.google.common.base.Converter;
-import com.google.common.collect.ImmutableMap;
-
-public class HardcodedCatalogServiceSpecResolver extends AbstractServiceSpecResolver {
-    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")
-            .build();
-
-    // Allow catalog-type or CatalogType as service type string
-    private static final Converter<String, String> FMT = CaseFormat.UPPER_CAMEL.converterTo(CaseFormat.LOWER_HYPHEN);
-
-    public HardcodedCatalogServiceSpecResolver() {
-        super(RESOLVER_NAME);
-    }
-
-    @Override
-    protected boolean canResolve(String type, BrooklynClassLoadingContext loader) {
-        String localType = getLocalType(type);
-        String specType = getImplementation(localType);
-        return specType != 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;
-        }
-    }
-
-    private String getImplementation(String type) {
-        String specType = CATALOG_TYPES.get(type);
-        if (specType != null) {
-            return specType;
-        } else {
-            return CATALOG_TYPES.get(FMT.convert(type));
-        }
-    }
-
-    private EntitySpec<?> buildSpec(String specType) {
-        // 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);
-        } catch (ClassNotFoundException e) {
-            throw new IllegalStateException("Unable to load hardcoded catalog type " + specType, e);
-        }
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/1db88751/software/base/src/main/resources/META-INF/services/org.apache.brooklyn.core.resolve.ServiceSpecResolver
----------------------------------------------------------------------
diff --git a/software/base/src/main/resources/META-INF/services/org.apache.brooklyn.core.resolve.ServiceSpecResolver b/software/base/src/main/resources/META-INF/services/org.apache.brooklyn.core.resolve.ServiceSpecResolver
deleted file mode 100644
index d3471e0..0000000
--- a/software/base/src/main/resources/META-INF/services/org.apache.brooklyn.core.resolve.ServiceSpecResolver
+++ /dev/null
@@ -1,20 +0,0 @@
-#
-# 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.
-#
-org.apache.brooklyn.entity.resolve.ChefServiceSpecResolver
-org.apache.brooklyn.entity.resolve.HardcodedCatalogServiceSpecResolver

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/1db88751/software/base/src/main/resources/META-INF/services/org.apache.brooklyn.core.resolve.entity.EntitySpecResolver
----------------------------------------------------------------------
diff --git a/software/base/src/main/resources/META-INF/services/org.apache.brooklyn.core.resolve.entity.EntitySpecResolver b/software/base/src/main/resources/META-INF/services/org.apache.brooklyn.core.resolve.entity.EntitySpecResolver
new file mode 100644
index 0000000..1224bd2
--- /dev/null
+++ b/software/base/src/main/resources/META-INF/services/org.apache.brooklyn.core.resolve.entity.EntitySpecResolver
@@ -0,0 +1,20 @@
+#
+# 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.
+#
+org.apache.brooklyn.entity.resolve.ChefEntitySpecResolver
+org.apache.brooklyn.entity.resolve.HardcodedCatalogEntitySpecResolver

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/1db88751/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/creation/BrooklynComponentTemplateResolver.java
----------------------------------------------------------------------
diff --git a/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/creation/BrooklynComponentTemplateResolver.java b/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/creation/BrooklynComponentTemplateResolver.java
index cfdfab2..e9d22f1 100644
--- a/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/creation/BrooklynComponentTemplateResolver.java
+++ b/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/creation/BrooklynComponentTemplateResolver.java
@@ -51,7 +51,7 @@ import org.apache.brooklyn.core.mgmt.BrooklynTaskTags;
 import org.apache.brooklyn.core.mgmt.ManagementContextInjectable;
 import org.apache.brooklyn.core.mgmt.classloading.BrooklynClassLoadingContext;
 import org.apache.brooklyn.core.mgmt.classloading.JavaBrooklynClassLoadingContext;
-import org.apache.brooklyn.core.resolve.ServiceSpecResolver;
+import org.apache.brooklyn.core.resolve.entity.EntitySpecResolver;
 import org.apache.brooklyn.util.collections.MutableList;
 import org.apache.brooklyn.util.collections.MutableSet;
 import org.apache.brooklyn.util.core.config.ConfigBag;
@@ -85,7 +85,7 @@ public class BrooklynComponentTemplateResolver {
     private final BrooklynYamlTypeInstantiator.Factory yamlLoader;
     private final String type;
     private final AtomicBoolean alreadyBuilt = new AtomicBoolean(false);
-    private final ServiceSpecResolver serviceSpecResolver;
+    private final EntitySpecResolver serviceSpecResolver;
 
     private BrooklynComponentTemplateResolver(BrooklynClassLoadingContext loader, ConfigBag attrs, AbstractResource optionalTemplate, String type) {
         this.loader = loader;
@@ -177,8 +177,8 @@ public class BrooklynComponentTemplateResolver {
         return typedSpec;
     }
 
-    private List<ServiceSpecResolver> getServiceTypeResolverOverrides() {
-        List<ServiceSpecResolver> overrides = new ArrayList<>();
+    private List<EntitySpecResolver> getServiceTypeResolverOverrides() {
+        List<EntitySpecResolver> overrides = new ArrayList<>();
         ServiceLoader<ServiceTypeResolver> loader = ServiceLoader.load(ServiceTypeResolver.class, mgmt.getCatalogClassLoader());
         for (ServiceTypeResolver resolver : loader) {
            overrides.add(new ServiceTypeResolverAdaptor(this, resolver));

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/1db88751/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/creation/CampUtils.java
----------------------------------------------------------------------
diff --git a/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/creation/CampUtils.java b/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/creation/CampUtils.java
index 4fca75c..83b85e2 100644
--- a/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/creation/CampUtils.java
+++ b/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/creation/CampUtils.java
@@ -40,8 +40,8 @@ import org.apache.brooklyn.camp.spi.AssemblyTemplate;
 import org.apache.brooklyn.camp.spi.instantiate.AssemblyTemplateInstantiator;
 import org.apache.brooklyn.camp.spi.pdp.DeploymentPlan;
 import org.apache.brooklyn.core.catalog.internal.BasicBrooklynCatalog;
-import org.apache.brooklyn.core.catalog.internal.CatalogUtils;
 import org.apache.brooklyn.core.catalog.internal.BasicBrooklynCatalog.BrooklynLoaderTracker;
+import org.apache.brooklyn.core.catalog.internal.CatalogUtils;
 import org.apache.brooklyn.core.mgmt.classloading.BrooklynClassLoadingContext;
 import org.apache.brooklyn.core.objs.BrooklynObjectInternal.ConfigurationSupportInternal;
 import org.apache.brooklyn.util.exceptions.Exceptions;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/1db88751/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/creation/service/BrooklynServiceTypeResolver.java
----------------------------------------------------------------------
diff --git a/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/creation/service/BrooklynServiceTypeResolver.java b/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/creation/service/BrooklynServiceTypeResolver.java
index edb1924..83f907b 100644
--- a/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/creation/service/BrooklynServiceTypeResolver.java
+++ b/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/creation/service/BrooklynServiceTypeResolver.java
@@ -28,7 +28,7 @@ import org.apache.brooklyn.camp.brooklyn.spi.creation.BrooklynComponentTemplateR
 import org.apache.brooklyn.camp.spi.PlatformComponentTemplate;
 import org.apache.brooklyn.core.catalog.internal.CatalogUtils;
 import org.apache.brooklyn.core.mgmt.persist.DeserializingClassRenamesProvider;
-import org.apache.brooklyn.core.resolve.AbstractServiceSpecResolver;
+import org.apache.brooklyn.core.resolve.entity.AbstractEntitySpecResolver;
 import org.apache.brooklyn.util.text.Strings;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -37,7 +37,7 @@ import org.slf4j.LoggerFactory;
  * This converts {@link PlatformComponentTemplate} instances whose type is prefixed {@code brooklyn:}
  * to Brooklyn {@link EntitySpec} instances.
  * 
- * @deprecated since 0.9.0, use {@link AbstractServiceSpecResolver} instead
+ * @deprecated since 0.9.0, use {@link AbstractEntitySpecResolver} instead
  */
 @Deprecated
 public class BrooklynServiceTypeResolver implements ServiceTypeResolver {

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/1db88751/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/creation/service/CampServiceSpecResolver.java
----------------------------------------------------------------------
diff --git a/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/creation/service/CampServiceSpecResolver.java b/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/creation/service/CampServiceSpecResolver.java
index 143f088..a993083 100644
--- a/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/creation/service/CampServiceSpecResolver.java
+++ b/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/creation/service/CampServiceSpecResolver.java
@@ -21,24 +21,24 @@ package org.apache.brooklyn.camp.brooklyn.spi.creation.service;
 import java.util.List;
 
 import org.apache.brooklyn.api.mgmt.ManagementContext;
-import org.apache.brooklyn.core.resolve.DelegatingServiceSpecResolver;
-import org.apache.brooklyn.core.resolve.ServiceSpecResolver;
+import org.apache.brooklyn.core.resolve.entity.DelegatingEntitySpecResolver;
+import org.apache.brooklyn.core.resolve.entity.EntitySpecResolver;
 
 import com.google.common.collect.ImmutableList;
 
-public class CampServiceSpecResolver extends DelegatingServiceSpecResolver {
+public class CampServiceSpecResolver extends DelegatingEntitySpecResolver {
 
-    public CampServiceSpecResolver(ManagementContext mgmt, List<ServiceSpecResolver> overridingResolvers) {
+    public CampServiceSpecResolver(ManagementContext mgmt, List<EntitySpecResolver> overridingResolvers) {
         super(getCampResolvers(mgmt, overridingResolvers));
     }
 
-    private static List<ServiceSpecResolver> getCampResolvers(ManagementContext mgmt, List<ServiceSpecResolver> overridingResolvers) {
-        List<ServiceSpecResolver> resolvers = ImmutableList.<ServiceSpecResolver>builder()
+    private static List<EntitySpecResolver> getCampResolvers(ManagementContext mgmt, List<EntitySpecResolver> overridingResolvers) {
+        List<EntitySpecResolver> resolvers = ImmutableList.<EntitySpecResolver>builder()
                 .addAll(overridingResolvers)
                 .addAll(getRegisteredResolvers())
                 .add(new UrlServiceSpecResolver())
                 .build();
-        for (ServiceSpecResolver resolver : resolvers) {
+        for (EntitySpecResolver resolver : resolvers) {
             resolver.injectManagementContext(mgmt);
         }
         return resolvers;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/1db88751/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/creation/service/ServiceTypeResolver.java
----------------------------------------------------------------------
diff --git a/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/creation/service/ServiceTypeResolver.java b/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/creation/service/ServiceTypeResolver.java
index da472c6..14f855a 100644
--- a/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/creation/service/ServiceTypeResolver.java
+++ b/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/creation/service/ServiceTypeResolver.java
@@ -24,7 +24,7 @@ import org.apache.brooklyn.api.catalog.CatalogItem;
 import org.apache.brooklyn.api.entity.Entity;
 import org.apache.brooklyn.api.entity.EntitySpec;
 import org.apache.brooklyn.camp.brooklyn.spi.creation.BrooklynComponentTemplateResolver;
-import org.apache.brooklyn.core.resolve.ServiceSpecResolver;
+import org.apache.brooklyn.core.resolve.entity.EntitySpecResolver;
 
 /**
  * Resolves and decorates {@link EntitySpec entity specifications} based on the {@code serviceType} in a template.
@@ -39,7 +39,7 @@ import org.apache.brooklyn.core.resolve.ServiceSpecResolver;
  * @see BrooklynServiceTypeResolver
  * @see ChefServiceTypeResolver
  * 
- * @deprecated since 0.9.0, {@link ServiceSpecResolver} instead.
+ * @deprecated since 0.9.0, {@link EntitySpecResolver} instead.
  */
 @Deprecated
 public interface ServiceTypeResolver {

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/1db88751/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/creation/service/ServiceTypeResolverAdaptor.java
----------------------------------------------------------------------
diff --git a/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/creation/service/ServiceTypeResolverAdaptor.java b/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/creation/service/ServiceTypeResolverAdaptor.java
index 17f4e2b..703a7cf 100644
--- a/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/creation/service/ServiceTypeResolverAdaptor.java
+++ b/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/creation/service/ServiceTypeResolverAdaptor.java
@@ -24,15 +24,15 @@ import org.apache.brooklyn.api.entity.Entity;
 import org.apache.brooklyn.api.entity.EntitySpec;
 import org.apache.brooklyn.camp.brooklyn.spi.creation.BrooklynComponentTemplateResolver;
 import org.apache.brooklyn.core.mgmt.classloading.BrooklynClassLoadingContext;
-import org.apache.brooklyn.core.resolve.AbstractServiceSpecResolver;
-import org.apache.brooklyn.core.resolve.ServiceSpecResolver;
+import org.apache.brooklyn.core.resolve.entity.AbstractEntitySpecResolver;
+import org.apache.brooklyn.core.resolve.entity.EntitySpecResolver;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 import com.google.common.base.Splitter;
 
 @SuppressWarnings("deprecation")
-public class ServiceTypeResolverAdaptor extends AbstractServiceSpecResolver {
+public class ServiceTypeResolverAdaptor extends AbstractEntitySpecResolver {
     private static final Logger log = LoggerFactory.getLogger(ServiceTypeResolverAdaptor.class);
     private ServiceTypeResolver serviceTypeResolver;
     private BrooklynComponentTemplateResolver resolver;
@@ -60,7 +60,7 @@ public class ServiceTypeResolverAdaptor extends AbstractServiceSpecResolver {
         String brooklynType = serviceTypeResolver.getBrooklynType(type);
         Class<? extends Entity> javaType = loader.loadClass(brooklynType, Entity.class);
         if (!javaType.isInterface()) {
-            log.warn("Using " + ServiceTypeResolver.class.getSimpleName() + " with a non-interface type - this usage is not supported. Use " + ServiceSpecResolver.class.getSimpleName() + " instead.");
+            log.warn("Using " + ServiceTypeResolver.class.getSimpleName() + " with a non-interface type - this usage is not supported. Use " + EntitySpecResolver.class.getSimpleName() + " instead.");
         }
         EntitySpec<?> spec = EntitySpec.create((Class)javaType);
         serviceTypeResolver.decorateSpec(resolver, spec);

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/1db88751/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/creation/service/UrlServiceSpecResolver.java
----------------------------------------------------------------------
diff --git a/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/creation/service/UrlServiceSpecResolver.java b/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/creation/service/UrlServiceSpecResolver.java
index bde501b..ab058c7 100644
--- a/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/creation/service/UrlServiceSpecResolver.java
+++ b/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/creation/service/UrlServiceSpecResolver.java
@@ -26,14 +26,14 @@ import org.apache.brooklyn.api.mgmt.ManagementContext;
 import org.apache.brooklyn.camp.brooklyn.BrooklynCampConstants;
 import org.apache.brooklyn.camp.brooklyn.spi.creation.CampUtils;
 import org.apache.brooklyn.core.mgmt.classloading.BrooklynClassLoadingContext;
-import org.apache.brooklyn.core.resolve.ServiceSpecResolver;
+import org.apache.brooklyn.core.resolve.entity.EntitySpecResolver;
 import org.apache.brooklyn.util.core.ResourceUtils;
 import org.apache.brooklyn.util.net.Urls;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 /** Specific to CAMP because linked plans are assumed to be CAMP format. No type discovery available. */
-public class UrlServiceSpecResolver implements ServiceSpecResolver {
+public class UrlServiceSpecResolver implements EntitySpecResolver {
     private static final Logger log = LoggerFactory.getLogger(UrlServiceSpecResolver.class);
 
     @Override