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

[08/18] brooklyn-server git commit: first pass rewriting LocationRegistry and resolvers to return specs

http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/f755c25d/core/src/main/java/org/apache/brooklyn/location/multi/MultiLocationResolver.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/location/multi/MultiLocationResolver.java b/core/src/main/java/org/apache/brooklyn/location/multi/MultiLocationResolver.java
index 5d9dd19..022b7e2 100644
--- a/core/src/main/java/org/apache/brooklyn/location/multi/MultiLocationResolver.java
+++ b/core/src/main/java/org/apache/brooklyn/location/multi/MultiLocationResolver.java
@@ -34,14 +34,13 @@ import org.apache.brooklyn.api.mgmt.ManagementContext;
 import org.apache.brooklyn.core.location.BasicLocationRegistry;
 import org.apache.brooklyn.core.location.LocationConfigUtils;
 import org.apache.brooklyn.core.location.LocationPropertiesFromBrooklynProperties;
-import org.apache.brooklyn.core.location.Locations;
 import org.apache.brooklyn.util.collections.MutableMap;
-import org.apache.brooklyn.util.exceptions.Exceptions;
 import org.apache.brooklyn.util.text.KeyValueParser;
 import org.apache.brooklyn.util.text.StringEscapes.JavaStringEscapes;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import com.google.common.collect.ImmutableMap;
 import com.google.common.collect.Lists;
 
 public class MultiLocationResolver implements LocationResolver {
@@ -60,11 +59,16 @@ public class MultiLocationResolver implements LocationResolver {
     }
 
     @Override
-    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) {
         // FIXME pass all flags into the location
         
-        Map globalProperties = registry.getProperties();
-        Map<String,?> locationArgs;
+        Map<?,?> globalProperties = registry.getProperties();
+        Map<Object,?> locationArgs;
         if (spec.equalsIgnoreCase(MULTI)) {
             locationArgs = MutableMap.copyOf(locationFlags);
         } else {
@@ -74,12 +78,13 @@ public class MultiLocationResolver implements LocationResolver {
             }
             String args = matcher.group(2);
             // TODO we are ignoring locationFlags after this (apart from named), looking only at these args
-            locationArgs = KeyValueParser.parseMap(args);
+            locationArgs = MutableMap.<Object,Object>copyOf(KeyValueParser.parseMap(args));
         }
         String namedLocation = (String) locationFlags.get("named");
 
-        Map<String, Object> filteredProperties = new LocationPropertiesFromBrooklynProperties().getLocationProperties(null, namedLocation, globalProperties);
-        MutableMap<String, Object> flags = MutableMap.<String, Object>builder()
+        @SuppressWarnings({ "unchecked", "rawtypes" })
+        Map<String, Object> filteredProperties = new LocationPropertiesFromBrooklynProperties().getLocationProperties(null, namedLocation, (Map)globalProperties);
+        MutableMap<Object, Object> flags = MutableMap.<Object, Object>builder()
                 .putAll(filteredProperties)
                 .putAll(locationFlags)
                 .removeAll("named")
@@ -90,50 +95,37 @@ public class MultiLocationResolver implements LocationResolver {
         }
         
         // TODO do we need to pass location flags etc into the children to ensure they are inherited?
-        List<Location> targets = Lists.newArrayList();
+        List<LocationSpec<?>> targets = Lists.newArrayList();
         Object targetSpecs = locationArgs.remove("targets");
-        try {
-            if (targetSpecs instanceof String) {
-                for (String targetSpec : JavaStringEscapes.unwrapJsonishListIfPossible((String)targetSpecs)) {
-                    targets.add(managementContext.getLocationRegistry().resolve(targetSpec));
-                }
-            } else if (targetSpecs instanceof Iterable) {
-                for (Object targetSpec: (Iterable<?>)targetSpecs) {
-                    if (targetSpec instanceof String) {
-                        targets.add(managementContext.getLocationRegistry().resolve((String)targetSpec));
-                    } else {
-                        Set<?> keys = ((Map<?,?>)targetSpec).keySet();
-                        if (keys.size()!=1) 
-                            throw new IllegalArgumentException("targets supplied to MultiLocation must be a list of single-entry maps (got map of size "+keys.size()+": "+targetSpec+")");
-                        Object key = keys.iterator().next();
-                        Object flagsS = ((Map<?,?>)targetSpec).get(key);
-                        targets.add(managementContext.getLocationRegistry().resolve((String)key, (Map<?,?>)flagsS));
-                    }
-                }
-            } else throw new IllegalArgumentException("targets must be supplied to MultiLocation, either as string spec or list of single-entry maps each being a location spec");
-            
-            MultiLocation result = managementContext.getLocationManager().createLocation(LocationSpec.create(MultiLocation.class)
-                    .configure(flags)
-                    .configure("subLocations", targets)
-                    .configure(LocationConfigUtils.finalAndOriginalSpecs(spec, locationFlags, globalProperties, namedLocation)));
 
-            // TODO Important workaround for BasicLocationRegistry.resolveForPeeking.
-            // That creates a location (from the resolver) and immediately unmanages it.
-            // The unmanage *must* remove all the targets created here; otherwise we have a leak.
-            // Adding the targets as children achieves this.
-            for (Location target : targets) {
-                target.setParent(result);
+        if (targetSpecs instanceof String) {
+            for (String targetSpec : JavaStringEscapes.unwrapJsonishListIfPossible((String)targetSpecs)) {
+                targets.add(managementContext.getLocationRegistry().getLocationSpec(targetSpec, ImmutableMap.of()).get());
             }
-            return result;
-
-        } catch (Exception e) {
-            // Must clean up after ourselves: don't leak sub-locations on error
-            if (LOG.isDebugEnabled()) LOG.debug("Problem resolving MultiLocation; cleaning up any sub-locations and rethrowing: "+e);
-            for (Location target : targets) {
-                Locations.unmanage(target);
+        } else if (targetSpecs instanceof Iterable) {
+            for (Object targetSpec: (Iterable<?>)targetSpecs) {
+                if (targetSpec instanceof String) {
+                    targets.add(managementContext.getLocationRegistry().getLocationSpec((String)targetSpec, ImmutableMap.of()).get());
+                } else {
+                    Set<?> keys = ((Map<?,?>)targetSpec).keySet();
+                    if (keys.size()!=1) 
+                        throw new IllegalArgumentException("targets supplied to MultiLocation must be a list of single-entry maps (got map of size "+keys.size()+": "+targetSpec+")");
+                    Object key = keys.iterator().next();
+                    Object flagsS = ((Map<?,?>)targetSpec).get(key);
+                    targets.add(managementContext.getLocationRegistry().getLocationSpec((String)key, (Map<?,?>)flagsS).get());
+                }
             }
-            throw Exceptions.propagate(e);
+        } else throw new IllegalArgumentException("targets must be supplied to MultiLocation, either as string spec or list of single-entry maps each being a location spec");
+
+        if (LOG.isDebugEnabled()) {
+            LOG.debug("Creating multi-location spec for sub-locations "+targets);
         }
+        LocationSpec<?> result = LocationSpec.create(MultiLocation.class)
+            .configure(flags)
+            .configure(MultiLocation.SUB_LOCATIONS.getName(), targets)
+            .configure(LocationConfigUtils.finalAndOriginalSpecs(spec, locationFlags, globalProperties, namedLocation));
+
+        return result;
     }
 
     @Override

http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/f755c25d/core/src/main/java/org/apache/brooklyn/location/ssh/SshMachineLocation.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/location/ssh/SshMachineLocation.java b/core/src/main/java/org/apache/brooklyn/location/ssh/SshMachineLocation.java
index 50349e6..4879829 100644
--- a/core/src/main/java/org/apache/brooklyn/location/ssh/SshMachineLocation.java
+++ b/core/src/main/java/org/apache/brooklyn/location/ssh/SshMachineLocation.java
@@ -300,7 +300,7 @@ public class SshMachineLocation extends AbstractLocation implements MachineLocat
         // Register any pre-existing port-mappings with the PortForwardManager
         Map<Integer, String> tcpPortMappings = getConfig(TCP_PORT_MAPPINGS);
         if (tcpPortMappings != null) {
-            PortForwardManager pfm = (PortForwardManager) getManagementContext().getLocationRegistry().resolve("portForwardManager(scope=global)");
+            PortForwardManager pfm = (PortForwardManager) getManagementContext().getLocationRegistry().getLocationManaged("portForwardManager(scope=global)");
             for (Map.Entry<Integer, String> entry : tcpPortMappings.entrySet()) {
                 int targetPort = entry.getKey();
                 HostAndPort publicEndpoint = HostAndPort.fromString(entry.getValue());

http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/f755c25d/launcher-common/src/main/java/org/apache/brooklyn/launcher/common/BasicLauncher.java
----------------------------------------------------------------------
diff --git a/launcher-common/src/main/java/org/apache/brooklyn/launcher/common/BasicLauncher.java b/launcher-common/src/main/java/org/apache/brooklyn/launcher/common/BasicLauncher.java
index 8ff0ea3..4188fde 100644
--- a/launcher-common/src/main/java/org/apache/brooklyn/launcher/common/BasicLauncher.java
+++ b/launcher-common/src/main/java/org/apache/brooklyn/launcher/common/BasicLauncher.java
@@ -470,7 +470,7 @@ public class BasicLauncher<T extends BasicLauncher<T>> {
         // Create the locations. Must happen after persistence is started in case the
         // management context's catalog is loaded from persisted state. (Location
         // resolution uses the catalog's classpath to scan for resolvers.)
-        locations.addAll(managementContext.getLocationRegistry().resolve(locationSpecs));
+        locations.addAll(managementContext.getLocationRegistry().getListOfLocationsManaged(locationSpecs));
     }
 
     protected void startingUp() {

http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/f755c25d/locations/jclouds/src/main/java/org/apache/brooklyn/core/mgmt/persist/jclouds/JcloudsBlobStoreBasedObjectStore.java
----------------------------------------------------------------------
diff --git a/locations/jclouds/src/main/java/org/apache/brooklyn/core/mgmt/persist/jclouds/JcloudsBlobStoreBasedObjectStore.java b/locations/jclouds/src/main/java/org/apache/brooklyn/core/mgmt/persist/jclouds/JcloudsBlobStoreBasedObjectStore.java
index 6c92753..7705e50 100644
--- a/locations/jclouds/src/main/java/org/apache/brooklyn/core/mgmt/persist/jclouds/JcloudsBlobStoreBasedObjectStore.java
+++ b/locations/jclouds/src/main/java/org/apache/brooklyn/core/mgmt/persist/jclouds/JcloudsBlobStoreBasedObjectStore.java
@@ -93,7 +93,7 @@ public class JcloudsBlobStoreBasedObjectStore implements PersistenceObjectStore
             if (location==null) {
                 Preconditions.checkNotNull(locationSpec, "locationSpec required for remote object store when location is null");
                 Preconditions.checkNotNull(mgmt, "mgmt not injected / object store not prepared");
-                location = (JcloudsLocation) mgmt.getLocationRegistry().resolve(locationSpec);
+                location = (JcloudsLocation) mgmt.getLocationRegistry().getLocationManaged(locationSpec);
             }
             
             String identity = checkNotNull(location.getConfig(LocationConfigKeys.ACCESS_IDENTITY), "identity must not be null");

http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/f755c25d/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/JcloudsByonLocationResolver.java
----------------------------------------------------------------------
diff --git a/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/JcloudsByonLocationResolver.java b/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/JcloudsByonLocationResolver.java
index 95597c5..c4e09fb 100644
--- a/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/JcloudsByonLocationResolver.java
+++ b/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/JcloudsByonLocationResolver.java
@@ -25,6 +25,7 @@ import java.util.Map;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 
+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.api.location.LocationSpec;
@@ -35,8 +36,6 @@ import org.apache.brooklyn.core.location.LocationConfigKeys;
 import org.apache.brooklyn.core.location.LocationConfigUtils;
 import org.apache.brooklyn.core.location.LocationPropertiesFromBrooklynProperties;
 import org.apache.brooklyn.core.location.internal.LocationInternal;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
 import org.apache.brooklyn.location.byon.FixedListMachineProvisioningLocation;
 import org.apache.brooklyn.util.collections.MutableMap;
 import org.apache.brooklyn.util.core.config.ConfigBag;
@@ -45,6 +44,8 @@ import org.apache.brooklyn.util.text.KeyValueParser;
 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;
+import org.slf4j.LoggerFactory;
 
 import com.google.common.collect.Lists;
 import com.google.common.collect.Maps;
@@ -75,9 +76,14 @@ public class JcloudsByonLocationResolver implements LocationResolver {
         this.managementContext = checkNotNull(managementContext, "managementContext");
     }
     
+    @Override
+    public boolean isEnabled() {
+        return LocationConfigUtils.isResolverPrefixEnabled(managementContext, getPrefix());
+    }
+    
     // TODO Remove some duplication from JcloudsResolver; needs more careful review
     @Override
-    public FixedListMachineProvisioningLocation<JcloudsSshMachineLocation> newLocationFromString(Map locationFlags, String spec, LocationRegistry registry) {
+    public LocationSpec<? extends Location> newLocationSpecFromString(String spec, Map<?, ?> locationFlags, LocationRegistry registry) {
         Map globalProperties = registry.getProperties();
 
         Matcher matcher = PATTERN.matcher(spec);
@@ -139,6 +145,7 @@ public class JcloudsByonLocationResolver implements LocationResolver {
                     .putIfNotNull("privateKeyFile", privateKeyFile)
                     .build();
             try {
+                // TODO management of these machines may be odd, as it is passed in as a key as config to a spec
                 JcloudsSshMachineLocation machine = jcloudsLocation.rebindMachine(jcloudsLocation.config().getBag().putAll(machineFlags));
                 machines.add(machine);
             } catch (NoMachinesAvailableException e) {
@@ -158,9 +165,9 @@ public class JcloudsByonLocationResolver implements LocationResolver {
 
         log.debug("Created Jclouds BYON location "+name+": "+machines);
         
-        return managementContext.getLocationManager().createLocation(LocationSpec.create(FixedListMachineProvisioningLocation.class)
+        return LocationSpec.create(FixedListMachineProvisioningLocation.class)
                 .configure(flags.getAllConfig())
-                .configure(LocationConfigUtils.finalAndOriginalSpecs(spec, locationFlags, globalProperties, namedLocation)));
+                .configure(LocationConfigUtils.finalAndOriginalSpecs(spec, locationFlags, globalProperties, namedLocation));
     }
     
     private Map getAllProperties(LocationRegistry registry, Map<?,?> properties) {

http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/f755c25d/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/JcloudsLocationResolver.java
----------------------------------------------------------------------
diff --git a/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/JcloudsLocationResolver.java b/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/JcloudsLocationResolver.java
index 3921407..239777a 100644
--- a/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/JcloudsLocationResolver.java
+++ b/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/JcloudsLocationResolver.java
@@ -25,6 +25,7 @@ import java.util.Collection;
 import java.util.Map;
 import java.util.NoSuchElementException;
 
+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.api.location.LocationSpec;
@@ -33,13 +34,14 @@ import org.apache.brooklyn.core.location.BasicLocationRegistry;
 import org.apache.brooklyn.core.location.LocationConfigKeys;
 import org.apache.brooklyn.core.location.LocationConfigUtils;
 import org.apache.brooklyn.core.location.internal.LocationInternal;
+import org.apache.brooklyn.util.collections.MutableMap;
+import org.apache.brooklyn.util.text.Strings;
 import org.jclouds.apis.ApiMetadata;
 import org.jclouds.apis.Apis;
 import org.jclouds.providers.ProviderMetadata;
 import org.jclouds.providers.Providers;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
-import org.apache.brooklyn.util.text.Strings;
 
 import com.google.common.collect.ImmutableMap;
 import com.google.common.collect.Maps;
@@ -82,6 +84,11 @@ public class JcloudsLocationResolver implements LocationResolver {
         this.managementContext = checkNotNull(managementContext, "managementContext");
     }
     
+    @Override
+    public boolean isEnabled() {
+        return LocationConfigUtils.isResolverPrefixEnabled(managementContext, getPrefix());
+    }
+    
     protected class JcloudsSpecParser {
         String providerOrApi;
         String parameter;
@@ -147,8 +154,7 @@ public class JcloudsLocationResolver implements LocationResolver {
     }
     
     @Override
-    @SuppressWarnings("unchecked")
-    public JcloudsLocation newLocationFromString(Map locationFlags, String spec, LocationRegistry registry) {
+    public LocationSpec<? extends Location> newLocationSpecFromString(String spec, Map<?, ?> locationFlags, LocationRegistry registry) {
         Map globalProperties = registry.getProperties();
 
         JcloudsSpecParser details = new JcloudsSpecParser().parse(spec, false);
@@ -170,10 +176,10 @@ public class JcloudsLocationResolver implements LocationResolver {
         // But for everything passed in via locationFlags, pass those as-is.
         // TODO Should revisit the locationFlags: where are these actually used? Reason accepting properties without
         //      full prefix is that the map's context is explicitly this location, rather than being generic properties.
-        Map allProperties = getAllProperties(registry, globalProperties);
+        Map<String,Object> allProperties = getAllProperties(registry, globalProperties);
         String regionOrEndpoint = details.parameter;
         if (regionOrEndpoint==null && isProvider) regionOrEndpoint = (String)locationFlags.get(LocationConfigKeys.CLOUD_REGION_ID.getName());
-        Map jcloudsProperties = new JcloudsPropertiesFromBrooklynProperties().getJcloudsProperties(providerOrApi, regionOrEndpoint, namedLocation, allProperties);
+        Map<Object,Object> jcloudsProperties = MutableMap.<Object,Object>copyOf(new JcloudsPropertiesFromBrooklynProperties().getJcloudsProperties(providerOrApi, regionOrEndpoint, namedLocation, allProperties));
         jcloudsProperties.putAll(locationFlags);
         
         if (regionOrEndpoint!=null) {
@@ -192,14 +198,14 @@ public class JcloudsLocationResolver implements LocationResolver {
             }
         }
         
-        return managementContext.getLocationManager().createLocation(LocationSpec.create(getLocationClass())
+        return LocationSpec.create(getLocationClass())
                 .configure(LocationConfigUtils.finalAndOriginalSpecs(spec, jcloudsProperties, globalProperties, namedLocation))
-                .configure(jcloudsProperties) );
+                .configure(jcloudsProperties);
     }
 
     @SuppressWarnings("unchecked")
-    private Map getAllProperties(LocationRegistry registry, Map<?,?> properties) {
-        Map<Object,Object> allProperties = Maps.newHashMap();
+    private Map<String,Object> getAllProperties(LocationRegistry registry, Map properties) {
+        Map<String,Object> allProperties = MutableMap.of();
         if (registry!=null) allProperties.putAll(registry.getProperties());
         allProperties.putAll(properties);
         return allProperties;

http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/f755c25d/rest/rest-resources/src/main/java/org/apache/brooklyn/rest/resources/ApplicationResource.java
----------------------------------------------------------------------
diff --git a/rest/rest-resources/src/main/java/org/apache/brooklyn/rest/resources/ApplicationResource.java b/rest/rest-resources/src/main/java/org/apache/brooklyn/rest/resources/ApplicationResource.java
index e3c23f0..5fdbc95 100644
--- a/rest/rest-resources/src/main/java/org/apache/brooklyn/rest/resources/ApplicationResource.java
+++ b/rest/rest-resources/src/main/java/org/apache/brooklyn/rest/resources/ApplicationResource.java
@@ -443,7 +443,7 @@ public class ApplicationResource extends AbstractBrooklynRestResource implements
     private void checkLocationsAreValid(ApplicationSpec applicationSpec) {
         for (String locationId : applicationSpec.getLocations()) {
             locationId = BrooklynRestResourceUtils.fixLocation(locationId);
-            if (!brooklyn().getLocationRegistry().canMaybeResolve(locationId) && brooklyn().getLocationRegistry().getDefinedLocationById(locationId)==null) {
+            if (brooklyn().getLocationRegistry().getLocationSpec(locationId).isAbsent() && brooklyn().getLocationRegistry().getDefinedLocationById(locationId)==null) {
                 throw WebResourceUtils.notFound("Undefined location '%s'", locationId);
             }
         }

http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/f755c25d/rest/rest-resources/src/main/java/org/apache/brooklyn/rest/transform/LocationTransformer.java
----------------------------------------------------------------------
diff --git a/rest/rest-resources/src/main/java/org/apache/brooklyn/rest/transform/LocationTransformer.java b/rest/rest-resources/src/main/java/org/apache/brooklyn/rest/transform/LocationTransformer.java
index db3c4f1..ad85ce2 100644
--- a/rest/rest-resources/src/main/java/org/apache/brooklyn/rest/transform/LocationTransformer.java
+++ b/rest/rest-resources/src/main/java/org/apache/brooklyn/rest/transform/LocationTransformer.java
@@ -18,33 +18,35 @@
  */
 package org.apache.brooklyn.rest.transform;
 
+import static org.apache.brooklyn.rest.util.WebResourceUtils.serviceUriBuilder;
+
 import java.net.URI;
 import java.util.Map;
 
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
+import javax.ws.rs.core.UriBuilder;
+
 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.core.config.Sanitizer;
 import org.apache.brooklyn.core.location.BasicLocationDefinition;
 import org.apache.brooklyn.core.location.LocationConfigKeys;
 import org.apache.brooklyn.core.location.internal.LocationInternal;
+import org.apache.brooklyn.rest.api.LocationApi;
 import org.apache.brooklyn.rest.domain.LocationSummary;
 import org.apache.brooklyn.rest.util.WebResourceUtils;
 import org.apache.brooklyn.util.collections.MutableMap;
 import org.apache.brooklyn.util.core.config.ConfigBag;
 import org.apache.brooklyn.util.guava.Maybe;
 import org.apache.brooklyn.util.text.Strings;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 import com.google.common.collect.ImmutableMap;
-import javax.ws.rs.core.UriBuilder;
-import org.apache.brooklyn.rest.api.LocationApi;
-import static org.apache.brooklyn.rest.util.WebResourceUtils.serviceUriBuilder;
 
 public class LocationTransformer {
 
-    @SuppressWarnings("unused")
     private static final Logger log = LoggerFactory.getLogger(LocationTransformer.LocationDetailLevel.class);
     
     public static enum LocationDetailLevel { NONE, LOCAL_EXCLUDING_SECRET, FULL_EXCLUDING_SECRET, FULL_INCLUDING_SECRET }
@@ -54,39 +56,71 @@ public class LocationTransformer {
     public static LocationSummary newInstance(String id, org.apache.brooklyn.rest.domain.LocationSpec locationSpec, UriBuilder ub) {
         return newInstance(null, id, locationSpec, LocationDetailLevel.LOCAL_EXCLUDING_SECRET, ub);
     }
-    @SuppressWarnings("deprecation")
-    public static LocationSummary newInstance(ManagementContext mgmt, String id, org.apache.brooklyn.rest.domain.LocationSpec locationSpec, LocationDetailLevel level, UriBuilder ub) {
-        // TODO: Remove null checks on mgmt when newInstance(String, LocationSpec) is deleted
-        Map<String, ?> config = locationSpec.getConfig();
-        if (mgmt != null && (level==LocationDetailLevel.FULL_EXCLUDING_SECRET || level==LocationDetailLevel.FULL_INCLUDING_SECRET)) {
-            LocationDefinition ld = new BasicLocationDefinition(id, locationSpec.getName(), locationSpec.getSpec(), locationSpec.getConfig());
-            Location ll = mgmt.getLocationRegistry().resolve(ld, false, null).orNull();
-            if (ll!=null) config = ((LocationInternal)ll).config().getBag().getAllConfig();
+    
+    private static LocationSummary newInstance(ManagementContext mgmt, 
+            LocationSpec<? extends Location> spec, ConfigBag explicitConfig, 
+            String optionalExplicitId, String name, String specString, 
+            LocationDetailLevel level, UriBuilder ub) {
+        // mgmt not actually needed
+        Map<String, Object> config = MutableMap.copyOf(explicitConfig==null ? null : explicitConfig.getAllConfig());
+        if (spec!=null && (level==LocationDetailLevel.FULL_EXCLUDING_SECRET || level==LocationDetailLevel.FULL_INCLUDING_SECRET)) {
+            // full takes from any resolved spec AND from explicit config
+            config = ConfigBag.newInstance(spec.getConfig()).putAll(config).getAllConfig();
         } else if (level==LocationDetailLevel.LOCAL_EXCLUDING_SECRET) {
-            // get displayName
-            if (!config.containsKey(LocationConfigKeys.DISPLAY_NAME.getName()) && mgmt!=null) {
-                LocationDefinition ld = new BasicLocationDefinition(id, locationSpec.getName(), locationSpec.getSpec(), locationSpec.getConfig());
-                Location ll = mgmt.getLocationRegistry().resolve(ld, false, null).orNull();
-                if (ll!=null) {
-                    Map<String, Object> configExtra = ((LocationInternal)ll).config().getBag().getAllConfig();
-                    if (configExtra.containsKey(LocationConfigKeys.DISPLAY_NAME.getName())) {
-                        ConfigBag configNew = ConfigBag.newInstance(config);
-                        configNew.configure(LocationConfigKeys.DISPLAY_NAME, (String)configExtra.get(LocationConfigKeys.DISPLAY_NAME.getName()));
-                        config = configNew.getAllConfig();
-                    }
-                }
+            // in local mode, just make sure display name is set
+            if (spec!=null && !explicitConfig.containsKey(LocationConfigKeys.DISPLAY_NAME) && Strings.isNonBlank(spec.getDisplayName())) {
+                config.put(LocationConfigKeys.DISPLAY_NAME.getName(), spec.getDisplayName());
             }
         }
 
+        String id = Strings.isNonBlank(optionalExplicitId) ? optionalExplicitId : spec!=null && Strings.isNonBlank(spec.getCatalogItemId()) ? spec.getCatalogItemId() : null;
         URI selfUri = serviceUriBuilder(ub, LocationApi.class, "get").build(id);
         return new LocationSummary(
                 id,
-                locationSpec.getName(),
-                locationSpec.getSpec(),
+                Strings.isNonBlank(name) ? name : spec!=null ? spec.getDisplayName() : null,
+                Strings.isNonBlank(specString) ? specString : spec!=null ? spec.getCatalogItemId() : null,
                 null,
                 copyConfig(config, level),
                 ImmutableMap.of("self", selfUri));
     }
+    
+    // XXX big commented out swathes should be removed when this is confirmed working
+    
+    @SuppressWarnings("deprecation") 
+    public static LocationSummary newInstance(ManagementContext mgmt, String id, org.apache.brooklyn.rest.domain.LocationSpec locationSpec, LocationDetailLevel level, UriBuilder ub) {
+        LocationDefinition ld = new BasicLocationDefinition(id, locationSpec.getName(), locationSpec.getSpec(), locationSpec.getConfig());
+        return newInstance(mgmt, ld, level, ub);
+//        
+//        Map<String, ?> config = locationSpec.getConfig();
+//        if (mgmt != null && (level==LocationDetailLevel.FULL_EXCLUDING_SECRET || level==LocationDetailLevel.FULL_INCLUDING_SECRET)) {
+//            
+//            Location ll = mgmt.getLocationRegistry().resolve(ld, false, null).orNull();
+//            if (ll!=null) config = ((LocationInternal)ll).config().getBag().getAllConfig();
+//        } else if (level==LocationDetailLevel.LOCAL_EXCLUDING_SECRET) {
+//            // get displayName
+//            if (!config.containsKey(LocationConfigKeys.DISPLAY_NAME.getName()) && mgmt!=null) {
+//                LocationDefinition ld = new BasicLocationDefinition(id, locationSpec.getName(), locationSpec.getSpec(), locationSpec.getConfig());
+//                Location ll = mgmt.getLocationRegistry().resolve(ld, false, null).orNull();
+//                if (ll!=null) {
+//                    Map<String, Object> configExtra = ((LocationInternal)ll).config().getBag().getAllConfig();
+//                    if (configExtra.containsKey(LocationConfigKeys.DISPLAY_NAME.getName())) {
+//                        ConfigBag configNew = ConfigBag.newInstance(config);
+//                        configNew.configure(LocationConfigKeys.DISPLAY_NAME, (String)configExtra.get(LocationConfigKeys.DISPLAY_NAME.getName()));
+//                        config = configNew.getAllConfig();
+//                    }
+//                }
+//            }
+//        }
+//
+//        URI selfUri = serviceUriBuilder(ub, LocationApi.class, "get").build(id);
+//        return new LocationSummary(
+//                id,
+//                locationSpec.getName(),
+//                locationSpec.getSpec(),
+//                null,
+//                copyConfig(config, level),
+//                ImmutableMap.of("self", selfUri));
+    }
 
     /** @deprecated since 0.7.0 use method taking management context and detail specifier */
     @Deprecated
@@ -94,35 +128,36 @@ public class LocationTransformer {
         return newInstance(null, l, LocationDetailLevel.LOCAL_EXCLUDING_SECRET, ub);
     }
 
-    public static LocationSummary newInstance(ManagementContext mgmt, LocationDefinition l, LocationDetailLevel level, UriBuilder ub) {
-        // TODO: Can remove null checks on mgmt when newInstance(LocationDefinition) is deleted
-        Map<String, Object> config = l.getConfig();
-        if (mgmt != null && (level==LocationDetailLevel.FULL_EXCLUDING_SECRET || level==LocationDetailLevel.FULL_INCLUDING_SECRET)) {
-            Location ll = mgmt.getLocationRegistry().resolve(l, false, null).orNull();
-            if (ll!=null) config = ((LocationInternal)ll).config().getBag().getAllConfig();
-        } else if (level==LocationDetailLevel.LOCAL_EXCLUDING_SECRET) {
-            // get displayName
-            if (mgmt != null && !config.containsKey(LocationConfigKeys.DISPLAY_NAME.getName())) {
-                Location ll = mgmt.getLocationRegistry().resolve(l, false, null).orNull();
-                if (ll!=null) {
-                    Map<String, Object> configExtra = ((LocationInternal)ll).config().getBag().getAllConfig();
-                    if (configExtra.containsKey(LocationConfigKeys.DISPLAY_NAME.getName())) {
-                        ConfigBag configNew = ConfigBag.newInstance(config);
-                        configNew.configure(LocationConfigKeys.DISPLAY_NAME, (String)configExtra.get(LocationConfigKeys.DISPLAY_NAME.getName()));
-                        config = configNew.getAllConfig();
-                    }
-                }
-            }
-        }
-
-        URI selfUri = serviceUriBuilder(ub, LocationApi.class, "get").build(l.getId());
-        return new LocationSummary(
-                l.getId(),
-                l.getName(),
-                l.getSpec(),
-                null,
-                copyConfig(config, level),
-                ImmutableMap.of("self", selfUri));
+    public static LocationSummary newInstance(ManagementContext mgmt, LocationDefinition ld, LocationDetailLevel level, UriBuilder ub) {
+        return newInstance(mgmt, mgmt.getLocationRegistry().getLocationSpec(ld).orNull(), ConfigBag.newInstance(ld.getConfig()),
+            ld.getId(), ld.getName(), ld.getSpec(), level, ub);
+//        Map<String, Object> config = ld.getConfig();
+//        
+//        if (mgmt != null && (level==LocationDetailLevel.FULL_EXCLUDING_SECRET || level==LocationDetailLevel.FULL_INCLUDING_SECRET)) {
+//            if (ll.isPresent()) config = ConfigBag.newInstance(ll.get().getConfig()).getAllConfig();
+//        } else if (level==LocationDetailLevel.LOCAL_EXCLUDING_SECRET) {
+//            // get any displayName
+//            if (mgmt != null && !config.containsKey(LocationConfigKeys.DISPLAY_NAME.getName())) {
+//                Maybe<LocationSpec<?>> ll = mgmt.getLocationRegistry().getLocationSpec(ld);
+//                if (ll.isPresent()) {
+//                    ConfigBag configNew = ConfigBag.newInstance(ll.get().getConfig());
+//                    // XXX useless? 
+//                    if (configNew.containsKey(LocationConfigKeys.DISPLAY_NAME.getName())) {
+//                        configNew.configure(LocationConfigKeys.DISPLAY_NAME, (String)configNew.get(LocationConfigKeys.DISPLAY_NAME));
+//                        config = configNew.getAllConfig();
+//                    }
+//                }
+//            }
+//        }
+//
+//        URI selfUri = serviceUriBuilder(ub, LocationApi.class, "get").build(ld.getId());
+//        return new LocationSummary(
+//                ld.getId(),
+//                ld.getName(),
+//                ld.getSpec(),
+//                null,
+//                copyConfig(config, level),
+//                ImmutableMap.of("self", selfUri));
     }
 
     private static Map<String, ?> copyConfig(Map<String,?> entries, LocationDetailLevel level) {
@@ -137,6 +172,7 @@ public class LocationTransformer {
         return builder.build();
     }
 
+    private static boolean LEGACY_SPEC_WARNING = false;
     public static LocationSummary newInstance(ManagementContext mgmt, Location l, LocationDetailLevel level, UriBuilder ub) {
         String spec = null;
         String specId = null;
@@ -165,6 +201,11 @@ public class LocationTransformer {
         }
         if (specId==null && spec!=null) {
             // fall back to attempting to lookup it
+            // TODO remove this block unless we get this warning
+            if (LEGACY_SPEC_WARNING==false) {
+                log.warn("Legacy spec lookup required for rest summary of "+l);
+                LEGACY_SPEC_WARNING = true;
+            }
             Location ll = mgmt.getLocationRegistry().resolve(spec, false, null).orNull();
             if (ll!=null) specId = ll.getId();
         }

http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/f755c25d/rest/rest-resources/src/main/java/org/apache/brooklyn/rest/util/BrooklynRestResourceUtils.java
----------------------------------------------------------------------
diff --git a/rest/rest-resources/src/main/java/org/apache/brooklyn/rest/util/BrooklynRestResourceUtils.java b/rest/rest-resources/src/main/java/org/apache/brooklyn/rest/util/BrooklynRestResourceUtils.java
index 3f837a1..f552ded 100644
--- a/rest/rest-resources/src/main/java/org/apache/brooklyn/rest/util/BrooklynRestResourceUtils.java
+++ b/rest/rest-resources/src/main/java/org/apache/brooklyn/rest/util/BrooklynRestResourceUtils.java
@@ -403,7 +403,8 @@ public class BrooklynRestResourceUtils {
             @Override
             public Location apply(String id) {
                 id = fixLocation(id);
-                return getLocationRegistry().resolve(id);
+                // XXX
+                return getLocationRegistry().getLocationManaged(id);
             }
         };
 

http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/f755c25d/server-cli/src/main/java/org/apache/brooklyn/cli/CloudExplorer.java
----------------------------------------------------------------------
diff --git a/server-cli/src/main/java/org/apache/brooklyn/cli/CloudExplorer.java b/server-cli/src/main/java/org/apache/brooklyn/cli/CloudExplorer.java
index d9f0a33..fa464f8 100644
--- a/server-cli/src/main/java/org/apache/brooklyn/cli/CloudExplorer.java
+++ b/server-cli/src/main/java/org/apache/brooklyn/cli/CloudExplorer.java
@@ -86,13 +86,13 @@ public class CloudExplorer {
                 if (location != null && allLocations) {
                     throw new FatalConfigurationRuntimeException("Must not specify --location and --all-locations");
                 } else if (location != null) {
-                    JcloudsLocation loc = (JcloudsLocation) mgmt.getLocationRegistry().resolve(location);
+                    JcloudsLocation loc = (JcloudsLocation) mgmt.getLocationRegistry().getLocationManaged(location);
                     locs.add(loc);
                 } else if (allLocations) {
                     // Find all named locations that point at different target clouds
                     Map<String, LocationDefinition> definedLocations = mgmt.getLocationRegistry().getDefinedLocations();
                     for (LocationDefinition locationDef : definedLocations.values()) {
-                        Location loc = mgmt.getLocationRegistry().resolve(locationDef);
+                        Location loc = mgmt.getLocationManager().createLocation( mgmt.getLocationRegistry().getLocationSpec(locationDef).get() );
                         if (loc instanceof JcloudsLocation) {
                             boolean found = false;
                             for (JcloudsLocation existing : locs) {

http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/f755c25d/software/base/src/main/java/org/apache/brooklyn/entity/machine/pool/ServerPoolImpl.java
----------------------------------------------------------------------
diff --git a/software/base/src/main/java/org/apache/brooklyn/entity/machine/pool/ServerPoolImpl.java b/software/base/src/main/java/org/apache/brooklyn/entity/machine/pool/ServerPoolImpl.java
index 6b0792d..513ee29 100644
--- a/software/base/src/main/java/org/apache/brooklyn/entity/machine/pool/ServerPoolImpl.java
+++ b/software/base/src/main/java/org/apache/brooklyn/entity/machine/pool/ServerPoolImpl.java
@@ -41,6 +41,8 @@ import org.apache.brooklyn.core.entity.trait.Startable;
 import org.apache.brooklyn.core.location.BasicLocationDefinition;
 import org.apache.brooklyn.core.location.Machines;
 import org.apache.brooklyn.core.location.dynamic.DynamicLocation;
+import org.apache.brooklyn.core.location.internal.LocationInternal;
+import org.apache.brooklyn.core.mgmt.internal.LocalLocationManager;
 import org.apache.brooklyn.core.sensor.Sensors;
 import org.apache.brooklyn.entity.group.AbstractMembershipTrackingPolicy;
 import org.apache.brooklyn.entity.group.DynamicClusterImpl;
@@ -172,7 +174,7 @@ public class ServerPoolImpl extends DynamicClusterImpl implements ServerPool {
         String locationSpec = String.format(ServerPoolLocationResolver.POOL_SPEC, getId()) + String.format(":(name=\"%s\")", locationName);
         LocationDefinition definition = new BasicLocationDefinition(locationName, locationSpec, flags);
         getManagementContext().getLocationRegistry().updateDefinedLocation(definition);
-        Location location = getManagementContext().getLocationRegistry().resolve(definition);
+        Location location = getManagementContext().getLocationManager().createLocation( getManagementContext().getLocationRegistry().getLocationSpec(definition).get() );
         LOG.info("Resolved and registered dynamic location {}: {}", locationName, location);
 
         sensors().set(LOCATION_SPEC, locationSpec);
@@ -252,7 +254,10 @@ public class ServerPoolImpl extends DynamicClusterImpl implements ServerPool {
 
     @Override
     public Collection<Entity> addExistingMachinesFromSpec(String spec) {
-        Location location = getManagementContext().getLocationRegistry().resolve(spec, true, null).orNull();
+        Location location = getManagementContext().getLocationManager().createLocation( 
+            getManagementContext().getLocationRegistry().getLocationSpec(spec).get()
+                .configure(LocalLocationManager.CREATE_UNMANAGED, true) );
+        
         List<Entity> additions = Lists.newLinkedList();
         if (location == null) {
             LOG.warn("Spec was unresolvable: {}", spec);

http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/f755c25d/software/base/src/main/java/org/apache/brooklyn/entity/machine/pool/ServerPoolLocationResolver.java
----------------------------------------------------------------------
diff --git a/software/base/src/main/java/org/apache/brooklyn/entity/machine/pool/ServerPoolLocationResolver.java b/software/base/src/main/java/org/apache/brooklyn/entity/machine/pool/ServerPoolLocationResolver.java
index d1e4909..54f232b 100644
--- a/software/base/src/main/java/org/apache/brooklyn/entity/machine/pool/ServerPoolLocationResolver.java
+++ b/software/base/src/main/java/org/apache/brooklyn/entity/machine/pool/ServerPoolLocationResolver.java
@@ -27,15 +27,18 @@ import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 
 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.LocationResolver;
 import org.apache.brooklyn.api.location.LocationSpec;
-import org.apache.brooklyn.api.location.LocationResolver.EnableableLocationResolver;
 import org.apache.brooklyn.api.mgmt.ManagementContext;
 import org.apache.brooklyn.core.location.BasicLocationRegistry;
+import org.apache.brooklyn.core.location.LocationConfigUtils;
 import org.apache.brooklyn.core.location.LocationPropertiesFromBrooklynProperties;
 import org.apache.brooklyn.core.location.dynamic.DynamicLocation;
 import org.apache.brooklyn.core.location.internal.LocationInternal;
+import org.apache.brooklyn.util.collections.MutableMap;
+import org.apache.brooklyn.util.text.KeyValueParser;
+import org.apache.brooklyn.util.text.Strings;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -43,11 +46,7 @@ import com.google.common.base.Joiner;
 import com.google.common.collect.ImmutableSet;
 import com.google.common.collect.Sets;
 
-import org.apache.brooklyn.util.collections.MutableMap;
-import org.apache.brooklyn.util.text.KeyValueParser;
-import org.apache.brooklyn.util.text.Strings;
-
-public class ServerPoolLocationResolver implements EnableableLocationResolver {
+public class ServerPoolLocationResolver implements LocationResolver {
 
     private static final Logger LOG = LoggerFactory.getLogger(ServerPoolLocationResolver.class);
     private static final String PREFIX = "pool";
@@ -62,7 +61,7 @@ public class ServerPoolLocationResolver implements EnableableLocationResolver {
 
     @Override
     public boolean isEnabled() {
-        return true;
+        return LocationConfigUtils.isResolverPrefixEnabled(managementContext, getPrefix());
     }
 
     @Override
@@ -82,7 +81,7 @@ public class ServerPoolLocationResolver implements EnableableLocationResolver {
 
     @SuppressWarnings({ "rawtypes", "unchecked" })
     @Override
-    public Location newLocationFromString(Map locationFlags, String spec, LocationRegistry registry) {
+    public LocationSpec newLocationSpecFromString(String spec, Map locationFlags, LocationRegistry registry) {
         if (LOG.isDebugEnabled()) {
             LOG.debug("Resolving location '" + spec + "' with flags " + Joiner.on(",").withKeyValueSeparator("=").join(locationFlags));
         }
@@ -127,12 +126,11 @@ public class ServerPoolLocationResolver implements EnableableLocationResolver {
         final String locationName = namePart != null ? namePart : "serverpool-" + poolId;
 
         Entity pool = managementContext.getEntityManager().getEntity(poolId);
-        LocationSpec<ServerPoolLocation> locationSpec = LocationSpec.create(ServerPoolLocation.class)
+        return LocationSpec.create(ServerPoolLocation.class)
                 .configure(flags)
                 .configure(DynamicLocation.OWNER, pool)
                 .configure(LocationInternal.NAMED_SPEC_NAME, locationName)
                 .displayName(displayName);
-        return managementContext.getLocationManager().createLocation(locationSpec);
     }
 
 }

http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/f755c25d/software/base/src/main/java/org/apache/brooklyn/entity/software/base/lifecycle/MachineLifecycleEffectorTasks.java
----------------------------------------------------------------------
diff --git a/software/base/src/main/java/org/apache/brooklyn/entity/software/base/lifecycle/MachineLifecycleEffectorTasks.java b/software/base/src/main/java/org/apache/brooklyn/entity/software/base/lifecycle/MachineLifecycleEffectorTasks.java
index 7e755a5..4fb403d 100644
--- a/software/base/src/main/java/org/apache/brooklyn/entity/software/base/lifecycle/MachineLifecycleEffectorTasks.java
+++ b/software/base/src/main/java/org/apache/brooklyn/entity/software/base/lifecycle/MachineLifecycleEffectorTasks.java
@@ -184,7 +184,7 @@ public abstract class MachineLifecycleEffectorTasks {
                 Collection<? extends Location> locations  = null;
 
                 Object locationsRaw = parameters.getStringKey(LOCATIONS.getName());
-                locations = Locations.coerceToCollection(entity().getManagementContext(), locationsRaw);
+                locations = Locations.coerceToCollectionOfLocationsManaged(entity().getManagementContext(), locationsRaw);
 
                 if (locations==null) {
                     // null/empty will mean to inherit from parent
@@ -204,7 +204,7 @@ public abstract class MachineLifecycleEffectorTasks {
             Collection<? extends Location> locations = null;
 
             Object locationsRaw = parameters.getStringKey(LOCATIONS.getName());
-            locations = Locations.coerceToCollection(entity().getManagementContext(), locationsRaw);
+            locations = Locations.coerceToCollectionOfLocationsManaged(entity().getManagementContext(), locationsRaw);
 
             if (locations == null) {
                 // null/empty will mean to inherit from parent

http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/f755c25d/software/winrm/src/main/java/org/apache/brooklyn/location/winrm/WinRmMachineLocation.java
----------------------------------------------------------------------
diff --git a/software/winrm/src/main/java/org/apache/brooklyn/location/winrm/WinRmMachineLocation.java b/software/winrm/src/main/java/org/apache/brooklyn/location/winrm/WinRmMachineLocation.java
index 394facb..e014e03 100644
--- a/software/winrm/src/main/java/org/apache/brooklyn/location/winrm/WinRmMachineLocation.java
+++ b/software/winrm/src/main/java/org/apache/brooklyn/location/winrm/WinRmMachineLocation.java
@@ -172,7 +172,7 @@ public class WinRmMachineLocation extends AbstractLocation implements MachineLoc
         // Register any pre-existing port-mappings with the PortForwardManager
         Map<Integer, String> tcpPortMappings = getConfig(TCP_PORT_MAPPINGS);
         if (tcpPortMappings != null) {
-            PortForwardManager pfm = (PortForwardManager) getManagementContext().getLocationRegistry().resolve("portForwardManager(scope=global)");
+            PortForwardManager pfm = (PortForwardManager) getManagementContext().getLocationRegistry().getLocationManaged("portForwardManager(scope=global)");
             for (Map.Entry<Integer, String> entry : tcpPortMappings.entrySet()) {
                 int targetPort = entry.getKey();
                 HostAndPort publicEndpoint = HostAndPort.fromString(entry.getValue());