brooklyn-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From henev...@apache.org
Subject [09/18] brooklyn-server git commit: first pass rewriting LocationRegistry and resolvers to return specs
Date Fri, 18 Mar 2016 11:06:30 GMT
first pass rewriting LocationRegistry and resolvers to return specs


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

Branch: refs/heads/master
Commit: f755c25d2e66fa93a4a5f9f29ab8edc8d1c5be48
Parents: d2c5cc8
Author: Alex Heneveld <alex.heneveld@cloudsoftcorp.com>
Authored: Wed Mar 16 20:43:56 2016 +0000
Committer: Alex Heneveld <alex.heneveld@cloudsoftcorp.com>
Committed: Thu Mar 17 12:02:47 2016 +0000

----------------------------------------------------------------------
 .../internal/AbstractBrooklynObjectSpec.java    |   5 +
 .../api/location/LocationDefinition.java        |   2 +-
 .../brooklyn/api/location/LocationRegistry.java |  75 +++++++--
 .../brooklyn/api/location/LocationResolver.java |  23 +--
 .../brooklyn/api/mgmt/LocationManager.java      |   5 +
 .../BrooklynComponentTemplateResolver.java      |   7 +-
 .../creation/BrooklynYamlLocationResolver.java  |  29 ++--
 .../spi/creation/CampInternalUtils.java         |  15 +-
 .../apache/brooklyn/core/config/ConfigKeys.java |   2 +-
 .../brooklyn/core/entity/trait/Startable.java   |   2 +-
 .../core/location/AbstractLocationResolver.java |  18 ++-
 .../core/location/BasicLocationRegistry.java    | 112 ++++++++++----
 .../core/location/CatalogLocationResolver.java  |  15 +-
 .../location/DefinedLocationByIdResolver.java   |  11 +-
 .../core/location/LocationConfigUtils.java      |  13 +-
 .../brooklyn/core/location/Locations.java       |  23 ++-
 .../core/location/NamedLocationResolver.java    |  14 +-
 .../location/access/PortForwardManagerImpl.java |   1 -
 .../PortForwardManagerLocationResolver.java     |  10 +-
 .../location/internal/LocationInternal.java     |   3 -
 .../mgmt/internal/LocalLocationManager.java     |  11 +-
 .../mgmt/internal/LocationManagerInternal.java  |   8 +
 .../mgmt/persist/BrooklynPersistenceUtils.java  |  19 ++-
 .../entity/group/DynamicRegionsFabricImpl.java  |   2 +-
 .../location/byon/HostLocationResolver.java     |   9 +-
 .../byon/SingleMachineLocationResolver.java     |  10 +-
 .../byon/SingleMachineProvisioningLocation.java |   2 +-
 .../localhost/LocalhostLocationResolver.java    |   8 +-
 .../brooklyn/location/multi/MultiLocation.java  |  42 +++--
 .../location/multi/MultiLocationResolver.java   |  86 +++++-----
 .../location/ssh/SshMachineLocation.java        |   2 +-
 .../brooklyn/launcher/common/BasicLauncher.java |   2 +-
 .../JcloudsBlobStoreBasedObjectStore.java       |   2 +-
 .../jclouds/JcloudsByonLocationResolver.java    |  17 +-
 .../jclouds/JcloudsLocationResolver.java        |  24 +--
 .../rest/resources/ApplicationResource.java     |   2 +-
 .../rest/transform/LocationTransformer.java     | 155 ++++++++++++-------
 .../rest/util/BrooklynRestResourceUtils.java    |   3 +-
 .../org/apache/brooklyn/cli/CloudExplorer.java  |   4 +-
 .../entity/machine/pool/ServerPoolImpl.java     |   9 +-
 .../pool/ServerPoolLocationResolver.java        |  20 ++-
 .../MachineLifecycleEffectorTasks.java          |   4 +-
 .../location/winrm/WinRmMachineLocation.java    |   2 +-
 43 files changed, 511 insertions(+), 317 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/f755c25d/api/src/main/java/org/apache/brooklyn/api/internal/AbstractBrooklynObjectSpec.java
----------------------------------------------------------------------
diff --git a/api/src/main/java/org/apache/brooklyn/api/internal/AbstractBrooklynObjectSpec.java b/api/src/main/java/org/apache/brooklyn/api/internal/AbstractBrooklynObjectSpec.java
index 789d282..3f95342 100644
--- a/api/src/main/java/org/apache/brooklyn/api/internal/AbstractBrooklynObjectSpec.java
+++ b/api/src/main/java/org/apache/brooklyn/api/internal/AbstractBrooklynObjectSpec.java
@@ -247,6 +247,11 @@ public abstract class AbstractBrooklynObjectSpec<T,SpecT extends AbstractBrookly
     /** strings inserted as flags, config keys inserted as config keys; 
      * if you want to force one or the other, create a ConfigBag and convert to the appropriate map type */
     public SpecT configure(Map<?,?> val) {
+        if (val==null) {
+            log.warn("Null supplied when configuring "+this);
+            log.debug("Source for null supplied when configuring "+this, new Throwable("Source for null supplied when configuring "+this));
+            return self();
+        }
         for (Map.Entry<?, ?> entry: val.entrySet()) {
             if (entry.getKey()==null) throw new NullPointerException("Null key not permitted");
             if (entry.getKey() instanceof CharSequence)

http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/f755c25d/api/src/main/java/org/apache/brooklyn/api/location/LocationDefinition.java
----------------------------------------------------------------------
diff --git a/api/src/main/java/org/apache/brooklyn/api/location/LocationDefinition.java b/api/src/main/java/org/apache/brooklyn/api/location/LocationDefinition.java
index 2bbe74c..21b325b 100644
--- a/api/src/main/java/org/apache/brooklyn/api/location/LocationDefinition.java
+++ b/api/src/main/java/org/apache/brooklyn/api/location/LocationDefinition.java
@@ -30,7 +30,7 @@ import org.apache.brooklyn.api.mgmt.ManagementContext;
  * a name that matches a named location defined in the brooklyn poperties.
  * 
  * Users are not expected to implement this, or to use the interface directly. See
- * {@link LocationRegistry#resolve(String)} and {@link ManagementContext#getLocationRegistry()}.
+ * {@link ManagementContext#getLocationRegistry()}.
  */
 public interface LocationDefinition {
 

http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/f755c25d/api/src/main/java/org/apache/brooklyn/api/location/LocationRegistry.java
----------------------------------------------------------------------
diff --git a/api/src/main/java/org/apache/brooklyn/api/location/LocationRegistry.java b/api/src/main/java/org/apache/brooklyn/api/location/LocationRegistry.java
index 73ab6f5..7804afc 100644
--- a/api/src/main/java/org/apache/brooklyn/api/location/LocationRegistry.java
+++ b/api/src/main/java/org/apache/brooklyn/api/location/LocationRegistry.java
@@ -24,16 +24,16 @@ import java.util.NoSuchElementException;
 
 import javax.annotation.Nullable;
 
+import org.apache.brooklyn.api.entity.Entity;
+import org.apache.brooklyn.api.entity.EntitySpec;
+import org.apache.brooklyn.api.mgmt.LocationManager;
 import org.apache.brooklyn.util.guava.Maybe;
 
-import com.google.common.annotations.Beta;
-
 /**
  * The registry of the sorts of locations that brooklyn knows about. Given a
  * {@LocationDefinition} or a {@link String} representation of a spec, this can
  * be used to create a {@link Location} instance.
  */
-@SuppressWarnings("rawtypes")
 public interface LocationRegistry {
 
     /** map of ID (possibly randomly generated) to the definition (spec, name, id, and props; 
@@ -59,24 +59,32 @@ public interface LocationRegistry {
      * <p>
      * The manage parameter is {@link Boolean} so that null can be used to say rely on anything in the flags.
      * 
-     * @since 0.7.0, but beta and likely to change as the semantics of this class are tuned */
-    @Beta
+     * @since 0.7.0, but beta and likely to change as the semantics of this class are tuned 
+     * @deprecated since 0.9.0 use {@link #getLocationSpec(String, Map)} or {@link #getLocationManaged(String, Map)} */
+    @SuppressWarnings("rawtypes")
+    @Deprecated
     public Maybe<Location> resolve(LocationDefinition ld, Boolean manage, Map locationFlags);
     
     /** As {@link #resolve(LocationDefinition, Boolean, Map), with the location managed, and no additional flags,
-     * unwrapping the result (throwing if not resolvable) */
+     * unwrapping the result (throwing if not resolvable) 
+     * @deprecated since 0.9.0 use {@link #getLocationSpec(LocationDefinition, Map)} and then manage it as needed*/
+    @Deprecated
     public Location resolve(LocationDefinition l);
 
     /** Returns a location created from the given spec, which might correspond to a definition, or created on-the-fly.
      * Optional flags can be passed through to underlying the location. 
-     * @since 0.7.0, but beta and likely to change as the semantics of this class are tuned */
-    @Beta
+     * @since 0.7.0, but beta and likely to change as the semantics of this class are tuned 
+     * @deprecated since 0.9.0 use {@link #getLocationSpec(String, Map)} or {@link #getLocationManaged(String, Map)} */
+    @SuppressWarnings("rawtypes")
+    @Deprecated
     public Maybe<Location> resolve(String spec, Boolean manage, Map locationFlags);
-    
+
     /** See {@link #resolve(String, Boolean, Map)}; asks for the location to be managed, and supplies no additional flags,
-     * and unwraps the result (throwing if the spec cannot be resolve) */
+     * and unwraps the result (throwing if the spec cannot be resolve).
+     * @deprecated since 0.9.0 use {@link #getLocationSpec(String)} or {@link #getLocationManaged(String)} */
+    @Deprecated
     public Location resolve(String spec);
-    
+        
     /** Returns true/false depending whether spec seems like a valid location,
      * that is it has a chance of being resolved (depending on the spec) but NOT guaranteed,
      * as it is not passed to the spec;
@@ -86,25 +94,62 @@ public interface LocationRegistry {
     public boolean canMaybeResolve(String spec);
     
     /** As {@link #resolve(String, Boolean, Map)}, but unwrapped
-     * @throws NoSuchElementException if the spec cannot be resolved */
+     * @throws NoSuchElementException if the spec cannot be resolved 
+     * @deprecated since 0.9.0 use {@link #getLocationSpec(String, Map)} and then manage it as needed*/
+    @SuppressWarnings("rawtypes")
+    @Deprecated
     public Location resolve(String spec, @Nullable Map locationFlags);
     
     /**
-     * As {@link #resolve(String)} but takes collections (of strings or locations)
+     * As {@link #getLocationManaged(String)} but takes collections (of strings or locations)
      * <p>
      * Expects a collection of elements being individual location spec strings or locations, 
      * and returns a list of resolved (newly created and managed) locations.
      * <p>
      * From 0.7.0 this no longer flattens lists (nested lists are disallowed) 
      * or parses comma-separated elements (they are resolved as-is)
-     */
+     * @deprecated since 0.9.0 use {@link #getListOfLocationsManaged(Object)} */
+    @Deprecated
     public List<Location> resolve(Iterable<?> spec);
     
     /** Takes a string, interpreted as a comma-separated (or JSON style, when you need internal double quotes or commas) list;
      * or a list, passed to {@link #resolve(Iterable)}; or null/empty (empty list),
-     * and returns a list of resolved (created and managed) locations */
+     * and returns a list of resolved (created and managed) locations 
+     * @deprecated since 0.9.0 use {@link #getListOfLocationsManaged(Object)} */
+    @Deprecated
     public List<Location> resolveList(Object specList);
+
+    /** Create a {@link LocationSpec} representing the given spec string such as a named location 
+     * or using a resolver prefix such as jclouds:aws-ec2. 
+     * This can then be inspected, assigned to an {@link EntitySpec}, 
+     * or passed to {@link LocationManager#createLocation(LocationSpec)} to create directly.
+     * (For that last case, common in tests, see {@link #getLocationManaged(String)}.) */
+    public Maybe<LocationSpec<? extends Location>> getLocationSpec(String spec);
+    /** As {@link #getLocationSpec(String)} but also setting the given flags configured on the resulting spec. */
+    public Maybe<LocationSpec<? extends Location>> getLocationSpec(String spec, Map<?,?> locationFlags);
+
+    /** As {@link #getLocationSpec(String)} where the caller has a {@link LocationDefinition}. */
+    public Maybe<LocationSpec<? extends Location>> getLocationSpec(LocationDefinition ld);
+    /** As {@link #getLocationSpec(String,Map)} where the caller has a {@link LocationDefinition}. */
+    public Maybe<LocationSpec<? extends Location>> getLocationSpec(LocationDefinition ld, Map<?,?> locationFlags);
     
+    /** A combination of {@link #getLocationSpec(String)} then {@link LocationManager#createLocation(LocationSpec)},
+     * mainly for use in tests or specialised situations where a managed location is needed directly.
+     * The caller is responsible for ensuring that the resulting {@link Location} 
+     * is cleaned up, ie removed from management via {@link LocationManager#unmanage(Location)} directly or linking it to 
+     * an {@link Entity} or another {@link Location} which will unmanage it. */
+    public Location getLocationManaged(String spec);
+    /** As {@link #getLocationManaged(String)} applying the config as per {@link #getLocationSpec(String, Map)}. */
+    public Location getLocationManaged(String spec, Map<?,?> locationFlags);
+    
+    /** Takes a string, interpreted as a comma-separated (or JSON style, when you need internal double quotes or commas) list;
+     * or a list of strings, or null (giving the empty list) and returns a list of managed locations.
+     * Note that lists of lists are not permitted.
+     * <p>
+     * The caller is responsible for ensuring these get cleaned up, as described at {@link #getLocationManaged(String)}. */
+    public List<Location> getListOfLocationsManaged(Object specList);
+
+    @SuppressWarnings("rawtypes")
     public Map getProperties();
     
 }

http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/f755c25d/api/src/main/java/org/apache/brooklyn/api/location/LocationResolver.java
----------------------------------------------------------------------
diff --git a/api/src/main/java/org/apache/brooklyn/api/location/LocationResolver.java b/api/src/main/java/org/apache/brooklyn/api/location/LocationResolver.java
index 4ddb5e4..6727334 100644
--- a/api/src/main/java/org/apache/brooklyn/api/location/LocationResolver.java
+++ b/api/src/main/java/org/apache/brooklyn/api/location/LocationResolver.java
@@ -22,8 +22,6 @@ import java.util.Map;
 
 import org.apache.brooklyn.api.mgmt.ManagementContext;
 
-import com.google.common.annotations.Beta;
-
 /**
  * Provides a way of creating location instances of a particular type.
  */
@@ -37,21 +35,14 @@ public interface LocationResolver {
     /** whether the spec is something which should be passed to this resolver */
     boolean accepts(String spec, LocationRegistry registry);
 
+    /** whether the location is enabled */
+    boolean isEnabled();
+
     /**
-     * Similar to {@link #newLocationFromString(Map, String)} 
-     * but passing in a reference to the registry itself (from which the base properties are discovered)
-     * and including flags (e.g. user, key, cloud credential) which are known to be for this location.
-     * <p>
-     * introduced to support locations which refer to other locations, e.g. NamedLocationResolver  
+     * Creates a LocationSpec given a spec string, flags (e.g. user, key, cloud credential),
+     * and the registry itself from which the base properties are discovered
+     * and supporting locations which refer to other locations, e.g. NamedLocationResolver.
      **/ 
-    @SuppressWarnings("rawtypes")
-    Location newLocationFromString(Map locationFlags, String spec, LocationRegistry registry);
+    LocationSpec<? extends Location> newLocationSpecFromString(String spec, Map<?,?> locationFlags, LocationRegistry registry);
 
-    /** @since 0.7.0 exploring this as a mechanism to disable locations */
-    @Beta
-    public interface EnableableLocationResolver extends LocationResolver {
-        /** whether the location is enabled */
-        boolean isEnabled();
-    }
-    
 }

http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/f755c25d/api/src/main/java/org/apache/brooklyn/api/mgmt/LocationManager.java
----------------------------------------------------------------------
diff --git a/api/src/main/java/org/apache/brooklyn/api/mgmt/LocationManager.java b/api/src/main/java/org/apache/brooklyn/api/mgmt/LocationManager.java
index 9d20a34..86ec570 100644
--- a/api/src/main/java/org/apache/brooklyn/api/mgmt/LocationManager.java
+++ b/api/src/main/java/org/apache/brooklyn/api/mgmt/LocationManager.java
@@ -31,6 +31,9 @@ public interface LocationManager {
 
     /**
      * Creates a new location, which is tracked by the management context.
+     * <p>
+     * Some sub-interfaces may expose an option to suppress management
+     * (e.g. <code>CREATE_UNMANAGED</code> on the Brooklyn LocationManagerInternal sub-interface). 
      * 
      * @param spec
      */
@@ -41,7 +44,9 @@ public interface LocationManager {
      * Equivalent to {@code createLocation(LocationSpec.create(type).configure(config))}
      * 
      * @see #createLocation(LocationSpec)
+     * @deprecated in 0.9.0, use {@link LocationSpec} instead
      */
+    @Deprecated
     <T extends Location> T createLocation(Map<?,?> config, Class<T> type);
 
     /**

http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/f755c25d/camp/camp-brooklyn/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/creation/BrooklynComponentTemplateResolver.java
----------------------------------------------------------------------
diff --git a/camp/camp-brooklyn/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/creation/BrooklynComponentTemplateResolver.java b/camp/camp-brooklyn/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/creation/BrooklynComponentTemplateResolver.java
index 9757063..dd03f46 100644
--- a/camp/camp-brooklyn/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/creation/BrooklynComponentTemplateResolver.java
+++ b/camp/camp-brooklyn/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/creation/BrooklynComponentTemplateResolver.java
@@ -31,7 +31,7 @@ import javax.annotation.Nullable;
 
 import org.apache.brooklyn.api.entity.Entity;
 import org.apache.brooklyn.api.entity.EntitySpec;
-import org.apache.brooklyn.api.location.Location;
+import org.apache.brooklyn.api.location.LocationSpec;
 import org.apache.brooklyn.api.mgmt.ManagementContext;
 import org.apache.brooklyn.api.mgmt.classloading.BrooklynClassLoadingContext;
 import org.apache.brooklyn.api.typereg.RegisteredType;
@@ -224,13 +224,12 @@ public class BrooklynComponentTemplateResolver {
         if (planId != null)
             spec.configure(BrooklynCampConstants.PLAN_ID, planId);
 
-        // XXX use location spec
-        List<Location> locations = new BrooklynYamlLocationResolver(mgmt).resolveLocations(attrs.getAllConfig(), true);
+        List<LocationSpec<?>> locations = new BrooklynYamlLocationResolver(mgmt).resolveLocations(attrs.getAllConfig(), true);
         if (locations != null) {
             // override locations defined in the type if locations are specified here
             // empty list can be used by caller to clear, so they are inherited
             spec.clearLocations();
-            spec.locations(locations);
+            spec.locationSpecs(locations);
         }
 
         decorateSpec(spec, encounteredRegisteredTypeIds);

http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/f755c25d/camp/camp-brooklyn/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/creation/BrooklynYamlLocationResolver.java
----------------------------------------------------------------------
diff --git a/camp/camp-brooklyn/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/creation/BrooklynYamlLocationResolver.java b/camp/camp-brooklyn/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/creation/BrooklynYamlLocationResolver.java
index 7f2e056..390d784 100644
--- a/camp/camp-brooklyn/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/creation/BrooklynYamlLocationResolver.java
+++ b/camp/camp-brooklyn/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/creation/BrooklynYamlLocationResolver.java
@@ -25,6 +25,7 @@ import java.util.NoSuchElementException;
 
 import org.apache.brooklyn.api.location.Location;
 import org.apache.brooklyn.api.location.LocationDefinition;
+import org.apache.brooklyn.api.location.LocationSpec;
 import org.apache.brooklyn.api.mgmt.ManagementContext;
 import org.apache.brooklyn.util.collections.MutableList;
 import org.apache.brooklyn.util.collections.MutableMap;
@@ -45,16 +46,16 @@ public class BrooklynYamlLocationResolver {
     }
 
     /** returns list of locations, if any were supplied, or null if none indicated */
-    @SuppressWarnings("unchecked")
-    public List<Location> resolveLocations(Map<? super String,?> attrs, boolean removeUsedAttributes) {
+    @SuppressWarnings({ "unchecked", "rawtypes" })
+    public List<LocationSpec<?>> resolveLocations(Map<? super String,?> attrs, boolean removeUsedAttributes) {
         Object location = attrs.get("location");
         Object locations = attrs.get("locations");
 
         if (location==null && locations==null)
             return null;
         
-        Location locationFromString = null;
-        List<Location> locationsFromList = null;
+        LocationSpec<?> locationFromString = null;
+        List<LocationSpec<?>> locationsFromList = null;
         
         if (location!=null) {
             if (location instanceof String) {
@@ -80,22 +81,22 @@ public class BrooklynYamlLocationResolver {
                 throw new UserFacingException("Conflicting 'location' and 'locations' ("+location+" and "+locations+"); "
                     + "different location specified in each");
         } else if (locationFromString!=null) {
-            locationsFromList = Arrays.asList(locationFromString);
+            locationsFromList = (List) Arrays.asList(locationFromString);
         }
         
         return locationsFromList;
     }
 
-    public List<Location> resolveLocations(Iterable<Object> locations) {
-        List<Location> result = MutableList.of();
+    public List<LocationSpec<?>> resolveLocations(Iterable<Object> locations) {
+        List<LocationSpec<?>> result = MutableList.of();
         for (Object l: locations) {
-            Location ll = resolveLocation(l);
+            LocationSpec<?> ll = resolveLocation(l);
             if (ll!=null) result.add(ll);
         }
         return result;
     }
 
-    public Location resolveLocation(Object location) {
+    public LocationSpec<?> resolveLocation(Object location) {
         if (location instanceof String) {
             return resolveLocationFromString((String)location);
         } else if (location instanceof Map) {
@@ -107,12 +108,12 @@ public class BrooklynYamlLocationResolver {
     
     /** resolves the location from the given spec string, either "Named Location", or "named:Named Location" format;
      * returns null if input is blank (or null); otherwise guaranteed to resolve or throw error */
-    public Location resolveLocationFromString(String location) {
+    public LocationSpec<?> resolveLocationFromString(String location) {
         if (Strings.isBlank(location)) return null;
         return resolveLocation(location, MutableMap.of());
     }
 
-    public Location resolveLocationFromMap(Map<?,?> location) {
+    public LocationSpec<?> resolveLocationFromMap(Map<?,?> location) {
         if (location.size() > 1) {
             throw new UserFacingException("Illegal parameter for 'location'; expected a single entry in map ("+location+")");
         }
@@ -128,13 +129,13 @@ public class BrooklynYamlLocationResolver {
         return resolveLocation((String)key, (Map<?,?>)value);
     }
     
-    protected Location resolveLocation(String spec, Map<?,?> flags) {
+    protected LocationSpec<?> resolveLocation(String spec, Map<?,?> flags) {
         LocationDefinition ldef = mgmt.getLocationRegistry().getDefinedLocationByName((String)spec);
         if (ldef!=null)
             // found it as a named location
-            return mgmt.getLocationRegistry().resolve(ldef, null, flags).get();
+            return mgmt.getLocationRegistry().getLocationSpec(ldef, flags).get();
         
-        Maybe<Location> l = mgmt.getLocationRegistry().resolve(spec, null, flags);
+        Maybe<LocationSpec<?>> l = mgmt.getLocationRegistry().getLocationSpec(spec, flags);
         if (l.isPresent()) return l.get();
         
         RuntimeException exception = ((Absent<?>)l).getException();

http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/f755c25d/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 9096168..677c3eb 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
@@ -47,8 +47,8 @@ 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.objs.BrooklynObjectInternal.ConfigurationSupportInternal;
 import org.apache.brooklyn.entity.stock.BasicApplicationImpl;
+import org.apache.brooklyn.util.collections.MutableMap;
 import org.apache.brooklyn.util.exceptions.Exceptions;
 import org.apache.brooklyn.util.guava.Maybe;
 import org.apache.brooklyn.util.stream.Streams;
@@ -170,6 +170,7 @@ class CampInternalUtils {
 
         String type = (String) checkNotNull(Yamls.getMultinameAttribute(itemMap, "location_type", "locationType", "type"), "location type");
         Map<String, Object> brooklynConfig = (Map<String, Object>) itemMap.get("brooklyn.config");
+        if (brooklynConfig==null) brooklynConfig = MutableMap.of();
         LocationSpec<?> locationSpec = resolveLocationSpec(type, brooklynConfig, loader);
         List<?> explicitParams = (List<?>) itemMap.get(BrooklynCampReservedKeys.BROOKLYN_PARAMETERS);
         initParameters(explicitParams, locationSpec, loader);
@@ -227,17 +228,9 @@ class CampInternalUtils {
             }
             return spec;
         } else {
-            Maybe<Location> loc = loader.getManagementContext().getLocationRegistry().resolve(type, false, brooklynConfig);
+            Maybe<LocationSpec<? extends Location>> loc = loader.getManagementContext().getLocationRegistry().getLocationSpec(type);
             if (loc.isPresent()) {
-                // TODO extensions?
-                Map<String, Object> locConfig = ((ConfigurationSupportInternal)loc.get().config()).getBag().getAllConfig();
-                Class<? extends Location> locType = loc.get().getClass();
-                Set<Object> locTags = loc.get().tags().getTags();
-                String locDisplayName = loc.get().getDisplayName();
-                return LocationSpec.create(locType)
-                        .configure(locConfig)
-                        .displayName(locDisplayName)
-                        .tags(locTags);
+                return loc.get().configure(brooklynConfig);
             } else {
                 throw new IllegalStateException("No class or resolver found for location type "+type);
             }

http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/f755c25d/core/src/main/java/org/apache/brooklyn/core/config/ConfigKeys.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/core/config/ConfigKeys.java b/core/src/main/java/org/apache/brooklyn/core/config/ConfigKeys.java
index c9bb2f3..aeff698 100644
--- a/core/src/main/java/org/apache/brooklyn/core/config/ConfigKeys.java
+++ b/core/src/main/java/org/apache/brooklyn/core/config/ConfigKeys.java
@@ -151,7 +151,7 @@ public class ConfigKeys {
 
 
     public static <T> AttributeSensorAndConfigKey<T, T> newSensorAndConfigKeyWithDefault(AttributeSensorAndConfigKey<T, T> parent, T defaultValue) {
-        return new BasicAttributeSensorAndConfigKey(parent, defaultValue);
+        return new BasicAttributeSensorAndConfigKey<T>(parent, defaultValue);
     }
 
     public static PortAttributeSensorAndConfigKey newPortSensorAndConfigKeyWithDefault(PortAttributeSensorAndConfigKey parent, Object defaultValue) {

http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/f755c25d/core/src/main/java/org/apache/brooklyn/core/entity/trait/Startable.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/core/entity/trait/Startable.java b/core/src/main/java/org/apache/brooklyn/core/entity/trait/Startable.java
index 96812ce..9169bdb 100644
--- a/core/src/main/java/org/apache/brooklyn/core/entity/trait/Startable.java
+++ b/core/src/main/java/org/apache/brooklyn/core/entity/trait/Startable.java
@@ -52,7 +52,7 @@ public interface Startable {
             "The location or locations to start in, as a string, a location object, a list of strings, "
             + "or a list of location objects");
         @Override public Void call(ConfigBag parameters) {
-            parameters.put(LOCATIONS, entity().getManagementContext().getLocationRegistry().resolveList(parameters.get(LOCATIONS)));
+            parameters.put(LOCATIONS, entity().getManagementContext().getLocationRegistry().getListOfLocationsManaged(parameters.get(LOCATIONS)));
             return new MethodEffector<Void>(Startable.class, "start").call(entity(), parameters.getAllConfig());
         }
     }

http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/f755c25d/core/src/main/java/org/apache/brooklyn/core/location/AbstractLocationResolver.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/core/location/AbstractLocationResolver.java b/core/src/main/java/org/apache/brooklyn/core/location/AbstractLocationResolver.java
index 766021e..809e228 100644
--- a/core/src/main/java/org/apache/brooklyn/core/location/AbstractLocationResolver.java
+++ b/core/src/main/java/org/apache/brooklyn/core/location/AbstractLocationResolver.java
@@ -52,7 +52,6 @@ import com.google.common.collect.ImmutableList;
  * 
  * @author aled
  */
-@SuppressWarnings({"unchecked","rawtypes"})
 public abstract class AbstractLocationResolver implements LocationResolver {
 
     public static final Logger log = LoggerFactory.getLogger(AbstractLocationResolver.class);
@@ -77,22 +76,29 @@ public abstract class AbstractLocationResolver implements LocationResolver {
     }
 
     @Override
-    public Location newLocationFromString(Map locationFlags, String spec, LocationRegistry registry) {
+    public boolean isEnabled() {
+        return LocationConfigUtils.isResolverPrefixEnabled(managementContext, getPrefix());
+    }
+
+    @Override
+    public LocationSpec<?> newLocationSpecFromString(String spec, Map<?,?> locationFlags, LocationRegistry registry) {
         ConfigBag config = extractConfig(locationFlags, spec, registry);
-        Map globalProperties = registry.getProperties();
+        @SuppressWarnings("unchecked")
+        Map<String,?> globalProperties = registry.getProperties();
         String namedLocation = (String) locationFlags.get(LocationInternal.NAMED_SPEC_NAME.getName());
         
         if (registry != null) {
             LocationPropertiesFromBrooklynProperties.setLocalTempDir(globalProperties, config);
         }
 
-        return managementContext.getLocationManager().createLocation(LocationSpec.create(getLocationType())
+        return LocationSpec.create(getLocationType())
             .configure(config.getAllConfig())
-            .configure(LocationConfigUtils.finalAndOriginalSpecs(spec, locationFlags, globalProperties, namedLocation)));
+            .configure(LocationConfigUtils.finalAndOriginalSpecs(spec, locationFlags, globalProperties, namedLocation));        
     }
 
     protected ConfigBag extractConfig(Map<?,?> locationFlags, String spec, LocationRegistry registry) {
-        Map globalProperties = registry.getProperties();
+        @SuppressWarnings("unchecked")
+        Map<String,?> globalProperties = registry.getProperties();
         ParsedSpec parsedSpec = specParser.parse(spec);
         String namedLocation = (String) locationFlags.get(LocationInternal.NAMED_SPEC_NAME.getName());
         

http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/f755c25d/core/src/main/java/org/apache/brooklyn/core/location/BasicLocationRegistry.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/core/location/BasicLocationRegistry.java b/core/src/main/java/org/apache/brooklyn/core/location/BasicLocationRegistry.java
index c7d7127..e117f73 100644
--- a/core/src/main/java/org/apache/brooklyn/core/location/BasicLocationRegistry.java
+++ b/core/src/main/java/org/apache/brooklyn/core/location/BasicLocationRegistry.java
@@ -57,6 +57,7 @@ import org.apache.brooklyn.util.guava.Maybe.Absent;
 import org.apache.brooklyn.util.javalang.JavaClassNames;
 import org.apache.brooklyn.util.text.Identifiers;
 import org.apache.brooklyn.util.text.StringEscapes.JavaStringEscapes;
+import org.apache.brooklyn.util.text.Strings;
 import org.apache.brooklyn.util.text.WildcardGlobs;
 import org.apache.brooklyn.util.text.WildcardGlobs.PhraseTreatment;
 import org.slf4j.Logger;
@@ -98,7 +99,7 @@ import com.google.common.collect.Sets;
  *       such as the YAML {@code location: my-new-location}.
  *       (this feels similar to the "named locations").
  *     <ol>
- *       <li>This automatically calls {@link #resolve(String)}.
+ *       <li>This automatically calls {@link #getLocationManaged(String)}.
  *       <li>The LocationDefinition is found by lookig up this name.
  *       <li>The {@link LocationDefiniton.getSpec()} is retrieved; the right {@link LocationResolver} is
  *           found for it.
@@ -173,10 +174,8 @@ public class BasicLocationRegistry implements LocationRegistry {
      * and returning true, unless the argument indicates false for {@link LocationResolver.EnableableLocationResolver#isEnabled()} */
     public boolean registerResolver(LocationResolver r) {
         r.init(mgmt);
-        if (r instanceof LocationResolver.EnableableLocationResolver) {
-            if (!((LocationResolver.EnableableLocationResolver)r).isEnabled()) {
-                return false;
-            }
+        if (!r.isEnabled()) {
+            return false;
         }
         resolvers.put(r.getPrefix(), r);
         return true;
@@ -299,17 +298,54 @@ public class BasicLocationRegistry implements LocationRegistry {
         return getSpecResolver(spec) != null;
     }
 
-    @Override
+    @Override @Deprecated
     public final Location resolve(String spec) {
         return resolve(spec, true, null).get();
     }
     
+    @Override @Deprecated
     public Maybe<Location> resolve(String spec, Boolean manage, Map locationFlags) {
+        if (manage!=null) {
+            locationFlags = MutableMap.copyOf(locationFlags);
+            locationFlags.put(LocalLocationManager.CREATE_UNMANAGED, !manage);
+        }
+        Maybe<LocationSpec<? extends Location>> lSpec = getLocationSpec(spec, locationFlags);
+        if (lSpec.isAbsent()) return (Maybe)lSpec;
+        return Maybe.of((Location)mgmt.getLocationManager().createLocation(lSpec.get()));
+    }
+
+    @Override
+    public Location getLocationManaged(String spec) {
+        return mgmt.getLocationManager().createLocation(getLocationSpec(spec).get());
+    }
+    
+    @Override
+    public final Location getLocationManaged(String spec, Map locationFlags) {
+        return mgmt.getLocationManager().createLocation(getLocationSpec(spec, locationFlags).get());
+    }
+
+    @Override
+    public Maybe<LocationSpec<? extends Location>> getLocationSpec(LocationDefinition ld) {
+        return getLocationSpec(ld, MutableMap.of());
+    }
+    
+    @Override
+    public Maybe<LocationSpec<? extends Location>> getLocationSpec(LocationDefinition ld, Map locationFlags) {
+        ConfigBag newLocationFlags = ConfigBag.newInstance(ld.getConfig())
+            .putAll(locationFlags)
+            .putIfAbsentAndNotNull(LocationInternal.NAMED_SPEC_NAME, ld.getName())
+            .putIfAbsentAndNotNull(LocationInternal.ORIGINAL_SPEC, ld.getName());
+        return getLocationSpec(ld.getSpec(), newLocationFlags.getAllConfigRaw());        
+    }
+
+    @Override
+    public Maybe<LocationSpec<? extends Location>> getLocationSpec(String spec) {
+        return getLocationSpec(spec, MutableMap.of());
+    }
+    @Override
+    public Maybe<LocationSpec<? extends Location>> getLocationSpec(String spec, Map locationFlags) {
         try {
             locationFlags = MutableMap.copyOf(locationFlags);
-            if (manage!=null) {
-                locationFlags.put(LocalLocationManager.CREATE_UNMANAGED, !manage);
-            }
             
             Set<String> seenSoFar = specsSeen.get();
             if (seenSoFar==null) {
@@ -324,7 +360,7 @@ public class BasicLocationRegistry implements LocationRegistry {
 
             if (resolver != null) {
                 try {
-                    return Maybe.of(resolver.newLocationFromString(locationFlags, spec, this));
+                    return (Maybe) Maybe.of(resolver.newLocationSpecFromString(spec, locationFlags, this));
                 } catch (RuntimeException e) {
                      return Maybe.absent(Suppliers.ofInstance(e));
                 }
@@ -332,27 +368,34 @@ public class BasicLocationRegistry implements LocationRegistry {
 
             // problem: but let's ensure that classpath is sane to give better errors in common IDE bogus case;
             // and avoid repeated logging
-            String errmsg;
+            String errmsg = "Unknown location '"+spec+"'";
+            ConfigBag cfg = ConfigBag.newInstance(locationFlags);
+            String orig = cfg.get(LocationInternal.ORIGINAL_SPEC);                
+            String named = cfg.get(LocationInternal.NAMED_SPEC_NAME);
+            if (Strings.isNonBlank(named) && !named.equals(spec) && !named.equals(orig)) {
+                errmsg += " when looking up '"+named+"'";
+            }
+            if (Strings.isNonBlank(orig) && !orig.equals(spec)) {
+                errmsg += " when resolving '"+orig+"'";
+            }
+
             if (spec == null || specsWarnedOnException.add(spec)) {
                 if (resolvers.get("id")==null || resolvers.get("named")==null) {
                     log.error("Standard location resolvers not installed, location resolution will fail shortly. "
                             + "This usually indicates a classpath problem, such as when running from an IDE which "
                             + "has not properly copied META-INF/services from src/main/resources. "
+                            + errmsg+". "
                             + "Known resolvers are: "+resolvers.keySet());
-                    errmsg = "Unresolvable location '"+spec+"': "
+                    errmsg = errmsg+": "
                             + "Problem detected with location resolver configuration; "
                             + resolvers.keySet()+" are the only available location resolvers. "
                             + "More information can be found in the logs.";
                 } else {
-                    log.debug("Location resolution failed for '"+spec+"' (if this is being loaded it will fail shortly): known resolvers are: "+resolvers.keySet());
-                    errmsg = "Unknown location '"+spec+"': "
-                            + "either this location is not recognised or there is a problem with location resolver configuration.";
+                    if (log.isDebugEnabled()) log.debug(errmsg + " (if this is being loaded it will fail shortly): known resolvers are: "+resolvers.keySet());
                 }
             } else {
-                // For helpful log message construction: assumes classpath will not suddenly become wrong; might happen with OSGi though!
-                if (log.isDebugEnabled()) log.debug("Location resolution failed again for '"+spec+"' (throwing)");
-                errmsg = "Unknown location '"+spec+"': "
-                        + "either this location is not recognised or there is a problem with location resolver configuration.";
+                if (log.isDebugEnabled()) log.debug(errmsg + "(with retry, already warned)");
+                errmsg += " (with retry)";
             }
 
             return Maybe.absent(Suppliers.ofInstance(new NoSuchElementException(errmsg)));
@@ -362,11 +405,11 @@ public class BasicLocationRegistry implements LocationRegistry {
         }
     }
 
-    @Override
+    @Override @Deprecated
     public final Location resolve(String spec, Map locationFlags) {
         return resolve(spec, null, locationFlags).get();
     }
-
+    
     protected LocationResolver getSpecResolver(String spec) {
         int colonIndex = spec.indexOf(':');
         int bracketIndex = spec.indexOf("(");
@@ -400,14 +443,18 @@ public class BasicLocationRegistry implements LocationRegistry {
         return false;
     }
 
-    @Override
+    @Override @Deprecated
     public List<Location> resolve(Iterable<?> spec) {
+        return getFromIterableListOfLocationsManaged(spec);
+    }
+    
+    private List<Location> getFromIterableListOfLocationsManaged(Iterable<?> spec) {
         List<Location> result = new ArrayList<Location>();
         for (Object id : spec) {
             if (id==null) {
                 // drop a null entry
             } if (id instanceof String) {
-                result.add(resolve((String) id));
+                result.add(getLocationManaged((String) id));
             } else if (id instanceof Location) {
                 result.add((Location) id);
             } else {
@@ -420,25 +467,26 @@ public class BasicLocationRegistry implements LocationRegistry {
         return result;
     }
     
+    @Override @Deprecated
     public List<Location> resolveList(Object l) {
+        return getListOfLocationsManaged(l);
+    }
+    
+    @Override 
+    public List<Location> getListOfLocationsManaged(Object l) {
         if (l==null) l = Collections.emptyList();
         if (l instanceof String) l = JavaStringEscapes.unwrapJsonishListIfPossible((String)l);
-        if (l instanceof Iterable) return resolve((Iterable<?>)l);
+        if (l instanceof Iterable) return getFromIterableListOfLocationsManaged((Iterable<?>)l);
         throw new IllegalArgumentException("Location list must be supplied as a collection or a string, not "+
             JavaClassNames.simpleClassName(l)+"/"+l);
     }
     
-    @Override
+    @Override @Deprecated
     public Location resolve(LocationDefinition ld) {
         return resolve(ld, null, null).get();
     }
     
-    /** @deprecated since 0.7.0 not used (and optionalName was ignored anyway) */
-    @Deprecated
-    public Location resolveLocationDefinition(LocationDefinition ld, Map locationFlags, String optionalName) {
-        return resolve(ld, null, locationFlags).get();
-    }
-    
+    @Override @Deprecated
     public Maybe<Location> resolve(LocationDefinition ld, Boolean manage, Map locationFlags) {
         ConfigBag newLocationFlags = ConfigBag.newInstance(ld.getConfig())
             .putAll(locationFlags)
@@ -450,7 +498,7 @@ public class BasicLocationRegistry implements LocationRegistry {
         throw new IllegalStateException("Cannot instantiate location '"+ld+"' pointing at "+ld.getSpec(), 
             ((Absent<?>)result).getException() );
     }
-
+    
     @Override
     public Map getProperties() {
         return mgmt.getConfig().asMapWithStringKeys();

http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/f755c25d/core/src/main/java/org/apache/brooklyn/core/location/CatalogLocationResolver.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/core/location/CatalogLocationResolver.java b/core/src/main/java/org/apache/brooklyn/core/location/CatalogLocationResolver.java
index 194e946..a218a66 100644
--- a/core/src/main/java/org/apache/brooklyn/core/location/CatalogLocationResolver.java
+++ b/core/src/main/java/org/apache/brooklyn/core/location/CatalogLocationResolver.java
@@ -49,8 +49,12 @@ public class CatalogLocationResolver implements LocationResolver {
     }
     
     @Override
-    @SuppressWarnings({ "rawtypes", "unchecked" })
-    public Location newLocationFromString(Map locationFlags, String spec, LocationRegistry registry) {
+    public boolean isEnabled() {
+        return true;
+    }
+    
+    @Override
+    public LocationSpec<? extends Location> newLocationSpecFromString(String spec, Map<?, ?> locationFlags, LocationRegistry registry) {
         String id = spec.substring(NAME.length()+1);
         RegisteredType item = managementContext.getTypeRegistry().get(id);
         if (item.isDisabled()) {
@@ -59,10 +63,9 @@ public class CatalogLocationResolver implements LocationResolver {
             log.warn("Use of deprecated catalog item "+item.getSymbolicName()+":"+item.getVersion());
         }
         
-        LocationSpec<?> origLocSpec = (LocationSpec) managementContext.getTypeRegistry().createSpec(item, null, LocationSpec.class);
-        LocationSpec locSpec = LocationSpec.create(origLocSpec)
-                .configure(locationFlags);
-        return managementContext.getLocationManager().createLocation(locSpec);
+        LocationSpec<?> origLocSpec = (LocationSpec<?>) managementContext.getTypeRegistry().createSpec(item, null, LocationSpec.class);
+        LocationSpec<?> locSpec = LocationSpec.create(origLocSpec).configure(locationFlags);
+        return locSpec;
     }
 
     @Override

http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/f755c25d/core/src/main/java/org/apache/brooklyn/core/location/DefinedLocationByIdResolver.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/core/location/DefinedLocationByIdResolver.java b/core/src/main/java/org/apache/brooklyn/core/location/DefinedLocationByIdResolver.java
index 0438d1d..ea6cc07 100644
--- a/core/src/main/java/org/apache/brooklyn/core/location/DefinedLocationByIdResolver.java
+++ b/core/src/main/java/org/apache/brooklyn/core/location/DefinedLocationByIdResolver.java
@@ -26,6 +26,7 @@ import org.apache.brooklyn.api.location.Location;
 import org.apache.brooklyn.api.location.LocationDefinition;
 import org.apache.brooklyn.api.location.LocationRegistry;
 import org.apache.brooklyn.api.location.LocationResolver;
+import org.apache.brooklyn.api.location.LocationSpec;
 import org.apache.brooklyn.api.mgmt.ManagementContext;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -46,16 +47,20 @@ public class DefinedLocationByIdResolver implements LocationResolver {
         this.managementContext = checkNotNull(managementContext, "managementContext");
     }
     
-    @SuppressWarnings({ "rawtypes" })
     @Override
-    public Location newLocationFromString(Map locationFlags, String spec, LocationRegistry registry) {
+    public boolean isEnabled() {
+        return true;
+    }
+    
+    @Override
+    public LocationSpec<? extends Location> newLocationSpecFromString(String spec, Map<?, ?> locationFlags, LocationRegistry registry) {
         String id = spec;
         if (spec.toLowerCase().startsWith(ID+":")) {
             id = spec.substring( (ID+":").length() );
         }
         LocationDefinition ld = registry.getDefinedLocationById(id);
         ld.getSpec();
-        return ((BasicLocationRegistry)registry).resolveLocationDefinition(ld, locationFlags, null);
+        return ((BasicLocationRegistry)registry).getLocationSpec(ld, locationFlags).get();
     }
 
     @Override

http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/f755c25d/core/src/main/java/org/apache/brooklyn/core/location/LocationConfigUtils.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/core/location/LocationConfigUtils.java b/core/src/main/java/org/apache/brooklyn/core/location/LocationConfigUtils.java
index 64d31f9..40ecd72 100644
--- a/core/src/main/java/org/apache/brooklyn/core/location/LocationConfigUtils.java
+++ b/core/src/main/java/org/apache/brooklyn/core/location/LocationConfigUtils.java
@@ -60,6 +60,8 @@ public class LocationConfigUtils {
 
     private static final Logger log = LoggerFactory.getLogger(LocationConfigUtils.class);
 
+    public static String BROOKLYN_LOCATION_PREFIX = "brooklyn.location";
+    
     /** Creates an instance of {@link OsCredential} by inspecting {@link LocationConfigKeys#PASSWORD}; 
      * {@link LocationConfigKeys#PRIVATE_KEY_DATA} and {@link LocationConfigKeys#PRIVATE_KEY_FILE};
      * {@link LocationConfigKeys#PRIVATE_KEY_PASSPHRASE} if needed, and
@@ -548,9 +550,14 @@ public class LocationConfigUtils {
         return result;
     }
 
-    public static boolean isEnabled(ManagementContext mgmt, String prefix) {
-        ConfigKey<Boolean> key = ConfigKeys.newConfigKeyWithPrefix(prefix+".", LocationConfigKeys.ENABLED);
-        Boolean enabled = mgmt.getConfig().getConfig(key);
+    public static boolean isResolverPrefixEnabled(ManagementContext mgmt, String resolverIdPrefix) {
+        return isEnabled(mgmt, BROOKLYN_LOCATION_PREFIX+"."+resolverIdPrefix);
+    }
+    
+    /** checks enablement, by looking at <code>key + ".enabled"</code> */
+    public static boolean isEnabled(ManagementContext mgmt, String key) {
+        ConfigKey<Boolean> k = ConfigKeys.newConfigKeyWithPrefix(key+".", LocationConfigKeys.ENABLED);
+        Boolean enabled = mgmt.getConfig().getConfig(k);
         if (enabled!=null) return enabled.booleanValue();
         return true;
     }

http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/f755c25d/core/src/main/java/org/apache/brooklyn/core/location/Locations.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/core/location/Locations.java b/core/src/main/java/org/apache/brooklyn/core/location/Locations.java
index 0b8a060..6fa468d 100644
--- a/core/src/main/java/org/apache/brooklyn/core/location/Locations.java
+++ b/core/src/main/java/org/apache/brooklyn/core/location/Locations.java
@@ -26,6 +26,7 @@ import java.util.Map;
 
 import org.apache.brooklyn.api.entity.Entity;
 import org.apache.brooklyn.api.location.Location;
+import org.apache.brooklyn.api.location.LocationRegistry;
 import org.apache.brooklyn.api.location.LocationSpec;
 import org.apache.brooklyn.api.location.MachineLocation;
 import org.apache.brooklyn.api.mgmt.LocationManager;
@@ -111,7 +112,11 @@ public class Locations {
         }
     }
 
-    public static Location coerce(ManagementContext mgmt, Object rawO) {
+    /**
+     * As {@link LocationRegistry#getLocationManaged(String, Map)} but also accepting maps and yaml representations of maps.
+     * <p>
+     * The caller is responsible for ensuring the resulting {@link Location} is unmanaged. */
+    public static Location coerceToLocationManaged(ManagementContext mgmt, Object rawO) {
         if (rawO==null)
             return null;
         if (rawO instanceof Location)
@@ -138,23 +143,29 @@ public class Locations {
         } else {
             throw new IllegalArgumentException("Location "+rawO+" is invalid; can only parse strings or maps");
         }
-        return mgmt.getLocationRegistry().resolve(name, flags);
+        return mgmt.getLocationRegistry().getLocationManaged(name, flags);
     }
     
-    public static Collection<? extends Location> coerceToCollection(ManagementContext mgmt, Object rawO) {
+    /**
+     * As {@link LocationRegistry#getListOfLocationsManaged(Object)}, 
+     * but using {@link #coerceToLocationManaged(ManagementContext, Object)}
+     * for more forgiving interpretations.
+     * <p>
+     * The caller is responsible for ensuring the resulting {@link Location} is unmanaged. */
+    public static Collection<? extends Location> coerceToCollectionOfLocationsManaged(ManagementContext mgmt, Object rawO) {
         if (rawO==null) return null;
         Object raw = rawO;
         if (raw instanceof Collection) {
             List<Location> result = MutableList.<Location>of();
             for (Object o: (Collection<?>)raw)
-                result.add(coerce(mgmt, o));
+                result.add(coerceToLocationManaged(mgmt, o));
             return result;
         }
         if (raw instanceof String) {
             raw = Yamls.parseAll((String)raw).iterator().next();
             if (raw instanceof Collection)
-                return coerceToCollection(mgmt, raw);
+                return Locations.coerceToCollectionOfLocationsManaged(mgmt, raw);
         }
-        return Collections.singletonList( coerce(mgmt, raw) );
+        return Collections.singletonList( coerceToLocationManaged(mgmt, raw) );
     }
 }

http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/f755c25d/core/src/main/java/org/apache/brooklyn/core/location/NamedLocationResolver.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/core/location/NamedLocationResolver.java b/core/src/main/java/org/apache/brooklyn/core/location/NamedLocationResolver.java
index 6dbe4d7..22f46a4 100644
--- a/core/src/main/java/org/apache/brooklyn/core/location/NamedLocationResolver.java
+++ b/core/src/main/java/org/apache/brooklyn/core/location/NamedLocationResolver.java
@@ -27,6 +27,7 @@ import org.apache.brooklyn.api.location.Location;
 import org.apache.brooklyn.api.location.LocationDefinition;
 import org.apache.brooklyn.api.location.LocationRegistry;
 import org.apache.brooklyn.api.location.LocationResolver;
+import org.apache.brooklyn.api.location.LocationSpec;
 import org.apache.brooklyn.api.mgmt.ManagementContext;
 import org.apache.brooklyn.core.location.internal.LocationInternal;
 import org.apache.brooklyn.util.core.config.ConfigBag;
@@ -56,7 +57,6 @@ public class NamedLocationResolver implements LocationResolver {
 
     public static final String NAMED = "named";
     
-    @SuppressWarnings("unused")
     private ManagementContext managementContext;
 
     @Override
@@ -65,8 +65,12 @@ public class NamedLocationResolver implements LocationResolver {
     }
     
     @Override
-    @SuppressWarnings({ "rawtypes" })
-    public Location newLocationFromString(Map locationFlags, String spec, LocationRegistry registry) {
+    public boolean isEnabled() {
+        return LocationConfigUtils.isResolverPrefixEnabled(managementContext, getPrefix());
+    }
+    
+    @Override
+    public LocationSpec<? extends Location> newLocationSpecFromString(String spec, Map<?, ?> locationFlags, LocationRegistry registry) {
         String name = spec;
         ConfigBag lfBag = ConfigBag.newInstance(locationFlags).putIfAbsent(LocationInternal.ORIGINAL_SPEC, name);
         name = Strings.removeFromStart(spec, getPrefix()+":");
@@ -78,7 +82,7 @@ public class NamedLocationResolver implements LocationResolver {
         
         LocationDefinition ld = registry.getDefinedLocationByName(name);
         if (ld==null) throw new NoSuchElementException("No named location defined matching '"+name+"'");
-        return ((BasicLocationRegistry)registry).resolveLocationDefinition(ld, lfBag.getAllConfig(), name);
+        return registry.getLocationSpec(ld, lfBag.getAllConfig()).get();
     }
 
     @Override
@@ -86,7 +90,7 @@ public class NamedLocationResolver implements LocationResolver {
         return NAMED;
     }
     
-    /** accepts anything starting  named:xxx  or  xxx where xxx is a defined location name */
+    /** accepts anything starting named:, such as named:my-loc, or just my-loc, so long as my-loc is a defined location name */
     @Override
     public boolean accepts(String spec, LocationRegistry registry) {
         if (BasicLocationRegistry.isResolverPrefixForSpec(this, spec, false)) return true;

http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/f755c25d/core/src/main/java/org/apache/brooklyn/core/location/access/PortForwardManagerImpl.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/core/location/access/PortForwardManagerImpl.java b/core/src/main/java/org/apache/brooklyn/core/location/access/PortForwardManagerImpl.java
index 30be900..c3b9858 100644
--- a/core/src/main/java/org/apache/brooklyn/core/location/access/PortForwardManagerImpl.java
+++ b/core/src/main/java/org/apache/brooklyn/core/location/access/PortForwardManagerImpl.java
@@ -75,7 +75,6 @@ import com.google.common.net.HostAndPort;
  *        such as the jcloudsMachine.getJcloudsId().
  * </ul>
  */
-@SuppressWarnings("serial")
 public class PortForwardManagerImpl extends AbstractLocation implements PortForwardManager {
 
     private static final Logger log = LoggerFactory.getLogger(PortForwardManagerImpl.class);

http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/f755c25d/core/src/main/java/org/apache/brooklyn/core/location/access/PortForwardManagerLocationResolver.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/core/location/access/PortForwardManagerLocationResolver.java b/core/src/main/java/org/apache/brooklyn/core/location/access/PortForwardManagerLocationResolver.java
index 3a52877..102bcad 100644
--- a/core/src/main/java/org/apache/brooklyn/core/location/access/PortForwardManagerLocationResolver.java
+++ b/core/src/main/java/org/apache/brooklyn/core/location/access/PortForwardManagerLocationResolver.java
@@ -47,7 +47,7 @@ public class PortForwardManagerLocationResolver extends AbstractLocationResolver
     }
 
     @Override
-    public Location newLocationFromString(Map locationFlags, String spec, LocationRegistry registry) {
+    public LocationSpec<?> newLocationSpecFromString(String spec, Map<?, ?> locationFlags, LocationRegistry registry) {
         ConfigBag config = extractConfig(locationFlags, spec, registry);
         Map globalProperties = registry.getProperties();
         String namedLocation = (String) locationFlags.get(LocationInternal.NAMED_SPEC_NAME.getName());
@@ -59,11 +59,13 @@ public class PortForwardManagerLocationResolver extends AbstractLocationResolver
                         LocationPredicates.configEqualTo(PortForwardManager.SCOPE, scope)));
         
         if (result.isPresent()) {
-            return result.get();
+            // XXX
+//            return result.get();
+            return null;
         } else {
-            PortForwardManager loc = managementContext.getLocationManager().createLocation(LocationSpec.create(PortForwardManagerImpl.class)
+            LocationSpec<PortForwardManagerImpl> loc = LocationSpec.create(PortForwardManagerImpl.class)
                     .configure(config.getAllConfig())
-                    .configure(LocationConfigUtils.finalAndOriginalSpecs(spec, locationFlags, globalProperties, namedLocation)));
+                    .configure(LocationConfigUtils.finalAndOriginalSpecs(spec, locationFlags, globalProperties, namedLocation));
             
             if (LOG.isDebugEnabled()) LOG.debug("Created "+loc+" for scope "+scope);
             return loc;

http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/f755c25d/core/src/main/java/org/apache/brooklyn/core/location/internal/LocationInternal.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/core/location/internal/LocationInternal.java b/core/src/main/java/org/apache/brooklyn/core/location/internal/LocationInternal.java
index 5c83f2d..da4742e 100644
--- a/core/src/main/java/org/apache/brooklyn/core/location/internal/LocationInternal.java
+++ b/core/src/main/java/org/apache/brooklyn/core/location/internal/LocationInternal.java
@@ -37,11 +37,8 @@ import com.google.common.annotations.Beta;
  */
 public interface LocationInternal extends BrooklynObjectInternal, Location {
 
-    @Beta
     public static final ConfigKey<String> ORIGINAL_SPEC = ConfigKeys.newStringConfigKey("spec.original", "The original spec used to instantiate a location");
-    @Beta
     public static final ConfigKey<String> FINAL_SPEC = ConfigKeys.newStringConfigKey("spec.final", "The actual spec (in a chain) which instantiates a location");
-    @Beta
     public static final ConfigKey<String> NAMED_SPEC_NAME = ConfigKeys.newStringConfigKey("spec.named.name", "The name on the (first) named spec in a chain");
     
     /**

http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/f755c25d/core/src/main/java/org/apache/brooklyn/core/mgmt/internal/LocalLocationManager.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/core/mgmt/internal/LocalLocationManager.java b/core/src/main/java/org/apache/brooklyn/core/mgmt/internal/LocalLocationManager.java
index dcd1b43..d73d2ce 100644
--- a/core/src/main/java/org/apache/brooklyn/core/mgmt/internal/LocalLocationManager.java
+++ b/core/src/main/java/org/apache/brooklyn/core/mgmt/internal/LocalLocationManager.java
@@ -29,35 +29,28 @@ import org.apache.brooklyn.api.location.Location;
 import org.apache.brooklyn.api.location.LocationSpec;
 import org.apache.brooklyn.api.location.ProvisioningLocation;
 import org.apache.brooklyn.api.mgmt.AccessController;
-import org.apache.brooklyn.config.ConfigKey;
 import org.apache.brooklyn.core.BrooklynLogging;
 import org.apache.brooklyn.core.BrooklynLogging.LoggingLevel;
-import org.apache.brooklyn.core.config.ConfigKeys;
 import org.apache.brooklyn.core.entity.lifecycle.Lifecycle;
 import org.apache.brooklyn.core.internal.storage.BrooklynStorage;
 import org.apache.brooklyn.core.location.AbstractLocation;
 import org.apache.brooklyn.core.location.internal.LocationInternal;
 import org.apache.brooklyn.core.mgmt.entitlement.Entitlements;
 import org.apache.brooklyn.core.objs.proxy.InternalLocationFactory;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
 import org.apache.brooklyn.util.core.config.ConfigBag;
 import org.apache.brooklyn.util.core.task.Tasks;
 import org.apache.brooklyn.util.exceptions.Exceptions;
 import org.apache.brooklyn.util.exceptions.RuntimeInterruptedException;
 import org.apache.brooklyn.util.stream.Streams;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
-import com.google.common.annotations.Beta;
 import com.google.common.base.Preconditions;
 import com.google.common.base.Predicate;
 import com.google.common.collect.ImmutableList;
 import com.google.common.collect.Maps;
 
 public class LocalLocationManager implements LocationManagerInternal {
-
-    @Beta /* expect to remove when API returns LocationSpec or similar */
-    public static final ConfigKey<Boolean> CREATE_UNMANAGED = ConfigKeys.newBooleanConfigKey("brooklyn.internal.location.createUnmanaged",
-        "If set on a location or spec, causes the manager to create it in an unmanaged state (for peeking)", false);
     
     private static final Logger log = LoggerFactory.getLogger(LocalLocationManager.class);
 

http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/f755c25d/core/src/main/java/org/apache/brooklyn/core/mgmt/internal/LocationManagerInternal.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/core/mgmt/internal/LocationManagerInternal.java b/core/src/main/java/org/apache/brooklyn/core/mgmt/internal/LocationManagerInternal.java
index d37c115..429d42c 100644
--- a/core/src/main/java/org/apache/brooklyn/core/mgmt/internal/LocationManagerInternal.java
+++ b/core/src/main/java/org/apache/brooklyn/core/mgmt/internal/LocationManagerInternal.java
@@ -19,10 +19,18 @@
 package org.apache.brooklyn.core.mgmt.internal;
 
 import org.apache.brooklyn.api.location.Location;
+import org.apache.brooklyn.api.location.LocationSpec;
 import org.apache.brooklyn.api.mgmt.LocationManager;
+import org.apache.brooklyn.config.ConfigKey;
+import org.apache.brooklyn.core.config.ConfigKeys;
 
 public interface LocationManagerInternal extends LocationManager, BrooklynObjectManagerInternal<Location> {
 
+    /** Indicates that a call to {@link #createLocation(LocationSpec)} should create a location instance not
+     * linked to the management context. This allows clients to peek at the result but not to use it. */
+    public static final ConfigKey<Boolean> CREATE_UNMANAGED = ConfigKeys.newBooleanConfigKey("brooklyn.internal.location.createUnmanaged",
+        "If set on a location or spec, causes the manager to create it in an unmanaged state (for peeking)", false);
+
     public Iterable<String> getLocationIds();
 
 }

http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/f755c25d/core/src/main/java/org/apache/brooklyn/core/mgmt/persist/BrooklynPersistenceUtils.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/core/mgmt/persist/BrooklynPersistenceUtils.java b/core/src/main/java/org/apache/brooklyn/core/mgmt/persist/BrooklynPersistenceUtils.java
index ee79764..ff57645 100644
--- a/core/src/main/java/org/apache/brooklyn/core/mgmt/persist/BrooklynPersistenceUtils.java
+++ b/core/src/main/java/org/apache/brooklyn/core/mgmt/persist/BrooklynPersistenceUtils.java
@@ -80,19 +80,18 @@ public class BrooklynPersistenceUtils {
     
     /** Creates a {@link PersistenceObjectStore} for use with a specified set of modes. */
     public static PersistenceObjectStore newPersistenceObjectStore(ManagementContext managementContext,
-            String locationSpec, String locationContainer, PersistMode persistMode, HighAvailabilityMode highAvailabilityMode) {
+            String locationSpecString, String locationContainer, PersistMode persistMode, HighAvailabilityMode highAvailabilityMode) {
         PersistenceObjectStore destinationObjectStore;
-        locationContainer = BrooklynServerPaths.newMainPersistencePathResolver(managementContext).location(locationSpec).dir(locationContainer).resolve();
+        locationContainer = BrooklynServerPaths.newMainPersistencePathResolver(managementContext).location(locationSpecString).dir(locationContainer).resolve();
 
-        Location location = null;
-        if (Strings.isBlank(locationSpec)) {
-            location = managementContext.getLocationManager().createLocation(LocationSpec.create(LocalhostMachineProvisioningLocation.class)
+        LocationSpec<?> locationSpec = Strings.isBlank(locationSpecString) ?
+            LocationSpec.create(LocalhostMachineProvisioningLocation.class) :
+                managementContext.getLocationRegistry().getLocationSpec(locationSpecString).get();
+            
+        Location location = managementContext.getLocationManager().createLocation(locationSpec
                 .configure(LocalLocationManager.CREATE_UNMANAGED, true));
-        } else {
-            location = managementContext.getLocationRegistry().resolve(locationSpec, false, null).get();
-            if (!(location instanceof LocationWithObjectStore)) {
-                throw new IllegalArgumentException("Destination location "+location+" does not offer a persistent store");
-            }
+        if (!(location instanceof LocationWithObjectStore)) {
+            throw new IllegalArgumentException("Destination location "+location+" does not offer a persistent store");
         }
         destinationObjectStore = ((LocationWithObjectStore)location).newPersistenceObjectStore(locationContainer);
         

http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/f755c25d/core/src/main/java/org/apache/brooklyn/entity/group/DynamicRegionsFabricImpl.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/entity/group/DynamicRegionsFabricImpl.java b/core/src/main/java/org/apache/brooklyn/entity/group/DynamicRegionsFabricImpl.java
index 427dd6c..f4db86e 100644
--- a/core/src/main/java/org/apache/brooklyn/entity/group/DynamicRegionsFabricImpl.java
+++ b/core/src/main/java/org/apache/brooklyn/entity/group/DynamicRegionsFabricImpl.java
@@ -42,7 +42,7 @@ public class DynamicRegionsFabricImpl extends DynamicFabricImpl implements Dynam
     @Override
     public String addRegion(String location) {
         Preconditions.checkNotNull(location, "location");
-        Location l = getManagementContext().getLocationRegistry().resolve(location);
+        Location l = getManagementContext().getLocationRegistry().getLocationManaged(location);
         addLocations(Arrays.asList(l));
         
         Entity e = addCluster(l);

http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/f755c25d/core/src/main/java/org/apache/brooklyn/location/byon/HostLocationResolver.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/location/byon/HostLocationResolver.java b/core/src/main/java/org/apache/brooklyn/location/byon/HostLocationResolver.java
index 88b32f9..f2d45ab 100644
--- a/core/src/main/java/org/apache/brooklyn/location/byon/HostLocationResolver.java
+++ b/core/src/main/java/org/apache/brooklyn/location/byon/HostLocationResolver.java
@@ -40,9 +40,8 @@ public class HostLocationResolver extends AbstractLocationResolver {
     
     private static final String HOST = "host";
     
-    @SuppressWarnings("rawtypes")
     @Override
-    public Location newLocationFromString(Map locationFlags, String spec, LocationRegistry registry) {
+    public LocationSpec<?> newLocationSpecFromString(String spec, Map<?, ?> locationFlags, LocationRegistry registry) {
         // Extract args from spec
         ParsedSpec parsedSpec = specParser.parse(spec);
         Map<String, String> argsMap = parsedSpec.argsMap;
@@ -64,16 +63,16 @@ public class HostLocationResolver extends AbstractLocationResolver {
 
         // Generate target spec
         String target = "byon("+KeyValueParser.toLine(argsMap)+")";
-        Maybe<Location> testResolve = managementContext.getLocationRegistry().resolve(target, false, null);
+        Maybe<LocationSpec<?>> testResolve = managementContext.getLocationRegistry().getLocationSpec(target);
         if (!testResolve.isPresent()) {
             throw new IllegalArgumentException("Invalid target location '" + target + "' for location '"+HOST+"': "+
                 Exceptions.collapseText( ((Absent<?>)testResolve).getException() ), ((Absent<?>)testResolve).getException());
         }
         
-        return managementContext.getLocationManager().createLocation(LocationSpec.create(SingleMachineProvisioningLocation.class)
+        return LocationSpec.create(SingleMachineProvisioningLocation.class)
                 .configure("location", target)
                 .configure("locationFlags", flags.getAllConfig())
-                .configure(LocationConfigUtils.finalAndOriginalSpecs(spec, locationFlags, globalProperties, namedLocation)));
+                .configure(LocationConfigUtils.finalAndOriginalSpecs(spec, locationFlags, globalProperties, namedLocation));
     }
     
     @Override

http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/f755c25d/core/src/main/java/org/apache/brooklyn/location/byon/SingleMachineLocationResolver.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/location/byon/SingleMachineLocationResolver.java b/core/src/main/java/org/apache/brooklyn/location/byon/SingleMachineLocationResolver.java
index 4d4db07..9c238eb 100644
--- a/core/src/main/java/org/apache/brooklyn/location/byon/SingleMachineLocationResolver.java
+++ b/core/src/main/java/org/apache/brooklyn/location/byon/SingleMachineLocationResolver.java
@@ -36,10 +36,10 @@ public class SingleMachineLocationResolver extends AbstractLocationResolver {
     
     private static final String SINGLE = "single";
     
-    @SuppressWarnings({ "rawtypes", "unchecked" })
     @Override
-    public Location newLocationFromString(Map locationFlags, String spec, LocationRegistry registry) {
+    public LocationSpec<?> newLocationSpecFromString(String spec, Map<?, ?> locationFlags, LocationRegistry registry) {
         ConfigBag config = extractConfig(locationFlags, spec, registry);
+        @SuppressWarnings("rawtypes")
         Map globalProperties = registry.getProperties();
         String namedLocation = (String) locationFlags.get(LocationInternal.NAMED_SPEC_NAME.getName());
         
@@ -52,16 +52,16 @@ public class SingleMachineLocationResolver extends AbstractLocationResolver {
         }
         String target = config.getStringKey("target").toString();
         config.remove("target");
-        Maybe<Location> testResolve = managementContext.getLocationRegistry().resolve(target, false, null);
+        Maybe<LocationSpec<?>> testResolve = managementContext.getLocationRegistry().getLocationSpec(target);
         if (!testResolve.isPresent()) {
             throw new IllegalArgumentException("Invalid target location '" + target + "' for location '"+SINGLE+"': "+
                 Exceptions.collapseText( ((Absent<?>)testResolve).getException() ));
         }
         
-        return managementContext.getLocationManager().createLocation(LocationSpec.create(SingleMachineProvisioningLocation.class)
+        return LocationSpec.create(SingleMachineProvisioningLocation.class)
                 .configure("location", target)
                 .configure("locationFlags", config.getAllConfig())
-                .configure(LocationConfigUtils.finalAndOriginalSpecs(spec, locationFlags, globalProperties, namedLocation)));
+                .configure(LocationConfigUtils.finalAndOriginalSpecs(spec, locationFlags, globalProperties, namedLocation));
     }
     
     @Override

http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/f755c25d/core/src/main/java/org/apache/brooklyn/location/byon/SingleMachineProvisioningLocation.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/location/byon/SingleMachineProvisioningLocation.java b/core/src/main/java/org/apache/brooklyn/location/byon/SingleMachineProvisioningLocation.java
index cba4966..3bd98ce 100644
--- a/core/src/main/java/org/apache/brooklyn/location/byon/SingleMachineProvisioningLocation.java
+++ b/core/src/main/java/org/apache/brooklyn/location/byon/SingleMachineProvisioningLocation.java
@@ -68,7 +68,7 @@ public class SingleMachineProvisioningLocation<T extends MachineLocation> extend
     public synchronized T obtain() throws NoMachinesAvailableException {
         if (singleLocation == null) {
             if (provisioningLocation == null) {
-                provisioningLocation = (MachineProvisioningLocation) getManagementContext().getLocationRegistry().resolve(
+                provisioningLocation = (MachineProvisioningLocation) getManagementContext().getLocationRegistry().getLocationManaged(
                     location, locationFlags);
             }
             singleLocation = provisioningLocation.obtain(ImmutableMap.of());

http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/f755c25d/core/src/main/java/org/apache/brooklyn/location/localhost/LocalhostLocationResolver.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/location/localhost/LocalhostLocationResolver.java b/core/src/main/java/org/apache/brooklyn/location/localhost/LocalhostLocationResolver.java
index 2c8f827..65ed85c 100644
--- a/core/src/main/java/org/apache/brooklyn/location/localhost/LocalhostLocationResolver.java
+++ b/core/src/main/java/org/apache/brooklyn/location/localhost/LocalhostLocationResolver.java
@@ -22,7 +22,6 @@ import java.util.Map;
 
 import org.apache.brooklyn.api.location.Location;
 import org.apache.brooklyn.api.location.LocationRegistry;
-import org.apache.brooklyn.api.location.LocationResolver;
 import org.apache.brooklyn.config.ConfigKey;
 import org.apache.brooklyn.core.config.ConfigKeys;
 import org.apache.brooklyn.core.location.AbstractLocationResolver;
@@ -41,9 +40,9 @@ import org.apache.brooklyn.util.core.config.ConfigBag;
  * 
  * @author alex, aled
  */
-public class LocalhostLocationResolver extends AbstractLocationResolver implements LocationResolver.EnableableLocationResolver {
+public class LocalhostLocationResolver extends AbstractLocationResolver {
 
-    private static String BROOKLYN_LOCATION_LOCALHOST_PREFIX = "brooklyn.location.localhost";
+    private static String BROOKLYN_LOCATION_LOCALHOST_PREFIX = LocationConfigUtils.BROOKLYN_LOCATION_PREFIX + "." + "localhost";
     
     public static ConfigKey<Boolean> LOCALHOST_ENABLED = ConfigKeys.newConfigKeyWithPrefix(BROOKLYN_LOCATION_LOCALHOST_PREFIX+".", LocationConfigKeys.ENABLED);
     
@@ -56,7 +55,8 @@ public class LocalhostLocationResolver extends AbstractLocationResolver implemen
 
     @Override
     public boolean isEnabled() {
-        return LocationConfigUtils.isEnabled(managementContext, BROOKLYN_LOCATION_LOCALHOST_PREFIX);
+        // right now these two checks, but in case the generic mechanism in super changes...
+        return super.isEnabled() && LocationConfigUtils.isEnabled(managementContext, BROOKLYN_LOCATION_LOCALHOST_PREFIX);
     }
 
     @Override

http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/f755c25d/core/src/main/java/org/apache/brooklyn/location/multi/MultiLocation.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/location/multi/MultiLocation.java b/core/src/main/java/org/apache/brooklyn/location/multi/MultiLocation.java
index f78d0d6..afd3212 100644
--- a/core/src/main/java/org/apache/brooklyn/location/multi/MultiLocation.java
+++ b/core/src/main/java/org/apache/brooklyn/location/multi/MultiLocation.java
@@ -44,6 +44,7 @@ import org.apache.brooklyn.util.exceptions.CompoundRuntimeException;
 import org.apache.brooklyn.util.exceptions.Exceptions;
 import org.apache.brooklyn.util.text.Strings;
 
+import com.google.common.annotations.Beta;
 import com.google.common.base.Predicate;
 import com.google.common.collect.ImmutableList;
 import com.google.common.collect.Iterables;
@@ -57,17 +58,16 @@ public class MultiLocation<T extends MachineLocation> extends AbstractLocation i
 
     @SuppressWarnings("serial")
     @SetFromFlag("subLocations")
-    public static final ConfigKey<List<MachineProvisioningLocation<?>>> SUB_LOCATIONS = ConfigKeys.newConfigKey(
-            new TypeToken<List<MachineProvisioningLocation<?>>>() {},
+    public static final ConfigKey<List<?>> SUB_LOCATIONS = ConfigKeys.newConfigKey(
+            new TypeToken<List<?>>() {},
             "subLocations", 
-            "The sub-machines that this location can delegate to");
+            "The sub-machines Location instances or LocationSpecs that this location can delegate to");
     
     @Override
     public void init() {
         super.init();
-        List<MachineProvisioningLocation<?>> subLocs = getSubLocations();
-        checkState(subLocs.size() >= 1, "sub-locations must not be empty");
-        AvailabilityZoneExtension azExtension = new AvailabilityZoneExtensionImpl(getManagementContext(), subLocs);
+        List<MachineProvisioningLocation<?>> subLocations = getSubLocationsAsLocations();
+        AvailabilityZoneExtension azExtension = new AvailabilityZoneExtensionImpl(getManagementContext(), subLocations);
         addExtension(AvailabilityZoneExtension.class, azExtension);
     }
 
@@ -81,7 +81,7 @@ public class MultiLocation<T extends MachineLocation> extends AbstractLocation i
     @SuppressWarnings("unchecked")
     @Override
     public T obtain(Map<?, ?> flags) throws NoMachinesAvailableException {
-        List<MachineProvisioningLocation<?>> sublocsList = getSubLocations();
+        List<MachineProvisioningLocation<?>> sublocsList = getSubLocationsAsLocations();
         Iterator<MachineProvisioningLocation<?>> sublocs = sublocsList.iterator();
         List<NoMachinesAvailableException> errors = MutableList.of();
         while (sublocs.hasNext()) {
@@ -109,9 +109,33 @@ public class MultiLocation<T extends MachineLocation> extends AbstractLocation i
             " configured here: "+msg, wrapped);
     }
 
-    public List<MachineProvisioningLocation<?>> getSubLocations() {
+    @Beta
+    public List<?> getSubLocationsAsSpecsOrInstances() {
         return getRequiredConfig(SUB_LOCATIONS);
     }
+    @Beta
+    public List<MachineProvisioningLocation<?>> getSubLocationsAsLocations() {
+        List<?> subLocsOrSpecs = getSubLocationsAsSpecsOrInstances();
+        checkState(subLocsOrSpecs.size() >= 1, "sub-locations must not be empty");
+        // TODO there is a possible leak case in the unmanagement of these locations if something fails
+        List<MachineProvisioningLocation<?>> subLocations = MutableList.of();
+        for (Object l: subLocsOrSpecs) {
+            if (l instanceof LocationSpec) {
+                if (((LocationSpec<?>)l).getParent()==null) {
+                    // use a copy with us set as parent
+                    l = LocationSpec.create((LocationSpec<?>)l).parent(this);
+                }
+                l = getManagementContext().getLocationManager().createLocation((LocationSpec<?>)l);
+            }
+            if (l instanceof MachineProvisioningLocation) {
+                subLocations.add((MachineProvisioningLocation<?>)l);
+            } else {
+                throw new IllegalArgumentException("Invalid sublocation "+l+" for "+this+"; expecting "+MachineProvisioningLocation.class);
+            }
+        }
+        config().set(SUB_LOCATIONS, subLocations);
+        return subLocations;
+    }
 
     @SuppressWarnings("unchecked")
     @Override
@@ -136,7 +160,7 @@ public class MultiLocation<T extends MachineLocation> extends AbstractLocation i
 
     @SuppressWarnings("unchecked")
     protected MachineProvisioningLocation<T> firstSubLoc() {
-        return (MachineProvisioningLocation<T>) Iterables.get(getSubLocations(), 0);
+        return (MachineProvisioningLocation<T>) Iterables.get(getSubLocationsAsLocations(), 0);
     }
 
     protected <K> K getRequiredConfig(ConfigKey<K> key) {


Mime
View raw message