Clocker pattern: change how LocationRegistry used Adds DynamicLocation.register() and .deregister()
Project: http://git-wip-us.apache.org/repos/asf/brooklyn-server/repo Commit: http://git-wip-us.apache.org/repos/asf/brooklyn-server/commit/453183f1 Tree: http://git-wip-us.apache.org/repos/asf/brooklyn-server/tree/453183f1 Diff: http://git-wip-us.apache.org/repos/asf/brooklyn-server/diff/453183f1 Branch: refs/heads/master Commit: 453183f1d89336ea793aab2edbe05c3b4070104b Parents: 292b4cf Author: Aled Sage <[email protected]> Authored: Fri Mar 11 20:50:45 2016 +0000 Committer: Aled Sage <[email protected]> Committed: Sat Mar 19 21:35:41 2016 +0000 ---------------------------------------------------------------------- .../core/location/dynamic/DynamicLocation.java | 12 ++ .../core/location/dynamic/LocationOwner.java | 4 - ...ClockerDynamicLocationPatternRebindTest.java | 35 ++++- .../ClockerDynamicLocationPatternTest.java | 22 ++- .../dynamic/clocker/StubContainerLocation.java | 13 +- .../core/location/dynamic/clocker/StubHost.java | 4 +- .../location/dynamic/clocker/StubHostImpl.java | 38 +++-- .../dynamic/clocker/StubHostLocation.java | 70 ++++++++- .../dynamic/clocker/StubInfrastructure.java | 7 +- .../dynamic/clocker/StubInfrastructureImpl.java | 66 +++----- .../clocker/StubInfrastructureLocation.java | 62 +++++++- .../location/dynamic/clocker/StubResolver.java | 157 +++++++------------ .../dynamic/clocker/StubResolverTest.java | 82 ++++++++++ 13 files changed, 384 insertions(+), 188 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/453183f1/core/src/main/java/org/apache/brooklyn/core/location/dynamic/DynamicLocation.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/org/apache/brooklyn/core/location/dynamic/DynamicLocation.java b/core/src/main/java/org/apache/brooklyn/core/location/dynamic/DynamicLocation.java index b04ebac..d961cdf 100644 --- a/core/src/main/java/org/apache/brooklyn/core/location/dynamic/DynamicLocation.java +++ b/core/src/main/java/org/apache/brooklyn/core/location/dynamic/DynamicLocation.java @@ -20,6 +20,8 @@ package org.apache.brooklyn.core.location.dynamic; import org.apache.brooklyn.api.entity.Entity; 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.config.ConfigKey; import org.apache.brooklyn.core.config.ConfigKeys; import org.apache.brooklyn.util.core.flags.SetFromFlag; @@ -47,4 +49,14 @@ public interface DynamicLocation<E extends Entity & LocationOwner<L, E>, L exten E getOwner(); + /** + * An opportunity to register this location (e.g. with the {@link LocationRegistry} or the + * catalog, so that it will be persisted). + */ + LocationDefinition register(); + + /** + * The complement of {@link #register()}, to deregister this location. + */ + void deregister(); } http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/453183f1/core/src/main/java/org/apache/brooklyn/core/location/dynamic/LocationOwner.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/org/apache/brooklyn/core/location/dynamic/LocationOwner.java b/core/src/main/java/org/apache/brooklyn/core/location/dynamic/LocationOwner.java index 718b97e..2c5a66c 100644 --- a/core/src/main/java/org/apache/brooklyn/core/location/dynamic/LocationOwner.java +++ b/core/src/main/java/org/apache/brooklyn/core/location/dynamic/LocationOwner.java @@ -22,7 +22,6 @@ import java.util.Map; import org.apache.brooklyn.api.entity.Entity; import org.apache.brooklyn.api.location.Location; -import org.apache.brooklyn.api.location.LocationDefinition; import org.apache.brooklyn.api.sensor.AttributeSensor; import org.apache.brooklyn.config.ConfigKey; import org.apache.brooklyn.core.config.ConfigKeys; @@ -71,9 +70,6 @@ public interface LocationOwner<L extends Location & DynamicLocation<E, L>, E ext AttributeSensor<Boolean> DYNAMIC_LOCATION_STATUS = Sensors.newBooleanSensor( "entity.dynamicLocation.status", "The status of the location owned by this entity"); - AttributeSensor<LocationDefinition> LOCATION_DEFINITION = Sensors.newSensor( - LocationDefinition.class, "entity.dynamicLocation.definition", "The location definition for the location owned by this entity"); - L getDynamicLocation(); L createLocation(Map<String, ?> flags); http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/453183f1/software/base/src/test/java/org/apache/brooklyn/core/location/dynamic/clocker/ClockerDynamicLocationPatternRebindTest.java ---------------------------------------------------------------------- diff --git a/software/base/src/test/java/org/apache/brooklyn/core/location/dynamic/clocker/ClockerDynamicLocationPatternRebindTest.java b/software/base/src/test/java/org/apache/brooklyn/core/location/dynamic/clocker/ClockerDynamicLocationPatternRebindTest.java index 361ee95..6ccd86c 100644 --- a/software/base/src/test/java/org/apache/brooklyn/core/location/dynamic/clocker/ClockerDynamicLocationPatternRebindTest.java +++ b/software/base/src/test/java/org/apache/brooklyn/core/location/dynamic/clocker/ClockerDynamicLocationPatternRebindTest.java @@ -29,6 +29,7 @@ import java.util.Map; 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.core.entity.BrooklynConfigKeys; import org.apache.brooklyn.core.entity.Entities; import org.apache.brooklyn.core.location.BasicLocationRegistry; import org.apache.brooklyn.core.location.Locations; @@ -41,6 +42,9 @@ import com.google.common.collect.ImmutableMap; import com.google.common.collect.Lists; import com.google.common.collect.Maps; +/** + * See explanation of what we're testing in {@link StubInfrastructure}. + */ public class ClockerDynamicLocationPatternRebindTest extends RebindTestFixtureWithApp { @Override @@ -59,9 +63,9 @@ public class ClockerDynamicLocationPatternRebindTest extends RebindTestFixtureWi return result; } - // To make this fail (with Clocker code as at 2016-03-11) requires several apps - there's a bug - // in rebind that only happens when there are several entities, so the order that they rebind - // is more interleaved. + // To make this fail previously (with Clocker code as at 2016-03-11) required several apps - + // there was a bug in rebind that only happened when there were several entities, so the order + // that they did the rebind was more interleaved. @Test public void testRebind() throws Exception { final int NUM_INFRAS = 10; @@ -70,26 +74,45 @@ public class ClockerDynamicLocationPatternRebindTest extends RebindTestFixtureWi // Maps from the infrastructure locSpec to the (potentially many) host locSpecs Map<String, List<String>> locSpecs = Maps.newLinkedHashMap(); + Map<String, List<String>> locNames = Maps.newLinkedHashMap(); for (int i = 0; i < NUM_INFRAS; i++) { + String infraLocName = "myname"+i; StubInfrastructure infra = mgmt().getEntityManager().createEntity(EntitySpec.create(StubInfrastructure.class) - .configure(StubInfrastructure.LOCATION_NAME, "myname"+i)); + .configure(StubInfrastructure.LOCATION_NAME, infraLocName) + .configure(BrooklynConfigKeys.SKIP_ON_BOX_BASE_DIR_RESOLUTION, true)); infra.start(ImmutableList.of(loc)); infra.getStubHostCluster().resize(HOST_CLUSTER_SIZE); assertEquals(infra.getStubHostCluster().getMembers().size(), HOST_CLUSTER_SIZE); String infraLocSpec = infra.sensors().get(StubInfrastructure.LOCATION_SPEC); List<String> hostLocSpecs = Lists.newArrayList(); + List<String> hostLocNames = Lists.newArrayList(); for (Entity host : infra.getStubHostCluster().getMembers()) { - hostLocSpecs.add(host.sensors().get(StubInfrastructure.LOCATION_SPEC)); + hostLocSpecs.add(host.sensors().get(StubHost.LOCATION_SPEC)); + hostLocNames.add(host.sensors().get(StubHost.LOCATION_NAME)); } locSpecs.put(infraLocSpec, hostLocSpecs); + locNames.put(infraLocName, hostLocNames); } assertEquals(locSpecs.size(), NUM_INFRAS); // in case the infrastructures all used the same loc name! + assertEquals(locNames.size(), NUM_INFRAS); // in case the infrastructures all used the same loc name! rebind(); - + + for (Map.Entry<String, List<String>> entry : locNames.entrySet()) { + String infraLocName = entry.getKey(); + List<String> hostLocName = entry.getValue(); + + StubInfrastructureLocation newInfraLoc = (StubInfrastructureLocation) mgmt().getLocationRegistry().resolve(infraLocName); + assertNotNull(newInfraLoc); + for (String hostLocSpec: hostLocName) { + StubHostLocation newHostLoc = (StubHostLocation) mgmt().getLocationRegistry().resolve(hostLocSpec); + assertNotNull(newHostLoc); + } + } + for (Map.Entry<String, List<String>> entry : locSpecs.entrySet()) { String infraLocSpec = entry.getKey(); List<String> hostLocSpecs = entry.getValue(); http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/453183f1/software/base/src/test/java/org/apache/brooklyn/core/location/dynamic/clocker/ClockerDynamicLocationPatternTest.java ---------------------------------------------------------------------- diff --git a/software/base/src/test/java/org/apache/brooklyn/core/location/dynamic/clocker/ClockerDynamicLocationPatternTest.java b/software/base/src/test/java/org/apache/brooklyn/core/location/dynamic/clocker/ClockerDynamicLocationPatternTest.java index 618c552..b67b11c 100644 --- a/software/base/src/test/java/org/apache/brooklyn/core/location/dynamic/clocker/ClockerDynamicLocationPatternTest.java +++ b/software/base/src/test/java/org/apache/brooklyn/core/location/dynamic/clocker/ClockerDynamicLocationPatternTest.java @@ -20,13 +20,16 @@ package org.apache.brooklyn.core.location.dynamic.clocker; import static org.testng.Assert.assertEquals; import static org.testng.Assert.assertFalse; +import static org.testng.Assert.assertSame; import org.apache.brooklyn.api.entity.EntitySpec; import org.apache.brooklyn.api.location.MachineLocation; +import org.apache.brooklyn.core.entity.BrooklynConfigKeys; import org.apache.brooklyn.core.entity.Entities; import org.apache.brooklyn.core.location.BasicLocationRegistry; import org.apache.brooklyn.core.location.Locations; import org.apache.brooklyn.core.test.BrooklynAppUnitTestSupport; +import org.apache.brooklyn.core.test.entity.TestApplication; import org.apache.brooklyn.location.localhost.LocalhostMachineProvisioningLocation; import org.testng.annotations.BeforeMethod; import org.testng.annotations.Test; @@ -35,6 +38,9 @@ import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; import com.google.common.collect.Iterables; +/** + * See explanation of what we're testing in {@link StubInfrastructure}. + */ public class ClockerDynamicLocationPatternTest extends BrooklynAppUnitTestSupport { private LocalhostMachineProvisioningLocation loc; @@ -51,7 +57,8 @@ public class ClockerDynamicLocationPatternTest extends BrooklynAppUnitTestSuppor @Test public void testCreateAndReleaseDirectly() throws Exception { - StubInfrastructure infra = mgmt.getEntityManager().createEntity(EntitySpec.create(StubInfrastructure.class)); + StubInfrastructure infra = mgmt.getEntityManager().createEntity(EntitySpec.create(StubInfrastructure.class) + .configure(BrooklynConfigKeys.SKIP_ON_BOX_BASE_DIR_RESOLUTION, shouldSkipOnBoxBaseDirResolution())); infra.start(ImmutableList.of(loc)); StubInfrastructureLocation loc = infra.getDynamicLocation(); @@ -72,17 +79,24 @@ public class ClockerDynamicLocationPatternTest extends BrooklynAppUnitTestSuppor @Test public void testThroughLocationRegistry() throws Exception { - StubInfrastructure infra = mgmt.getEntityManager().createEntity(EntitySpec.create(StubInfrastructure.class)); + StubInfrastructure infra = mgmt.getEntityManager().createEntity(EntitySpec.create(StubInfrastructure.class) + .configure(BrooklynConfigKeys.SKIP_ON_BOX_BASE_DIR_RESOLUTION, shouldSkipOnBoxBaseDirResolution())); infra.start(ImmutableList.of(loc)); String infraLocSpec = infra.sensors().get(StubInfrastructure.LOCATION_SPEC); + String infraLocName = infra.sensors().get(StubInfrastructure.LOCATION_NAME); StubInfrastructureLocation infraLoc = (StubInfrastructureLocation) mgmt.getLocationRegistry().resolve(infraLocSpec); - + StubInfrastructureLocation infraLoc2 = (StubInfrastructureLocation) mgmt.getLocationRegistry().resolve(infraLocName); + assertSame(infraLoc, infraLoc2); + MachineLocation machine = infraLoc.obtain(ImmutableMap.of()); StubHost host = (StubHost) Iterables.getOnlyElement(infra.getStubHostCluster().getMembers()); - String hostLocSpec = host.sensors().get(StubInfrastructure.LOCATION_SPEC); + String hostLocSpec = host.sensors().get(StubHost.LOCATION_SPEC); + String hostLocName = host.sensors().get(StubHost.LOCATION_NAME); StubHostLocation hostLoc = (StubHostLocation) mgmt.getLocationRegistry().resolve(hostLocSpec); + StubHostLocation hostLoc2 = (StubHostLocation) mgmt.getLocationRegistry().resolve(hostLocName); + assertSame(hostLoc, hostLoc2); StubContainer container = (StubContainer) Iterables.getOnlyElement(host.getDockerContainerCluster().getMembers()); StubContainerLocation containerLoc = container.getDynamicLocation(); http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/453183f1/software/base/src/test/java/org/apache/brooklyn/core/location/dynamic/clocker/StubContainerLocation.java ---------------------------------------------------------------------- diff --git a/software/base/src/test/java/org/apache/brooklyn/core/location/dynamic/clocker/StubContainerLocation.java b/software/base/src/test/java/org/apache/brooklyn/core/location/dynamic/clocker/StubContainerLocation.java index f4b0345..570cd73 100644 --- a/software/base/src/test/java/org/apache/brooklyn/core/location/dynamic/clocker/StubContainerLocation.java +++ b/software/base/src/test/java/org/apache/brooklyn/core/location/dynamic/clocker/StubContainerLocation.java @@ -18,6 +18,7 @@ */ package org.apache.brooklyn.core.location.dynamic.clocker; +import org.apache.brooklyn.api.location.LocationDefinition; import org.apache.brooklyn.core.location.dynamic.DynamicLocation; import org.apache.brooklyn.location.ssh.SshMachineLocation; import org.apache.brooklyn.util.core.flags.SetFromFlag; @@ -38,4 +39,14 @@ public class StubContainerLocation extends SshMachineLocation implements Dynamic public SshMachineLocation getMachine() { return machine; } -} \ No newline at end of file + + @Override + public LocationDefinition register() { + throw new UnsupportedOperationException("Container location type definition cannot be persisted"); + } + + @Override + public void deregister() { + // no-op + } +} http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/453183f1/software/base/src/test/java/org/apache/brooklyn/core/location/dynamic/clocker/StubHost.java ---------------------------------------------------------------------- diff --git a/software/base/src/test/java/org/apache/brooklyn/core/location/dynamic/clocker/StubHost.java b/software/base/src/test/java/org/apache/brooklyn/core/location/dynamic/clocker/StubHost.java index e5b4005..6b2d319 100644 --- a/software/base/src/test/java/org/apache/brooklyn/core/location/dynamic/clocker/StubHost.java +++ b/software/base/src/test/java/org/apache/brooklyn/core/location/dynamic/clocker/StubHost.java @@ -24,10 +24,10 @@ import org.apache.brooklyn.core.location.dynamic.LocationOwner; import org.apache.brooklyn.core.sensor.AttributeSensorAndConfigKey; import org.apache.brooklyn.core.sensor.Sensors; import org.apache.brooklyn.entity.group.DynamicCluster; -import org.apache.brooklyn.entity.machine.MachineEntity; +import org.apache.brooklyn.entity.software.base.EmptySoftwareProcess; @ImplementedBy(StubHostImpl.class) -public interface StubHost extends MachineEntity, LocationOwner<StubHostLocation, StubHost> { +public interface StubHost extends EmptySoftwareProcess, LocationOwner<StubHostLocation, StubHost> { AttributeSensorAndConfigKey<StubInfrastructure, StubInfrastructure> DOCKER_INFRASTRUCTURE = StubAttributes.DOCKER_INFRASTRUCTURE; AttributeSensor<DynamicCluster> DOCKER_CONTAINER_CLUSTER = Sensors.newSensor(DynamicCluster.class, http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/453183f1/software/base/src/test/java/org/apache/brooklyn/core/location/dynamic/clocker/StubHostImpl.java ---------------------------------------------------------------------- diff --git a/software/base/src/test/java/org/apache/brooklyn/core/location/dynamic/clocker/StubHostImpl.java b/software/base/src/test/java/org/apache/brooklyn/core/location/dynamic/clocker/StubHostImpl.java index 4c2ad36..3139d93 100644 --- a/software/base/src/test/java/org/apache/brooklyn/core/location/dynamic/clocker/StubHostImpl.java +++ b/software/base/src/test/java/org/apache/brooklyn/core/location/dynamic/clocker/StubHostImpl.java @@ -21,23 +21,20 @@ package org.apache.brooklyn.core.location.dynamic.clocker; import java.util.Map; import org.apache.brooklyn.api.entity.EntitySpec; -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.core.feed.ConfigToAttributes; -import org.apache.brooklyn.core.location.BasicLocationDefinition; import org.apache.brooklyn.core.location.Locations; import org.apache.brooklyn.core.location.Machines; import org.apache.brooklyn.entity.group.Cluster; import org.apache.brooklyn.entity.group.DynamicCluster; -import org.apache.brooklyn.entity.machine.MachineEntityImpl; +import org.apache.brooklyn.entity.software.base.EmptySoftwareProcessImpl; import org.apache.brooklyn.location.ssh.SshMachineLocation; -import org.apache.brooklyn.util.collections.MutableMap; import org.apache.brooklyn.util.collections.QuorumCheck.QuorumChecks; -import org.apache.brooklyn.util.guava.Maybe; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -public class StubHostImpl extends MachineEntityImpl implements StubHost { +public class StubHostImpl extends EmptySoftwareProcessImpl implements StubHost { private static final Logger LOG = LoggerFactory.getLogger(StubHostImpl.class); @@ -81,14 +78,7 @@ public class StubHostImpl extends MachineEntityImpl implements StubHost { super.preStart(); ConfigToAttributes.apply(this); - Maybe<SshMachineLocation> found = Machines.findUniqueMachineLocation(getLocations(), SshMachineLocation.class); - - Map<String, ?> flags = MutableMap.<String, Object>builder() - .putAll(config().get(LOCATION_FLAGS)) - .put("machine", found.get()) - .build(); - - createLocation(flags); + createLocation(config().get(LOCATION_FLAGS)); sensors().get(DOCKER_CONTAINER_CLUSTER).sensors().set(SERVICE_UP, Boolean.TRUE); } @@ -96,18 +86,25 @@ public class StubHostImpl extends MachineEntityImpl implements StubHost { public StubHostLocation createLocation(Map<String, ?> flags) { StubInfrastructure infrastructure = getInfrastructure(); StubInfrastructureLocation docker = infrastructure.getDynamicLocation(); + SshMachineLocation machine = Machines.findUniqueMachineLocation(getLocations(), SshMachineLocation.class).get(); String locationName = docker.getId() + "-" + getId(); - String locationSpec = String.format(StubResolver.DOCKER_HOST_MACHINE_SPEC, infrastructure.getId(), getId()) + String.format(":(name=\"%s\")", locationName); - sensors().set(LOCATION_SPEC, locationSpec); + StubHostLocation location = getManagementContext().getLocationManager().createLocation(LocationSpec.create(StubHostLocation.class) + .parent(infrastructure.getDynamicLocation()) + .displayName("Docker Host("+getId()+")") + .configure(flags) + .configure("owner", getProxy()) + .configure("machine", machine) + .configure("locationName", locationName)); + + LocationDefinition definition = location.register(); - LocationDefinition definition = new BasicLocationDefinition(locationName, locationSpec, flags); - Location location = getManagementContext().getLocationRegistry().resolve(definition); + sensors().set(LOCATION_SPEC, definition.getSpec()); + sensors().set(LOCATION_NAME, locationName); sensors().set(DYNAMIC_LOCATION, location); - sensors().set(LOCATION_NAME, location.getId()); LOG.info("New Docker host location {} created", location); - return (StubHostLocation) location; + return location; } @Override @@ -119,6 +116,7 @@ public class StubHostImpl extends MachineEntityImpl implements StubHost { public void deleteLocation() { StubHostLocation loc = (StubHostLocation) sensors().get(DYNAMIC_LOCATION); if (loc != null) { + loc.deregister(); Locations.unmanage(loc); } sensors().set(DYNAMIC_LOCATION, null); http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/453183f1/software/base/src/test/java/org/apache/brooklyn/core/location/dynamic/clocker/StubHostLocation.java ---------------------------------------------------------------------- diff --git a/software/base/src/test/java/org/apache/brooklyn/core/location/dynamic/clocker/StubHostLocation.java b/software/base/src/test/java/org/apache/brooklyn/core/location/dynamic/clocker/StubHostLocation.java index a861220..9c76848 100644 --- a/software/base/src/test/java/org/apache/brooklyn/core/location/dynamic/clocker/StubHostLocation.java +++ b/software/base/src/test/java/org/apache/brooklyn/core/location/dynamic/clocker/StubHostLocation.java @@ -18,16 +18,22 @@ */ package org.apache.brooklyn.core.location.dynamic.clocker; +import static com.google.common.base.Preconditions.checkNotNull; + import java.util.Collection; import java.util.Map; import org.apache.brooklyn.api.entity.Entity; import org.apache.brooklyn.api.entity.EntityLocal; +import org.apache.brooklyn.api.location.LocationDefinition; import org.apache.brooklyn.api.location.MachineProvisioningLocation; import org.apache.brooklyn.api.location.NoMachinesAvailableException; +import org.apache.brooklyn.config.ConfigKey; +import org.apache.brooklyn.core.config.ConfigKeys; import org.apache.brooklyn.core.entity.Entities; import org.apache.brooklyn.core.entity.trait.Startable; import org.apache.brooklyn.core.location.AbstractLocation; +import org.apache.brooklyn.core.location.BasicLocationDefinition; import org.apache.brooklyn.core.location.LocationConfigKeys; import org.apache.brooklyn.core.location.Locations; import org.apache.brooklyn.core.location.dynamic.DynamicLocation; @@ -46,12 +52,68 @@ public class StubHostLocation extends AbstractLocation implements MachineProvisi private static final Logger LOG = LoggerFactory.getLogger(StubHostLocation.class); - @SetFromFlag("machine") - private SshMachineLocation machine; + public static final ConfigKey<String> LOCATION_NAME = ConfigKeys.newStringConfigKey("locationName"); + + public static final ConfigKey<SshMachineLocation> MACHINE = ConfigKeys.newConfigKey( + SshMachineLocation.class, + "machine"); + + @SetFromFlag("locationRegistrationId") + private String locationRegistrationId; - @SetFromFlag("owner") - private StubHost dockerHost; + private transient StubHost dockerHost; + private transient SshMachineLocation machine; + + @Override + public void init() { + super.init(); + dockerHost = (StubHost) checkNotNull(getConfig(OWNER), "owner"); + machine = (SshMachineLocation) checkNotNull(getConfig(MACHINE), "machine"); + } + + @Override + public void rebind() { + super.rebind(); + dockerHost = (StubHost) getConfig(OWNER); + machine = (SshMachineLocation) getConfig(MACHINE); + + if (getConfig(LOCATION_NAME) != null) { + register(); + } + } + + @Override + public LocationDefinition register() { + String locationName = checkNotNull(getConfig(LOCATION_NAME), "config %s", LOCATION_NAME.getName()); + + LocationDefinition check = getManagementContext().getLocationRegistry().getDefinedLocationByName(locationName); + if (check != null) { + throw new IllegalStateException("Location " + locationName + " is already defined: " + check); + } + + String hostLocId = getId(); + String infraLocId = (getParent() != null) ? getParent().getId() : ""; + String locationSpec = String.format(StubResolver.DOCKER_HOST_MACHINE_SPEC, infraLocId, hostLocId) + String.format(":(name=\"%s\")", locationName); + + LocationDefinition definition = new BasicLocationDefinition(locationName, locationSpec, ImmutableMap.<String, Object>of()); + getManagementContext().getLocationRegistry().updateDefinedLocation(definition); + + locationRegistrationId = definition.getId(); + requestPersist(); + + return definition; + } + + @Override + public void deregister() { + if (locationRegistrationId != null) { + getManagementContext().getLocationRegistry().removeDefinedLocation(locationRegistrationId); + locationRegistrationId = null; + requestPersist(); + } + } + @Override public StubHost getOwner() { return (StubHost) getConfig(OWNER); http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/453183f1/software/base/src/test/java/org/apache/brooklyn/core/location/dynamic/clocker/StubInfrastructure.java ---------------------------------------------------------------------- diff --git a/software/base/src/test/java/org/apache/brooklyn/core/location/dynamic/clocker/StubInfrastructure.java b/software/base/src/test/java/org/apache/brooklyn/core/location/dynamic/clocker/StubInfrastructure.java index 3170cf2..f6a9afd 100644 --- a/software/base/src/test/java/org/apache/brooklyn/core/location/dynamic/clocker/StubInfrastructure.java +++ b/software/base/src/test/java/org/apache/brooklyn/core/location/dynamic/clocker/StubInfrastructure.java @@ -29,6 +29,8 @@ import org.apache.brooklyn.config.ConfigKey; import org.apache.brooklyn.core.config.ConfigKeys; import org.apache.brooklyn.core.entity.trait.Startable; import org.apache.brooklyn.core.location.dynamic.LocationOwner; +import org.apache.brooklyn.core.sensor.AttributeSensorAndConfigKey; +import org.apache.brooklyn.core.sensor.BasicAttributeSensorAndConfigKey; import org.apache.brooklyn.core.sensor.Sensors; import org.apache.brooklyn.entity.group.DynamicCluster; import org.apache.brooklyn.entity.group.DynamicGroup; @@ -81,8 +83,9 @@ import org.apache.brooklyn.entity.group.DynamicMultiGroup; */ @ImplementedBy(StubInfrastructureImpl.class) public interface StubInfrastructure extends Application, Startable, LocationOwner<StubInfrastructureLocation, StubInfrastructure> { - ConfigKey<String> LOCATION_NAME = ConfigKeys.newConfigKeyWithDefault(LocationOwner.LOCATION_NAME.getConfigKey(), "my-stub-cloud"); - + AttributeSensorAndConfigKey<String, String> LOCATION_NAME = ConfigKeys.newSensorAndConfigKeyWithDefault(LocationOwner.LOCATION_NAME, "my-stub-cloud"); + ConfigKey<Integer> DOCKER_HOST_CLUSTER_MIN_SIZE = ConfigKeys.newConfigKeyWithPrefix("docker.host.", DynamicCluster.INITIAL_SIZE); + AttributeSensor<DynamicCluster> DOCKER_HOST_CLUSTER = Sensors.newSensor(DynamicCluster.class, "docker.hosts", "Docker host cluster"); AttributeSensor<DynamicGroup> DOCKER_CONTAINER_FABRIC = Sensors.newSensor(DynamicGroup.class, "docker.fabric", "Docker container fabric"); AttributeSensor<DynamicMultiGroup> DOCKER_APPLICATIONS = Sensors.newSensor(DynamicMultiGroup.class, "docker.buckets", "Docker applications"); http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/453183f1/software/base/src/test/java/org/apache/brooklyn/core/location/dynamic/clocker/StubInfrastructureImpl.java ---------------------------------------------------------------------- diff --git a/software/base/src/test/java/org/apache/brooklyn/core/location/dynamic/clocker/StubInfrastructureImpl.java b/software/base/src/test/java/org/apache/brooklyn/core/location/dynamic/clocker/StubInfrastructureImpl.java index 0d807fa..0f578bc 100644 --- a/software/base/src/test/java/org/apache/brooklyn/core/location/dynamic/clocker/StubInfrastructureImpl.java +++ b/software/base/src/test/java/org/apache/brooklyn/core/location/dynamic/clocker/StubInfrastructureImpl.java @@ -30,15 +30,13 @@ 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.LocationDefinition; -import org.apache.brooklyn.api.mgmt.LocationManager; -import org.apache.brooklyn.api.mgmt.ManagementContext; +import org.apache.brooklyn.api.location.LocationSpec; import org.apache.brooklyn.core.entity.AbstractApplication; -import org.apache.brooklyn.core.entity.Attributes; import org.apache.brooklyn.core.entity.Entities; import org.apache.brooklyn.core.entity.EntityPredicates; import org.apache.brooklyn.core.entity.trait.Startable; import org.apache.brooklyn.core.feed.ConfigToAttributes; -import org.apache.brooklyn.core.location.BasicLocationDefinition; +import org.apache.brooklyn.core.location.Locations; import org.apache.brooklyn.core.location.dynamic.LocationOwner; import org.apache.brooklyn.entity.group.BasicGroup; import org.apache.brooklyn.entity.group.Cluster; @@ -48,11 +46,13 @@ import org.apache.brooklyn.entity.group.DynamicMultiGroup; import org.apache.brooklyn.entity.software.base.SoftwareProcess; import org.apache.brooklyn.util.collections.MutableMap; import org.apache.brooklyn.util.collections.QuorumCheck.QuorumChecks; +import org.apache.brooklyn.util.text.Strings; import org.apache.brooklyn.util.time.Duration; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.google.common.base.Function; +import com.google.common.base.Joiner; import com.google.common.base.Predicates; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableSet; @@ -73,7 +73,7 @@ public class StubInfrastructureImpl extends AbstractApplication implements StubI .configure(SoftwareProcess.CHILDREN_STARTABLE_MODE, SoftwareProcess.ChildStartableMode.BACKGROUND_LATE); DynamicCluster hosts = addChild(EntitySpec.create(DynamicCluster.class) - .configure(Cluster.INITIAL_SIZE, 1) + .configure(Cluster.INITIAL_SIZE, config().get(DOCKER_HOST_CLUSTER_MIN_SIZE)) .configure(DynamicCluster.QUARANTINE_FAILED_ENTITIES, true) .configure(DynamicCluster.MEMBER_SPEC, dockerHostSpec) .configure(DynamicCluster.RUNNING_QUORUM_CHECK, QuorumChecks.atLeastOneUnlessEmpty()) @@ -104,17 +104,6 @@ public class StubInfrastructureImpl extends AbstractApplication implements StubI } @Override - public void rebind() { - super.rebind(); - - // Reload our location definition on rebind - ManagementContext.PropertiesReloadListener listener = sensors().get(Attributes.PROPERTIES_RELOAD_LISTENER); - if (listener != null) { - listener.reloaded(); - } - } - - @Override public StubInfrastructureLocation getDynamicLocation() { return (StubInfrastructureLocation) sensors().get(DYNAMIC_LOCATION); } @@ -178,27 +167,25 @@ public class StubInfrastructureImpl extends AbstractApplication implements StubI @Override public StubInfrastructureLocation createLocation(Map<String, ?> flags) { String locationName = config().get(LOCATION_NAME); - - LocationDefinition check = getManagementContext().getLocationRegistry().getDefinedLocationByName(locationName); - if (check != null) { - throw new IllegalStateException("Location " + locationName + " is already defined: " + check); + if (Strings.isBlank(locationName)) { + String prefix = config().get(LOCATION_NAME_PREFIX); + String suffix = config().get(LOCATION_NAME_SUFFIX); + locationName = Joiner.on("-").skipNulls().join(prefix, getId(), suffix); } - String locationSpec = String.format(StubResolver.DOCKER_INFRASTRUCTURE_SPEC, getId()) + String.format(":(name=\"%s\")", locationName); - sensors().set(LOCATION_SPEC, locationSpec); - LocationDefinition definition = new BasicLocationDefinition(locationName, locationSpec, flags); - Location location = getManagementContext().getLocationRegistry().resolve(definition); - getManagementContext().getLocationRegistry().updateDefinedLocation(definition); - - ManagementContext.PropertiesReloadListener listener = StubUtils.reloadLocationListener(getManagementContext(), definition); - getManagementContext().addPropertiesReloadListener(listener); - sensors().set(Attributes.PROPERTIES_RELOAD_LISTENER, listener); + StubInfrastructureLocation location = getManagementContext().getLocationManager().createLocation(LocationSpec.create(StubInfrastructureLocation.class) + .displayName("Docker Infrastructure("+getId()+")") + .configure(flags) + .configure("owner", getProxy()) + .configure("locationName", locationName)); + + LocationDefinition definition = location.register(); - sensors().set(LocationOwner.LOCATION_DEFINITION, definition); + sensors().set(LocationOwner.LOCATION_SPEC, definition.getSpec()); sensors().set(LocationOwner.DYNAMIC_LOCATION, location); - sensors().set(LocationOwner.LOCATION_NAME, location.getId()); + sensors().set(LocationOwner.LOCATION_NAME, locationName); - return (StubInfrastructureLocation) location; + return location; } @Override @@ -211,21 +198,10 @@ public class StubInfrastructureImpl extends AbstractApplication implements StubI StubInfrastructureLocation location = getDynamicLocation(); if (location != null) { - LocationManager mgr = getManagementContext().getLocationManager(); - if (mgr.isManaged(location)) { - mgr.unmanage(location); - } - final LocationDefinition definition = sensors().get(LocationOwner.LOCATION_DEFINITION); - if (definition != null) { - getManagementContext().getLocationRegistry().removeDefinedLocation(definition.getId()); - } - } - ManagementContext.PropertiesReloadListener listener = sensors().get(Attributes.PROPERTIES_RELOAD_LISTENER); - if (listener != null) { - getManagementContext().removePropertiesReloadListener(listener); + location.deregister(); + Locations.unmanage(location); } - sensors().set(LocationOwner.LOCATION_DEFINITION, null); sensors().set(LocationOwner.DYNAMIC_LOCATION, null); sensors().set(LocationOwner.LOCATION_NAME, null); } http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/453183f1/software/base/src/test/java/org/apache/brooklyn/core/location/dynamic/clocker/StubInfrastructureLocation.java ---------------------------------------------------------------------- diff --git a/software/base/src/test/java/org/apache/brooklyn/core/location/dynamic/clocker/StubInfrastructureLocation.java b/software/base/src/test/java/org/apache/brooklyn/core/location/dynamic/clocker/StubInfrastructureLocation.java index 05587f1..5d5695c 100644 --- a/software/base/src/test/java/org/apache/brooklyn/core/location/dynamic/clocker/StubInfrastructureLocation.java +++ b/software/base/src/test/java/org/apache/brooklyn/core/location/dynamic/clocker/StubInfrastructureLocation.java @@ -18,14 +18,20 @@ */ package org.apache.brooklyn.core.location.dynamic.clocker; +import static com.google.common.base.Preconditions.checkNotNull; + import java.util.Collection; import java.util.Map; import java.util.Set; +import org.apache.brooklyn.api.location.LocationDefinition; import org.apache.brooklyn.api.location.MachineLocation; import org.apache.brooklyn.api.location.MachineProvisioningLocation; import org.apache.brooklyn.api.location.NoMachinesAvailableException; +import org.apache.brooklyn.config.ConfigKey; +import org.apache.brooklyn.core.config.ConfigKeys; import org.apache.brooklyn.core.location.AbstractLocation; +import org.apache.brooklyn.core.location.BasicLocationDefinition; import org.apache.brooklyn.core.location.dynamic.DynamicLocation; import org.apache.brooklyn.util.core.flags.SetFromFlag; import org.slf4j.Logger; @@ -43,15 +49,65 @@ public class StubInfrastructureLocation extends AbstractLocation implements Mach @SuppressWarnings("unused") private static final Logger LOG = LoggerFactory.getLogger(StubInfrastructureLocation.class); - @SetFromFlag("owner") - private StubInfrastructure infrastructure; + public static final ConfigKey<String> LOCATION_NAME = ConfigKeys.newStringConfigKey("locationName"); + + @SetFromFlag("locationRegistrationId") + private String locationRegistrationId; @SetFromFlag("machines") private final SetMultimap<StubHostLocation, String> containers = Multimaps.synchronizedSetMultimap(HashMultimap.<StubHostLocation, String>create()); + private transient StubInfrastructure infrastructure; + + @Override + public void init() { + super.init(); + infrastructure = (StubInfrastructure) checkNotNull(getConfig(OWNER), "owner"); + } + + @Override + public void rebind() { + super.rebind(); + + infrastructure = (StubInfrastructure) getConfig(OWNER); + + if (getConfig(LOCATION_NAME) != null) { + register(); + } + } + + @Override + public LocationDefinition register() { + String locationName = checkNotNull(getConfig(LOCATION_NAME), "config %s", LOCATION_NAME.getName()); + + LocationDefinition check = getManagementContext().getLocationRegistry().getDefinedLocationByName(locationName); + if (check != null) { + throw new IllegalStateException("Location " + locationName + " is already defined: " + check); + } + + String locationSpec = String.format(StubResolver.DOCKER_INFRASTRUCTURE_SPEC, getId()) + String.format(":(name=\"%s\")", locationName); + + LocationDefinition definition = new BasicLocationDefinition(locationName, locationSpec, ImmutableMap.<String, Object>of()); + getManagementContext().getLocationRegistry().updateDefinedLocation(definition); + + locationRegistrationId = definition.getId(); + requestPersist(); + + return definition; + } + + @Override + public void deregister() { + if (locationRegistrationId != null) { + getManagementContext().getLocationRegistry().removeDefinedLocation(locationRegistrationId); + locationRegistrationId = null; + requestPersist(); + } + } + @Override public StubInfrastructure getOwner() { - return infrastructure; + return (StubInfrastructure) getConfig(OWNER); } @Override http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/453183f1/software/base/src/test/java/org/apache/brooklyn/core/location/dynamic/clocker/StubResolver.java ---------------------------------------------------------------------- diff --git a/software/base/src/test/java/org/apache/brooklyn/core/location/dynamic/clocker/StubResolver.java b/software/base/src/test/java/org/apache/brooklyn/core/location/dynamic/clocker/StubResolver.java index 99fd2b1..8aaf4a8 100644 --- a/software/base/src/test/java/org/apache/brooklyn/core/location/dynamic/clocker/StubResolver.java +++ b/software/base/src/test/java/org/apache/brooklyn/core/location/dynamic/clocker/StubResolver.java @@ -26,21 +26,23 @@ import java.util.Set; import java.util.regex.Matcher; import java.util.regex.Pattern; +import org.apache.brooklyn.api.internal.AbstractBrooklynObjectSpec; import org.apache.brooklyn.api.location.Location; import org.apache.brooklyn.api.location.LocationRegistry; -import org.apache.brooklyn.api.location.LocationResolver.EnableableLocationResolver; +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.config.ConfigKey; +import org.apache.brooklyn.core.config.ConfigKeys; import org.apache.brooklyn.core.location.BasicLocationRegistry; -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.core.objs.proxy.SpecialBrooklynObjectConstructor; +import org.apache.brooklyn.core.objs.proxy.SpecialBrooklynObjectConstructor.Config; import org.apache.brooklyn.util.text.KeyValueParser; import org.apache.brooklyn.util.text.Strings; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import com.google.common.annotations.Beta; import com.google.common.base.Joiner; import com.google.common.collect.ImmutableSet; import com.google.common.collect.Sets; @@ -54,17 +56,17 @@ import com.google.common.collect.Sets; * <li>docker:infrastructureId:dockerHostId:(name=dockerHost-brooklyn-1234,user=docker) * </ul> */ -public class StubResolver implements EnableableLocationResolver { +public class StubResolver implements LocationResolver { private static final Logger LOG = LoggerFactory.getLogger(StubResolver.class); - public static final String DOCKER = "docker"; + public static final String DOCKER = "stub"; public static final Pattern PATTERN = Pattern.compile("("+DOCKER+"|"+DOCKER.toUpperCase()+")" + ":([a-zA-Z0-9]+)" + "(:([a-zA-Z0-9]+))?" + "(:\\((.*)\\))?$"); - public static final Set<String> ACCEPTABLE_ARGS = ImmutableSet.of("name", "displayName"); + public static final String DOCKER_INFRASTRUCTURE_SPEC = "stub:%s"; + public static final String DOCKER_HOST_MACHINE_SPEC = "stub:%s:%s"; - public static final String DOCKER_INFRASTRUCTURE_SPEC = "docker:%s"; - public static final String DOCKER_HOST_MACHINE_SPEC = "docker:%s:%s"; + private static final Set<String> ACCEPTABLE_ARGS = ImmutableSet.of("name"); private ManagementContext managementContext; @@ -79,118 +81,79 @@ public class StubResolver implements EnableableLocationResolver { } @Override - public Location newLocationFromString(Map locationFlags, String spec, LocationRegistry registry) { - return newLocationFromString(spec, registry, registry.getProperties(), locationFlags); + public boolean accepts(String spec, LocationRegistry registry) { + return BasicLocationRegistry.isResolverPrefixForSpec(this, spec, true); } - protected Location newLocationFromString(String spec, LocationRegistry registry, Map properties, Map locationFlags) { + @Override + public boolean isEnabled() { + // TODO Should we base enablement on whether the required location/entity exists? + return true; + } + + @Override + public LocationSpec<? extends Location> newLocationSpecFromString(String spec, Map<?,?> locationFlags, LocationRegistry registry) { + Map<?,?> properties = registry.getProperties(); + if (LOG.isDebugEnabled()) { LOG.debug("Resolving location '" + spec + "' with flags " + Joiner.on(",").withKeyValueSeparator("=").join(locationFlags)); } - String namedLocation = (String) locationFlags.get(LocationInternal.NAMED_SPEC_NAME.getName()); Matcher matcher = PATTERN.matcher(spec); if (!matcher.matches()) { - throw new IllegalArgumentException("Invalid location '"+spec+"'; must specify something like docker:entityId or docker:entityId:(name=abc)"); + throw new IllegalArgumentException("Invalid location '"+spec+"'; must specify something like stub:entityId or stub:entityId:(name=abc)"); } + String infrastructureLocId = matcher.group(2); + if (Strings.isBlank(infrastructureLocId)) { + throw new IllegalArgumentException("Invalid location '"+spec+"'; infrastructure location id must be non-empty"); + } + String hostLocId = matcher.group(4); + + // TODO Could validate that the namePart matches the existing loc String argsPart = matcher.group(6); Map<String, String> argsMap = (argsPart != null) ? KeyValueParser.parseMap(argsPart) : Collections.<String,String>emptyMap(); - String displayNamePart = argsMap.get("displayName"); + @SuppressWarnings("unused") String namePart = argsMap.get("name"); if (!ACCEPTABLE_ARGS.containsAll(argsMap.keySet())) { Set<String> illegalArgs = Sets.difference(argsMap.keySet(), ACCEPTABLE_ARGS); throw new IllegalArgumentException("Invalid location '"+spec+"'; illegal args "+illegalArgs+"; acceptable args are "+ACCEPTABLE_ARGS); } - if (argsMap.containsKey("displayName") && Strings.isEmpty(displayNamePart)) { - throw new IllegalArgumentException("Invalid location '"+spec+"'; if displayName supplied then value must be non-empty"); - } - if (argsMap.containsKey("name") && Strings.isEmpty(namePart)) { - throw new IllegalArgumentException("Invalid location '"+spec+"'; if name supplied then value must be non-empty"); - } - Map<String, Object> filteredProperties = new LocationPropertiesFromBrooklynProperties().getLocationProperties(DOCKER, namedLocation, properties); - MutableMap<String, Object> flags = MutableMap.<String, Object>builder().putAll(filteredProperties).putAll(locationFlags).build(); - - String infrastructureId = matcher.group(2); - if (Strings.isBlank(infrastructureId)) { - throw new IllegalArgumentException("Invalid location '"+spec+"'; infrastructure entity id must be non-empty"); + Location infrastructureLoc = managementContext.getLocationManager().getLocation(infrastructureLocId); + if (infrastructureLoc == null) { + throw new IllegalArgumentException("Unknown Clocker infrastructure location id "+infrastructureLocId+", spec "+spec); + } else if (!(infrastructureLoc instanceof StubInfrastructureLocation)) { + throw new IllegalArgumentException("Invalid location id for Clocker infrastructure, spec "+spec+"; instead matches "+infrastructureLoc); } - String dockerHostId = matcher.group(4); - // Build the display name - StringBuilder name = new StringBuilder(); - if (displayNamePart != null) { - name.append(displayNamePart); - } else { - name.append("Docker "); - if (dockerHostId == null) { - name.append("Infrastructure ").append(infrastructureId); - } else { - name.append("Host ").append(dockerHostId); + if (hostLocId != null) { + Location hostLoc = managementContext.getLocationManager().getLocation(hostLocId); + if (hostLoc == null) { + throw new IllegalArgumentException("Unknown Clocker host location id "+hostLocId+", spec "+spec); + } else if (!(hostLoc instanceof StubHostLocation)) { + throw new IllegalArgumentException("Invalid location id for Clocker host, spec "+spec+"; instead matches "+hostLoc); } - } - final String displayName = name.toString(); - - // Build the location name - name = new StringBuilder(); - if (namePart != null) { - name.append(namePart); + + return LocationSpec.create(StubHostLocation.class) + .configure(StubLocationConstructor.LOCATION, hostLoc) + .configure(Config.SPECIAL_CONSTRUCTOR, StubLocationConstructor.class); } else { - name.append("docker-"); - name.append(infrastructureId); - if (dockerHostId != null) { - name.append("-").append(dockerHostId); - } - } - final String locationName = name.toString(); - StubInfrastructure infrastructure = (StubInfrastructure) managementContext.getEntityManager().getEntity(infrastructureId); - Iterable<Location> managedLocations = managementContext.getLocationManager().getLocations(); - - if (dockerHostId == null) { - for (Location location : managedLocations) { - if (location instanceof StubInfrastructureLocation) { - if (((StubInfrastructureLocation) location).getOwner().getId().equals(infrastructureId)) { - return location; - } - } - } - LocationSpec<StubInfrastructureLocation> locationSpec = LocationSpec.create(StubInfrastructureLocation.class) - .configure(flags) - .configure(DynamicLocation.OWNER, infrastructure) - .configure(LocationInternal.NAMED_SPEC_NAME, locationName) - .displayName(displayName); - return managementContext.getLocationManager().createLocation(locationSpec); - } else { - StubHost dockerHost = (StubHost) managementContext.getEntityManager().getEntity(dockerHostId); - for (Location location : managedLocations) { - if (location instanceof StubHostLocation) { - if (((StubHostLocation) location).getOwner().getId().equals(dockerHostId)) { - return location; - } - } - } - - LocationSpec<StubHostLocation> locationSpec = LocationSpec.create(StubHostLocation.class) - .parent(infrastructure.getDynamicLocation()) - .configure(flags) - .configure(DynamicLocation.OWNER, dockerHost) - .configure(LocationInternal.NAMED_SPEC_NAME, locationName) - .displayName(displayName); - return managementContext.getLocationManager().createLocation(locationSpec); + return LocationSpec.create(StubInfrastructureLocation.class) + .configure(StubLocationConstructor.LOCATION, infrastructureLoc) + .configure(Config.SPECIAL_CONSTRUCTOR, StubLocationConstructor.class); } } - @Override - public boolean accepts(String spec, LocationRegistry registry) { - return BasicLocationRegistry.isResolverPrefixForSpec(this, spec, true); - } - - @Override - public boolean isEnabled() { - return true; -// return Iterables.tryFind(managementContext.getEntityManager().getEntities(), Predicates.instanceOf(StubInfrastructure.class)).isPresent(); + @Beta + public static class StubLocationConstructor implements SpecialBrooklynObjectConstructor { + public static ConfigKey<Location> LOCATION = ConfigKeys.newConfigKey(Location.class, "stubresolver.location"); + + @SuppressWarnings("unchecked") + @Override + public <T> T create(ManagementContext mgmt, Class<T> type, AbstractBrooklynObjectSpec<?, ?> spec) { + return (T) checkNotNull(spec.getConfig().get(LOCATION), LOCATION.getName()); + } } - } http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/453183f1/software/base/src/test/java/org/apache/brooklyn/core/location/dynamic/clocker/StubResolverTest.java ---------------------------------------------------------------------- diff --git a/software/base/src/test/java/org/apache/brooklyn/core/location/dynamic/clocker/StubResolverTest.java b/software/base/src/test/java/org/apache/brooklyn/core/location/dynamic/clocker/StubResolverTest.java new file mode 100644 index 0000000..6ffb387 --- /dev/null +++ b/software/base/src/test/java/org/apache/brooklyn/core/location/dynamic/clocker/StubResolverTest.java @@ -0,0 +1,82 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.brooklyn.core.location.dynamic.clocker; + +import static org.testng.Assert.assertEquals; + +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.core.entity.BrooklynConfigKeys; +import org.apache.brooklyn.core.location.BasicLocationRegistry; +import org.apache.brooklyn.core.location.dynamic.LocationOwner; +import org.apache.brooklyn.core.test.BrooklynAppUnitTestSupport; +import org.apache.brooklyn.location.localhost.LocalhostMachineProvisioningLocation; +import org.testng.annotations.BeforeMethod; +import org.testng.annotations.Test; + +import com.google.common.collect.ImmutableList; +import com.google.common.collect.Iterables; + +public class StubResolverTest extends BrooklynAppUnitTestSupport { + + private StubInfrastructure infrastructure; + private Location localhostLoc; + + @BeforeMethod(alwaysRun=true) + @Override + public void setUp() throws Exception { + super.setUp(); + + StubResolver stubResolver = new StubResolver(); + ((BasicLocationRegistry)mgmt.getLocationRegistry()).registerResolver(stubResolver); + + infrastructure = app.createAndManageChild(EntitySpec.create(StubInfrastructure.class) + .configure(BrooklynConfigKeys.SKIP_ON_BOX_BASE_DIR_RESOLUTION, shouldSkipOnBoxBaseDirResolution()) + .configure(StubInfrastructure.DOCKER_HOST_CLUSTER_MIN_SIZE, 1)); + localhostLoc = mgmt.getLocationManager() + .createLocation(LocationSpec.create(LocalhostMachineProvisioningLocation.class)); + app.start(ImmutableList.of(localhostLoc)); + } + + @Test + public void testResolveInfrastructure() { + String spec = "stub:" + infrastructure.getDynamicLocation().getId(); + StubInfrastructureLocation loc = (StubInfrastructureLocation) mgmt.getLocationRegistry().resolve(spec); + assertEquals(loc, infrastructure.getDynamicLocation()); + + String spec2 = infrastructure.sensors().get(LocationOwner.LOCATION_SPEC); + StubInfrastructureLocation loc2 = (StubInfrastructureLocation) mgmt.getLocationRegistry().resolve(spec2); + assertEquals(loc2, infrastructure.getDynamicLocation()); + } + + @Test + public void testResolveHost() { + StubHost host = (StubHost) Iterables.getOnlyElement(infrastructure.getStubHostCluster().getMembers()); + + String spec = "stub:" + infrastructure.getDynamicLocation().getId() + ":" + host.getDynamicLocation().getId(); + StubHostLocation loc = (StubHostLocation) mgmt.getLocationRegistry().resolve(spec); + assertEquals(loc, host.getDynamicLocation()); + + + String spec2 = host.sensors().get(LocationOwner.LOCATION_SPEC); + StubHostLocation loc2 = (StubHostLocation) mgmt.getLocationRegistry().resolve(spec2); + assertEquals(loc2, host.getDynamicLocation()); + } +}
