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/30 15:53:07 UTC

[2/2] brooklyn-server git commit: MultiLocation resolver: use config list of LocationSpec

MultiLocation resolver: use config list of LocationSpec

Similar to ByonResolver, use a separate config key for LocationSpecs
of child locations.

Restores backwards compatibility, by re-adding:
MultiLocation.getSubLocations()


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

Branch: refs/heads/0.9.0
Commit: 2bc65e34e4b0d72e4f4a5f9759a4092d72d822d0
Parents: 9d73953
Author: Aled Sage <al...@gmail.com>
Authored: Wed Mar 30 13:52:03 2016 +0100
Committer: Alex Heneveld <al...@cloudsoftcorp.com>
Committed: Wed Mar 30 14:52:55 2016 +0100

----------------------------------------------------------------------
 .../camp/brooklyn/LocationsYamlTest.java        |  2 +-
 .../brooklyn/location/multi/MultiLocation.java  | 79 +++++++++++---------
 .../location/multi/MultiLocationResolver.java   |  2 +-
 .../multi/MultiLocationResolverTest.java        | 19 ++++-
 4 files changed, 63 insertions(+), 39 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/2bc65e34/camp/camp-brooklyn/src/test/java/org/apache/brooklyn/camp/brooklyn/LocationsYamlTest.java
----------------------------------------------------------------------
diff --git a/camp/camp-brooklyn/src/test/java/org/apache/brooklyn/camp/brooklyn/LocationsYamlTest.java b/camp/camp-brooklyn/src/test/java/org/apache/brooklyn/camp/brooklyn/LocationsYamlTest.java
index 5566e1d..f1efd33 100644
--- a/camp/camp-brooklyn/src/test/java/org/apache/brooklyn/camp/brooklyn/LocationsYamlTest.java
+++ b/camp/camp-brooklyn/src/test/java/org/apache/brooklyn/camp/brooklyn/LocationsYamlTest.java
@@ -263,7 +263,7 @@ public class LocationsYamlTest extends AbstractYamlTest {
         Entity app = createStartWaitAndLogApplication(new StringReader(yaml));
         Entity child = Iterables.getOnlyElement(app.getChildren());
         MultiLocation<?> loc = (MultiLocation<?>) Iterables.getOnlyElement(Entities.getAllInheritedLocations(child));
-        Assert.assertEquals(loc.getSubLocationsAsLocations().size(), 2);
+        Assert.assertEquals(loc.getSubLocations().size(), 2);
         
         assertUserAddress((SshMachineLocation)loc.obtain(), "root", "127.0.0.1");
         assertUserAddress((SshMachineLocation)loc.obtain(), "root", "127.0.0.2");

http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/2bc65e34/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 afd3212..415d509 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
@@ -39,7 +39,6 @@ import org.apache.brooklyn.core.location.cloud.AbstractAvailabilityZoneExtension
 import org.apache.brooklyn.core.location.cloud.AvailabilityZoneExtension;
 import org.apache.brooklyn.util.collections.MutableList;
 import org.apache.brooklyn.util.collections.MutableMap;
-import org.apache.brooklyn.util.core.flags.SetFromFlag;
 import org.apache.brooklyn.util.exceptions.CompoundRuntimeException;
 import org.apache.brooklyn.util.exceptions.Exceptions;
 import org.apache.brooklyn.util.text.Strings;
@@ -56,18 +55,52 @@ import com.google.common.reflect.TypeToken;
  * is used, it may stripe across each of the locations.  See notes at {@link AvailabilityZoneExtension}. */
 public class MultiLocation<T extends MachineLocation> extends AbstractLocation implements MachineProvisioningLocation<T> {
 
+    /**
+     * The subLocationSpecs allows {@link MultiLocationResolver} to work with just LocationSpecs, rather than 
+     * having to instantiate the sub-locations immediately (which would be bad, because the caller
+     * might not use the spec and thus might not unmanage the sub-location instances).
+     *
+     * We clear the subLocationSpecs in init, so they will never be persisted. This will help with
+     * backwards compatibility if we change how this is done.
+     *
+     * By the end of init(), the {@link #SUB_LOCATIONS} will contain the full list of locations; it 
+     * will never contain a {@link LocationSpec}.
+     */
+    @Beta
     @SuppressWarnings("serial")
-    @SetFromFlag("subLocations")
-    public static final ConfigKey<List<?>> SUB_LOCATIONS = ConfigKeys.newConfigKey(
-            new TypeToken<List<?>>() {},
-            "subLocations", 
-            "The sub-machines Location instances or LocationSpecs that this location can delegate to");
+    public static final ConfigKey<List<LocationSpec<?>>> SUB_LOCATION_SPECS = ConfigKeys.newConfigKey(
+            new TypeToken<List<LocationSpec<?>>>() {},
+            "subLocationSpecs", 
+            "Specs of sub-locations that should be immediatly instantiated on init");
     
+    @SuppressWarnings("serial")
+    public static final ConfigKey<List<MachineProvisioningLocation<?>>> SUB_LOCATIONS = ConfigKeys.newConfigKey(
+            new TypeToken<List<MachineProvisioningLocation<?>>>() {},
+            "subLocations", 
+            "The sub-locations that this location can delegate to");
+
     @Override
     public void init() {
         super.init();
-        List<MachineProvisioningLocation<?>> subLocations = getSubLocationsAsLocations();
-        AvailabilityZoneExtension azExtension = new AvailabilityZoneExtensionImpl(getManagementContext(), subLocations);
+        
+        List<MachineProvisioningLocation<?>> subLocs = MutableList.copyOf(getConfig(SUB_LOCATIONS));
+        
+        List<LocationSpec<?>> subLocSpecs = getConfig(SUB_LOCATION_SPECS);
+        if (subLocSpecs != null) {
+            for (LocationSpec<?> spec : subLocSpecs) {
+                if (spec.getParent() == null) {
+                    // use a copy with us set as parent
+                    spec = LocationSpec.create(spec).parent(this);
+                }
+                MachineProvisioningLocation<?> subLoc = (MachineProvisioningLocation<?>) getManagementContext().getLocationManager().createLocation(spec);
+                subLocs.add(subLoc);
+            }
+        }
+        checkState(subLocs.size() >= 1, "sub-locations must not be empty");
+        config().set(SUB_LOCATIONS, subLocs);
+        config().set(SUB_LOCATION_SPECS, (List<LocationSpec<?>>) null);
+
+        AvailabilityZoneExtension azExtension = new AvailabilityZoneExtensionImpl(getManagementContext(), subLocs);
         addExtension(AvailabilityZoneExtension.class, azExtension);
     }
 
@@ -81,7 +114,7 @@ public class MultiLocation<T extends MachineLocation> extends AbstractLocation i
     @SuppressWarnings("unchecked")
     @Override
     public T obtain(Map<?, ?> flags) throws NoMachinesAvailableException {
-        List<MachineProvisioningLocation<?>> sublocsList = getSubLocationsAsLocations();
+        List<MachineProvisioningLocation<?>> sublocsList = getSubLocations();
         Iterator<MachineProvisioningLocation<?>> sublocs = sublocsList.iterator();
         List<NoMachinesAvailableException> errors = MutableList.of();
         while (sublocs.hasNext()) {
@@ -109,33 +142,9 @@ public class MultiLocation<T extends MachineLocation> extends AbstractLocation i
             " configured here: "+msg, wrapped);
     }
 
-    @Beta
-    public List<?> getSubLocationsAsSpecsOrInstances() {
+    public List<MachineProvisioningLocation<?>> getSubLocations() {
         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
@@ -160,7 +169,7 @@ public class MultiLocation<T extends MachineLocation> extends AbstractLocation i
 
     @SuppressWarnings("unchecked")
     protected MachineProvisioningLocation<T> firstSubLoc() {
-        return (MachineProvisioningLocation<T>) Iterables.get(getSubLocationsAsLocations(), 0);
+        return (MachineProvisioningLocation<T>) Iterables.get(getSubLocations(), 0);
     }
 
     protected <K> K getRequiredConfig(ConfigKey<K> key) {

http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/2bc65e34/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 022b7e2..544d3ed 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
@@ -122,7 +122,7 @@ public class MultiLocationResolver implements LocationResolver {
         }
         LocationSpec<?> result = LocationSpec.create(MultiLocation.class)
             .configure(flags)
-            .configure(MultiLocation.SUB_LOCATIONS.getName(), targets)
+            .configure(MultiLocation.SUB_LOCATION_SPECS.getName(), targets)
             .configure(LocationConfigUtils.finalAndOriginalSpecs(spec, locationFlags, globalProperties, namedLocation));
 
         return result;

http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/2bc65e34/core/src/test/java/org/apache/brooklyn/location/multi/MultiLocationResolverTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/location/multi/MultiLocationResolverTest.java b/core/src/test/java/org/apache/brooklyn/location/multi/MultiLocationResolverTest.java
index ef13015b..7dd367b 100644
--- a/core/src/test/java/org/apache/brooklyn/location/multi/MultiLocationResolverTest.java
+++ b/core/src/test/java/org/apache/brooklyn/location/multi/MultiLocationResolverTest.java
@@ -24,6 +24,7 @@ import static org.testng.Assert.assertTrue;
 import static org.testng.Assert.fail;
 
 import java.net.InetAddress;
+import java.util.Collection;
 import java.util.Collections;
 import java.util.Iterator;
 import java.util.List;
@@ -32,6 +33,7 @@ import java.util.NoSuchElementException;
 import javax.annotation.Nullable;
 
 import org.apache.brooklyn.api.location.Location;
+import org.apache.brooklyn.api.location.LocationSpec;
 import org.apache.brooklyn.api.location.MachineLocation;
 import org.apache.brooklyn.api.location.MachineProvisioningLocation;
 import org.apache.brooklyn.api.location.NoMachinesAvailableException;
@@ -145,7 +147,7 @@ public class MultiLocationResolverTest {
         Location l = managementContext.getLocationRegistry().getLocationManaged("multi", MutableMap.of("targets", 
             MutableList.of("localhost", MutableMap.of("byon", MutableMap.of("hosts", "127.0.0.127")))));
         MultiLocation<?> ml = (MultiLocation<?>)l;
-        Iterator<MachineProvisioningLocation<?>> ci = ml.getSubLocationsAsLocations().iterator();
+        Iterator<MachineProvisioningLocation<?>> ci = ml.getSubLocations().iterator();
         
         l = ci.next();
         Assert.assertTrue(l instanceof LocalhostMachineProvisioningLocation, "Expected localhost, got "+l);
@@ -158,6 +160,14 @@ public class MultiLocationResolverTest {
         Assert.assertFalse(ci.hasNext());
     }
 
+    @Test
+    public void testLocationSpecDoesNotCreateMachines() throws Exception {
+        Collection<Location> before = managementContext.getLocationManager().getLocations();
+        getLocationSpec("multi:(name=myname,targets=localhost)");
+        
+        Collection<Location> after = managementContext.getLocationManager().getLocations();
+        assertEquals(after, before, "after="+after+"; before="+before);
+    }
 
     private void assertThrowsNoSuchElement(String val) {
         try {
@@ -181,7 +191,12 @@ public class MultiLocationResolverTest {
     private MultiLocation<SshMachineLocation> resolve(String val) {
         return (MultiLocation<SshMachineLocation>) managementContext.getLocationRegistry().getLocationManaged(val);
     }
-    
+
+    @SuppressWarnings("unchecked")
+    private LocationSpec<MultiLocation<SshMachineLocation>> getLocationSpec(String val) {
+        return (LocationSpec<MultiLocation<SshMachineLocation>>) managementContext.getLocationRegistry().getLocationSpec(val).get();
+    }
+
     @SuppressWarnings({ "rawtypes", "unchecked" })
     private void assertMultiLocation(MultiLocation<?> multiLoc, int expectedSize, List<? extends Predicate> expectedSubLocationPredicates) {
         AvailabilityZoneExtension zones = multiLoc.getExtension(AvailabilityZoneExtension.class);