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 2015/12/17 13:32:32 UTC

[1/7] incubator-brooklyn git commit: Remove "public static final" from GeoDns entity interfaces

Repository: incubator-brooklyn
Updated Branches:
  refs/heads/master b0875f4a1 -> 3584f5bf9


Remove "public static final" from GeoDns entity interfaces


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

Branch: refs/heads/master
Commit: c85c378f9a43a916aeb1a979868f95270a997f2d
Parents: c45fdcd
Author: Sam Corbett <sa...@cloudsoftcorp.com>
Authored: Tue Dec 8 18:16:27 2015 +0000
Committer: Sam Corbett <sa...@cloudsoftcorp.com>
Committed: Wed Dec 9 16:55:09 2015 +0000

----------------------------------------------------------------------
 .../entity/dns/AbstractGeoDnsService.java       | 31 ++++++------
 .../dns/geoscaling/GeoscalingDnsService.java    | 50 ++++++++++++--------
 2 files changed, 46 insertions(+), 35 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/c85c378f/software/webapp/src/main/java/org/apache/brooklyn/entity/dns/AbstractGeoDnsService.java
----------------------------------------------------------------------
diff --git a/software/webapp/src/main/java/org/apache/brooklyn/entity/dns/AbstractGeoDnsService.java b/software/webapp/src/main/java/org/apache/brooklyn/entity/dns/AbstractGeoDnsService.java
index 2896b48..43c7b97 100644
--- a/software/webapp/src/main/java/org/apache/brooklyn/entity/dns/AbstractGeoDnsService.java
+++ b/software/webapp/src/main/java/org/apache/brooklyn/entity/dns/AbstractGeoDnsService.java
@@ -29,31 +29,34 @@ import org.apache.brooklyn.core.entity.Attributes;
 import org.apache.brooklyn.core.entity.lifecycle.Lifecycle;
 import org.apache.brooklyn.core.entity.trait.Startable;
 import org.apache.brooklyn.core.location.geo.HostGeoInfo;
-import org.apache.brooklyn.core.sensor.BasicAttributeSensor;
+import org.apache.brooklyn.core.sensor.Sensors;
 
 import com.google.common.reflect.TypeToken;
 
 public interface AbstractGeoDnsService extends Entity {
     
-    public static final ConfigKey<Boolean> INCLUDE_HOMELESS_ENTITIES = ConfigKeys.newBooleanConfigKey("geodns.includeHomeless", "Whether to include entities whose geo-coordinates cannot be inferred", false);
-    public static final ConfigKey<Boolean> USE_HOSTNAMES = ConfigKeys.newBooleanConfigKey("geodns.useHostnames", "Whether to use the hostname for the returned value for routing, rather than IP address (defaults to true)", true);
+    ConfigKey<Boolean> INCLUDE_HOMELESS_ENTITIES = ConfigKeys.newBooleanConfigKey(
+            "geodns.includeHomeless", "Whether to include entities whose geo-coordinates cannot be inferred", false);
+
+    ConfigKey<Boolean> USE_HOSTNAMES = ConfigKeys.newBooleanConfigKey(
+            "geodns.useHostnames", "Whether to use the hostname for the returned value for routing, rather than IP address (defaults to true)", true);
     
-    public static final AttributeSensor<Lifecycle> SERVICE_STATE_ACTUAL = Attributes.SERVICE_STATE_ACTUAL;
-    public static final AttributeSensor<Boolean> SERVICE_UP = Startable.SERVICE_UP;
-    public static final AttributeSensor<String> HOSTNAME = Attributes.HOSTNAME;
-    public static final AttributeSensor<String> ADDRESS = Attributes.ADDRESS;
-    @SuppressWarnings("serial")
-    public static final AttributeSensor<Map<String,String>> TARGETS = new BasicAttributeSensor<Map<String,String>>(
-            new TypeToken<Map<String,String>>() {}, "geodns.targets", "Map of targets currently being managed (entity ID to URL)");
+    AttributeSensor<Lifecycle> SERVICE_STATE_ACTUAL = Attributes.SERVICE_STATE_ACTUAL;
+    AttributeSensor<Boolean> SERVICE_UP = Startable.SERVICE_UP;
+    AttributeSensor<String> HOSTNAME = Attributes.HOSTNAME;
+    AttributeSensor<String> ADDRESS = Attributes.ADDRESS;
+
+    AttributeSensor<Map<String,String>> TARGETS = Sensors.newSensor(new TypeToken<Map<String, String>>() {},
+            "geodns.targets", "Map of targets currently being managed (entity ID to URL)");
 
-    public void setServiceState(Lifecycle state);
+    void setServiceState(Lifecycle state);
     
     /** sets target to be a group whose *members* will be searched (non-Group items not supported) */
     // prior to 0.7.0 the API accepted non-group items, but did not handle them correctly
-    public void setTargetEntityProvider(final Group entityProvider);
+    void setTargetEntityProvider(final Group entityProvider);
     
     /** should return the hostname which this DNS service is configuring */
-    public String getHostname();
+    String getHostname();
     
-    public Map<Entity, HostGeoInfo> getTargetHosts();
+    Map<Entity, HostGeoInfo> getTargetHosts();
 }

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/c85c378f/software/webapp/src/main/java/org/apache/brooklyn/entity/dns/geoscaling/GeoscalingDnsService.java
----------------------------------------------------------------------
diff --git a/software/webapp/src/main/java/org/apache/brooklyn/entity/dns/geoscaling/GeoscalingDnsService.java b/software/webapp/src/main/java/org/apache/brooklyn/entity/dns/geoscaling/GeoscalingDnsService.java
index f421df7..f9e0e54 100644
--- a/software/webapp/src/main/java/org/apache/brooklyn/entity/dns/geoscaling/GeoscalingDnsService.java
+++ b/software/webapp/src/main/java/org/apache/brooklyn/entity/dns/geoscaling/GeoscalingDnsService.java
@@ -23,10 +23,9 @@ import java.net.URI;
 import org.apache.brooklyn.api.entity.ImplementedBy;
 import org.apache.brooklyn.api.sensor.AttributeSensor;
 import org.apache.brooklyn.config.ConfigKey;
-import org.apache.brooklyn.core.config.BasicConfigKey;
 import org.apache.brooklyn.core.config.ConfigKeys;
 import org.apache.brooklyn.core.entity.Attributes;
-import org.apache.brooklyn.core.sensor.BasicAttributeSensor;
+import org.apache.brooklyn.core.sensor.Sensors;
 import org.apache.brooklyn.entity.dns.AbstractGeoDnsService;
 import org.apache.brooklyn.entity.webapp.WebAppServiceConstants;
 import org.apache.brooklyn.util.core.flags.SetFromFlag;
@@ -35,36 +34,45 @@ import org.apache.brooklyn.util.core.flags.SetFromFlag;
 public interface GeoscalingDnsService extends AbstractGeoDnsService {
     
     @SetFromFlag("sslTrustAll")
-    public static final ConfigKey<Boolean> SSL_TRUST_ALL = ConfigKeys.newBooleanConfigKey(
+    ConfigKey<Boolean> SSL_TRUST_ALL = ConfigKeys.newBooleanConfigKey(
             "ssl.trustAll",
             "Whether to trust all certificates, or to fail with 'peer not authenticated' if untrusted (default false)",
             false);
+
     @SetFromFlag("randomizeSubdomainName")
-    public static final ConfigKey<Boolean> RANDOMIZE_SUBDOMAIN_NAME = new BasicConfigKey<Boolean>(
-            Boolean.class, "randomize.subdomain.name");
+    ConfigKey<Boolean> RANDOMIZE_SUBDOMAIN_NAME = ConfigKeys.newBooleanConfigKey(
+            "randomize.subdomain.name");
+
     @SetFromFlag("username")
-    public static final ConfigKey<String> GEOSCALING_USERNAME = new BasicConfigKey<String>(
-            String.class, "geoscaling.username");
+    ConfigKey<String> GEOSCALING_USERNAME = ConfigKeys.newStringConfigKey(
+            "geoscaling.username");
+
     @SetFromFlag("password")
-    public static final ConfigKey<String> GEOSCALING_PASSWORD = new BasicConfigKey<String>(
-            String.class, "geoscaling.password");
+    ConfigKey<String> GEOSCALING_PASSWORD = ConfigKeys.newStringConfigKey(
+            "geoscaling.password");
+
     @SetFromFlag("primaryDomainName")
-    public static final ConfigKey<String> GEOSCALING_PRIMARY_DOMAIN_NAME = new BasicConfigKey<String>(
-            String.class, "geoscaling.primary.domain.name");
+    ConfigKey<String> GEOSCALING_PRIMARY_DOMAIN_NAME = ConfigKeys.newStringConfigKey(
+            "geoscaling.primary.domain.name");
+
     @SetFromFlag("smartSubdomainName")
-    public static final ConfigKey<String> GEOSCALING_SMART_SUBDOMAIN_NAME = new BasicConfigKey<String>(
-            String.class, "geoscaling.smart.subdomain.name");
+    ConfigKey<String> GEOSCALING_SMART_SUBDOMAIN_NAME = ConfigKeys.newStringConfigKey(
+            "geoscaling.smart.subdomain.name");
     
-    public static final AttributeSensor<String> GEOSCALING_ACCOUNT = new BasicAttributeSensor<String>(
-            String.class, "geoscaling.account", "Active user account for the GeoScaling.com service");
-    public static final AttributeSensor<URI> MAIN_URI = Attributes.MAIN_URI;
-    public static final AttributeSensor<String> ROOT_URL = WebAppServiceConstants.ROOT_URL;
-    public static final AttributeSensor<String> MANAGED_DOMAIN = new BasicAttributeSensor<String>(
-            String.class, "geoscaling.managed.domain", "Fully qualified domain name that will be geo-redirected; " +
+    AttributeSensor<String> GEOSCALING_ACCOUNT = Sensors.newStringSensor(
+            "geoscaling.account", "Active user account for the GeoScaling.com service");
+
+    AttributeSensor<URI> MAIN_URI = Attributes.MAIN_URI;
+
+    AttributeSensor<String> ROOT_URL = WebAppServiceConstants.ROOT_URL;
+
+    AttributeSensor<String> MANAGED_DOMAIN = Sensors.newStringSensor(
+            "geoscaling.managed.domain",
+            "Fully qualified domain name that will be geo-redirected; " +
                     "this will be the same as "+ROOT_URL.getName()+" but the latter will only be set when the domain has active targets");
     
-    public void applyConfig();
+    void applyConfig();
     
     /** minimum/default TTL here is 300s = 5m */
-    public long getTimeToLiveSeconds();
+    long getTimeToLiveSeconds();
 }


[5/7] incubator-brooklyn git commit: GeoDns AWS behaviour note

Posted by he...@apache.org.
GeoDns AWS behaviour note


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

Branch: refs/heads/master
Commit: 88a6b86b121e9051fb6778c52855add463b1334d
Parents: cbcad7e
Author: Sam Corbett <sa...@cloudsoftcorp.com>
Authored: Wed Dec 9 16:53:17 2015 +0000
Committer: Sam Corbett <sa...@cloudsoftcorp.com>
Committed: Wed Dec 9 17:07:42 2015 +0000

----------------------------------------------------------------------
 .../brooklyn/entity/dns/geoscaling/GeoscalingDnsService.java | 8 ++++++++
 1 file changed, 8 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/88a6b86b/software/webapp/src/main/java/org/apache/brooklyn/entity/dns/geoscaling/GeoscalingDnsService.java
----------------------------------------------------------------------
diff --git a/software/webapp/src/main/java/org/apache/brooklyn/entity/dns/geoscaling/GeoscalingDnsService.java b/software/webapp/src/main/java/org/apache/brooklyn/entity/dns/geoscaling/GeoscalingDnsService.java
index f9e0e54..58fcca4 100644
--- a/software/webapp/src/main/java/org/apache/brooklyn/entity/dns/geoscaling/GeoscalingDnsService.java
+++ b/software/webapp/src/main/java/org/apache/brooklyn/entity/dns/geoscaling/GeoscalingDnsService.java
@@ -30,6 +30,14 @@ import org.apache.brooklyn.entity.dns.AbstractGeoDnsService;
 import org.apache.brooklyn.entity.webapp.WebAppServiceConstants;
 import org.apache.brooklyn.util.core.flags.SetFromFlag;
 
+/**
+ * A geo-DNS service using geoscaling.com.
+ * <p>
+ * AWS users should note that if the Brooklyn server managing this entity is in the same
+ * region as the server being geoscaled then they must set {@link #INCLUDE_HOMELESS_ENTITIES}
+ * to true, as IP lookups of the server will resolve the private address and it will be
+ * ignored by default.
+ */
 @ImplementedBy(GeoscalingDnsServiceImpl.class)
 public interface GeoscalingDnsService extends AbstractGeoDnsService {
     


[7/7] incubator-brooklyn git commit: This closes #1096

Posted by he...@apache.org.
This closes #1096


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

Branch: refs/heads/master
Commit: 3584f5bf98a1ab3f8cc31b9ee74b62529accc322
Parents: b0875f4 02c5d33
Author: Alex Heneveld <al...@cloudsoftcorp.com>
Authored: Thu Dec 17 12:32:05 2015 +0000
Committer: Alex Heneveld <al...@cloudsoftcorp.com>
Committed: Thu Dec 17 12:32:05 2015 +0000

----------------------------------------------------------------------
 parent/pom.xml                                  |   1 +
 .../entity/dns/AbstractGeoDnsService.java       |  47 ++++--
 .../entity/dns/AbstractGeoDnsServiceImpl.java   | 100 +++++++-----
 .../dns/geoscaling/GeoscalingDnsService.java    |  58 ++++---
 .../geoscaling/GeoscalingDnsServiceImpl.java    |  18 ++-
 .../entity/dns/AbstractGeoDnsServiceTest.java   | 153 +++++++++++--------
 .../geoscaling/GeoscalingIntegrationTest.java   |  62 ++++----
 .../dns/geoscaling/GeoscalingWebClientTest.java |  41 +++--
 .../camp/brooklyn/AbstractYamlTest.java         |  10 +-
 .../camp/brooklyn/GeoDnsServiceYamlTest.java    |  45 ++++++
 .../apache/brooklyn/camp/brooklyn/geodns.yaml   |  42 +++++
 11 files changed, 385 insertions(+), 192 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/3584f5bf/parent/pom.xml
----------------------------------------------------------------------


[6/7] incubator-brooklyn git commit: Include a version for the maven-jar-plugin

Posted by he...@apache.org.
Include a version for the maven-jar-plugin


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

Branch: refs/heads/master
Commit: 02c5d33618373fc5ebe891eb485eca084391c540
Parents: 88a6b86
Author: Sam Corbett <sa...@cloudsoftcorp.com>
Authored: Wed Dec 9 16:53:38 2015 +0000
Committer: Sam Corbett <sa...@cloudsoftcorp.com>
Committed: Wed Dec 9 17:07:42 2015 +0000

----------------------------------------------------------------------
 parent/pom.xml | 1 +
 1 file changed, 1 insertion(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/02c5d336/parent/pom.xml
----------------------------------------------------------------------
diff --git a/parent/pom.xml b/parent/pom.xml
index 481ef5f..ec63b77 100644
--- a/parent/pom.xml
+++ b/parent/pom.xml
@@ -1301,6 +1301,7 @@
                     <plugin>
                         <groupId>org.apache.maven.plugins</groupId>
                         <artifactId>maven-jar-plugin</artifactId>
+                        <version>2.6</version>
                         <configuration>
                             <archive>
                                 <manifestFile> ${project.build.outputDirectory}/META-INF/MANIFEST.MF </manifestFile>


[4/7] incubator-brooklyn git commit: GeoDns excludes entities that are not running by default

Posted by he...@apache.org.
GeoDns excludes entities that are not running by default

Can be disabled by setting AbstractGeoDnsService.FILTER_FOR_RUNNING
to false.


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

Branch: refs/heads/master
Commit: cbcad7e667a86498bca85bde366b24bfaac7f8ae
Parents: ecfca89
Author: Sam Corbett <sa...@cloudsoftcorp.com>
Authored: Tue Dec 8 18:28:13 2015 +0000
Committer: Sam Corbett <sa...@cloudsoftcorp.com>
Committed: Wed Dec 9 17:07:39 2015 +0000

----------------------------------------------------------------------
 .../entity/dns/AbstractGeoDnsService.java       |  5 ++
 .../entity/dns/AbstractGeoDnsServiceImpl.java   | 84 +++++++++++---------
 .../entity/dns/AbstractGeoDnsServiceTest.java   | 30 +++++++
 3 files changed, 83 insertions(+), 36 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/cbcad7e6/software/webapp/src/main/java/org/apache/brooklyn/entity/dns/AbstractGeoDnsService.java
----------------------------------------------------------------------
diff --git a/software/webapp/src/main/java/org/apache/brooklyn/entity/dns/AbstractGeoDnsService.java b/software/webapp/src/main/java/org/apache/brooklyn/entity/dns/AbstractGeoDnsService.java
index 0535f2c..6e55d5d 100644
--- a/software/webapp/src/main/java/org/apache/brooklyn/entity/dns/AbstractGeoDnsService.java
+++ b/software/webapp/src/main/java/org/apache/brooklyn/entity/dns/AbstractGeoDnsService.java
@@ -48,6 +48,11 @@ public interface AbstractGeoDnsService extends Entity {
     ConfigKey<Group> ENTITY_PROVIDER = ConfigKeys.newConfigKey(Group.class,
             "geodns.entityProvider", "The group whose members should be tracked");
 
+    /** @see Lifecycle#RUNNING */
+    @SetFromFlag("filterForRunning")
+    ConfigKey<Boolean> FILTER_FOR_RUNNING = ConfigKeys.newBooleanConfigKey(
+            "geodns.filterForRunning", "Whether to only track targets whose status is \"RUNNING\"", true);
+
     AttributeSensor<Lifecycle> SERVICE_STATE_ACTUAL = Attributes.SERVICE_STATE_ACTUAL;
     AttributeSensor<Boolean> SERVICE_UP = Startable.SERVICE_UP;
     AttributeSensor<String> HOSTNAME = Attributes.HOSTNAME;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/cbcad7e6/software/webapp/src/main/java/org/apache/brooklyn/entity/dns/AbstractGeoDnsServiceImpl.java
----------------------------------------------------------------------
diff --git a/software/webapp/src/main/java/org/apache/brooklyn/entity/dns/AbstractGeoDnsServiceImpl.java b/software/webapp/src/main/java/org/apache/brooklyn/entity/dns/AbstractGeoDnsServiceImpl.java
index e18d3e1..ca2caf7 100644
--- a/software/webapp/src/main/java/org/apache/brooklyn/entity/dns/AbstractGeoDnsServiceImpl.java
+++ b/software/webapp/src/main/java/org/apache/brooklyn/entity/dns/AbstractGeoDnsServiceImpl.java
@@ -36,6 +36,7 @@ import java.util.Set;
 import org.apache.brooklyn.api.entity.Entity;
 import org.apache.brooklyn.api.entity.Group;
 import org.apache.brooklyn.api.policy.PolicySpec;
+import org.apache.brooklyn.api.sensor.Sensor;
 import org.apache.brooklyn.core.entity.AbstractEntity;
 import org.apache.brooklyn.core.entity.Attributes;
 import org.apache.brooklyn.core.entity.lifecycle.Lifecycle;
@@ -64,9 +65,9 @@ public abstract class AbstractGeoDnsServiceImpl extends AbstractEntity implement
     @SetFromFlag
     protected Group targetEntityProvider;
     protected AbstractMembershipTrackingPolicy tracker;
-    
+
     protected Map<Entity, HostGeoInfo> targetHosts = Collections.synchronizedMap(new LinkedHashMap<Entity, HostGeoInfo>());
-    
+
     // We complain (at debug) when we encounter a target entity for whom we can't derive hostname/ip information; 
     // this is the commonest case for the transient condition between the time the entity is created and the time 
     // it is started (at which point the location is specified). This set contains those entities we've complained 
@@ -81,7 +82,7 @@ public abstract class AbstractGeoDnsServiceImpl extends AbstractEntity implement
     public AbstractGeoDnsServiceImpl() {
         super();
     }
-    
+
     @Override
     public void init() {
         super.init();
@@ -95,12 +96,13 @@ public abstract class AbstractGeoDnsServiceImpl extends AbstractEntity implement
     public Map<Entity, HostGeoInfo> getTargetHosts() {
         return targetHosts;
     }
-    
+
     @Override
     public void onManagementBecomingMaster() {
         super.onManagementBecomingMaster();
         startTracker();
     }
+
     @Override
     public void onManagementNoLongerMaster() {
         endTracker();
@@ -112,7 +114,7 @@ public abstract class AbstractGeoDnsServiceImpl extends AbstractEntity implement
         setServiceState(Lifecycle.DESTROYED);
         super.destroy();
     }
-        
+
     @Override
     public void setServiceState(Lifecycle state) {
         sensors().set(HOSTNAME, getHostname());
@@ -122,36 +124,43 @@ public abstract class AbstractGeoDnsServiceImpl extends AbstractEntity implement
         else
             ServiceNotUpLogic.updateNotUpIndicator(this, SERVICE_STATE_ACTUAL, "Not in RUNNING state");
     }
-    
+
     @Override
     public void setTargetEntityProvider(final Group entityProvider) {
         this.targetEntityProvider = checkNotNull(entityProvider, "targetEntityProvider");
         startTracker();
     }
-    
+
     /** should set up so these hosts are targeted, and setServiceState appropriately */
     protected abstract void reconfigureService(Collection<HostGeoInfo> targetHosts);
-    
+
     protected synchronized void startTracker() {
         if (targetEntityProvider==null || !getManagementSupport().isDeployed()) {
             log.debug("Tracker for "+this+" not yet active: "+targetEntityProvider+" / "+getManagementContext());
             return;
         }
         endTracker();
+
+        ImmutableSet.Builder<Sensor<?>> sensorsToTrack = ImmutableSet.<Sensor<?>>builder().add(
+                HOSTNAME, ADDRESS, Attributes.MAIN_URI, WebAppService.ROOT_URL);
+        // Don't subscribe to lifecycle events if entities will be included regardless of their status.
+        if (Boolean.TRUE.equals(config().get(FILTER_FOR_RUNNING))) {
+            sensorsToTrack.add(Attributes.SERVICE_STATE_ACTUAL);
+        }
         log.debug("Initializing tracker for "+this+", following "+targetEntityProvider);
         tracker = policies().add(PolicySpec.create(MemberTrackingPolicy.class)
                 .displayName("GeoDNS targets tracker")
-                .configure("sensorsToTrack", ImmutableSet.of(HOSTNAME, ADDRESS, Attributes.MAIN_URI, WebAppService.ROOT_URL))
-                .configure("group", targetEntityProvider));
+                .configure(AbstractMembershipTrackingPolicy.SENSORS_TO_TRACK, sensorsToTrack.build())
+                .configure(AbstractMembershipTrackingPolicy.GROUP, targetEntityProvider));
         refreshGroupMembership();
     }
-    
+
     protected synchronized void endTracker() {
         if (tracker == null || targetEntityProvider==null) return;
         policies().remove(tracker);
         tracker = null;
     }
-    
+
     public static class MemberTrackingPolicy extends AbstractMembershipTrackingPolicy {
         @Override
         protected void onEntityEvent(EventType type, Entity entity) {
@@ -161,9 +170,9 @@ public abstract class AbstractGeoDnsServiceImpl extends AbstractEntity implement
 
     @Override
     public abstract String getHostname();
-    
+
     long lastUpdate = -1;
-    
+
     // TODO: remove group member polling once locations can be determined via subscriptions
     protected void refreshGroupMembership() {
         try {
@@ -174,18 +183,21 @@ public abstract class AbstractGeoDnsServiceImpl extends AbstractEntity implement
                 ((DynamicGroup) targetEntityProvider).rescanEntities();
             Set<Entity> pool = MutableSet.copyOf(targetEntityProvider instanceof Group ? ((Group)targetEntityProvider).getMembers(): targetEntityProvider.getChildren());
             if (log.isDebugEnabled()) log.debug("GeoDns {} refreshing targets, pool now {}", this, pool);
-            
+
             boolean changed = false;
+            boolean filterForRunning = Boolean.TRUE.equals(config().get(FILTER_FOR_RUNNING));
             Set<Entity> previousOnes = MutableSet.copyOf(targetHosts.keySet());
             for (Entity e: pool) {
-                previousOnes.remove(e);
-                changed |= addTargetHost(e);
+                if (!filterForRunning || Lifecycle.RUNNING.equals(e.sensors().get(Attributes.SERVICE_STATE_ACTUAL))) {
+                    previousOnes.remove(e);
+                    changed |= addTargetHost(e);
+                }
             }
             // anything left in previousOnes is no longer applicable
             for (Entity e: previousOnes) {
                 changed |= removeTargetHost(e, false);
             }
-            
+
             // do a periodic full update hourly once we are active (the latter is probably not needed)
             if (changed || (lastUpdate > 0 && Time.hasElapsedSince(lastUpdate, Duration.ONE_HOUR))) {
                 update();
@@ -194,7 +206,7 @@ public abstract class AbstractGeoDnsServiceImpl extends AbstractEntity implement
             log.error("Problem refreshing group membership: "+e, e);
         }
     }
-    
+
     /**
      * Adds this host, if it is absent or if its hostname has changed.
      * <p>
@@ -213,7 +225,7 @@ public abstract class AbstractGeoDnsServiceImpl extends AbstractEntity implement
             String hostname = inferHostname(entity);
             String ip = inferIp(entity);
             String addr = (getConfig(USE_HOSTNAMES) || ip == null) ? hostname : ip;
-            
+
             if (addr==null) addr = ip;
             if (addr == null) {
                 if (entitiesWithoutHostname.add(entity)) {
@@ -221,12 +233,12 @@ public abstract class AbstractGeoDnsServiceImpl extends AbstractEntity implement
                 }
                 return false;
             }
-            
+
             // prefer the geo from the entity (or location parent), but fall back to inferring
             // e.g. if it supplies a URL
             HostGeoInfo geo = HostGeoInfo.fromEntity(entity);
             if (geo==null) geo = inferHostGeoInfo(hostname, ip);
-            
+
             if (Networking.isPrivateSubnet(addr) && ip!=null && !Networking.isPrivateSubnet(ip)) {
                 // fix for #1216
                 log.debug("GeoDns using IP "+ip+" for "+entity+" as addr "+addr+" resolves to private subnet");
@@ -263,12 +275,12 @@ public abstract class AbstractGeoDnsServiceImpl extends AbstractEntity implement
                 // if the location provider did not have an address, create a new one with it
                 geo = HostGeoInfo.create(addr, geo.displayName, geo.latitude, geo.longitude);
             }
-            
+
             // If we already knew about it, and it hasn't changed, then nothing to do
             if (oldGeo != null && geo.getAddress().equals(oldGeo.getAddress())) {
                 return false;
             }
-            
+
             entitiesWithoutHostname.remove(entity);
             entitiesWithoutGeoInfo.remove(entity);
             log.info("GeoDns adding "+entity+" at "+geo+(oldGeo != null ? " (previously "+oldGeo+")" : ""));
@@ -290,32 +302,32 @@ public abstract class AbstractGeoDnsServiceImpl extends AbstractEntity implement
         }
         return false;
     }
-    
+
     protected void update() {
         lastUpdate = System.currentTimeMillis();
-        
+
         Map<Entity, HostGeoInfo> m;
         synchronized(targetHosts) { m = ImmutableMap.copyOf(targetHosts); }
         if (log.isDebugEnabled()) log.debug("Full update of "+this+" ("+m.size()+" target hosts)");
-        
+
         Map<String,String> entityIdToAddress = Maps.newLinkedHashMap();
         for (Map.Entry<Entity, HostGeoInfo> entry : m.entrySet()) {
             entityIdToAddress.put(entry.getKey().getId(), entry.getValue().address);
         }
-        
+
         reconfigureService(new LinkedHashSet<HostGeoInfo>(m.values()));
-        
+
         if (log.isDebugEnabled()) log.debug("Targets being set as "+entityIdToAddress);
         sensors().set(TARGETS, entityIdToAddress);
     }
-    
+
     protected String inferHostname(Entity entity) {
         String hostname = entity.getAttribute(Attributes.HOSTNAME);
         URI url = entity.getAttribute(Attributes.MAIN_URI);
         if (url!=null) {
             try {
                 URL u = url.toURL();
-                
+
                 String hostname2 = u.getHost(); 
                 if (hostname==null) {
                     if (!entitiesWithoutGeoInfo.contains(entity))  //don't log repeatedly
@@ -325,23 +337,23 @@ public abstract class AbstractGeoDnsServiceImpl extends AbstractEntity implement
                     if (!entitiesWithoutGeoInfo.contains(entity))  //don't log repeatedly
                         log.warn("GeoDns "+this+" URL {} of "+entity+" does not match advertised HOSTNAME {}; using hostname, not URL", url, hostname);
                 }
-                
+
                 if (u.getPort() > 0 && u.getPort() != 80 && u.getPort() != 443) {
                     if (!entitiesWithoutGeoInfo.contains(entity))  //don't log repeatedly
                         log.warn("GeoDns "+this+" detected non-standard port in URL {} for {}; forwarding may not work", url, entity);
                 }
-                
+
             } catch (MalformedURLException e) {
                 log.warn("Invalid URL {} for entity {} in {}", new Object[] {url, entity, this});
             }
         }
         return hostname;
     }
-    
+
     protected String inferIp(Entity entity) {
         return entity.getAttribute(Attributes.ADDRESS);
     }
-    
+
     protected HostGeoInfo inferHostGeoInfo(String hostname, String ip) throws UnknownHostException {
         HostGeoInfo geoH = null;
         if (hostname != null) {
@@ -374,7 +386,7 @@ public abstract class AbstractGeoDnsServiceImpl extends AbstractEntity implement
         } else {
             if (log.isTraceEnabled()) log.trace("GeoDns inferred GeoInfo {} from hostname {}", geoH, hostname);
         }
-        
+
         return geoH;
     }
 }

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/cbcad7e6/software/webapp/src/test/java/org/apache/brooklyn/entity/dns/AbstractGeoDnsServiceTest.java
----------------------------------------------------------------------
diff --git a/software/webapp/src/test/java/org/apache/brooklyn/entity/dns/AbstractGeoDnsServiceTest.java b/software/webapp/src/test/java/org/apache/brooklyn/entity/dns/AbstractGeoDnsServiceTest.java
index 2048680..a9ff180 100644
--- a/software/webapp/src/test/java/org/apache/brooklyn/entity/dns/AbstractGeoDnsServiceTest.java
+++ b/software/webapp/src/test/java/org/apache/brooklyn/entity/dns/AbstractGeoDnsServiceTest.java
@@ -18,6 +18,8 @@
  */
 package org.apache.brooklyn.entity.dns;
 
+import static org.apache.brooklyn.core.entity.EntityAsserts.assertAttributeEqualsContinually;
+import static org.apache.brooklyn.core.entity.EntityAsserts.assertAttributeEventually;
 import static org.testng.Assert.assertFalse;
 import static org.testng.Assert.assertTrue;
 
@@ -36,7 +38,9 @@ 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.entity.Attributes;
+import org.apache.brooklyn.core.entity.Entities;
 import org.apache.brooklyn.core.entity.EntityAsserts;
+import org.apache.brooklyn.core.entity.lifecycle.Lifecycle;
 import org.apache.brooklyn.core.location.BasicLocationRegistry;
 import org.apache.brooklyn.core.location.LocationConfigKeys;
 import org.apache.brooklyn.core.location.Locations;
@@ -249,6 +253,32 @@ public class AbstractGeoDnsServiceTest extends BrooklynAppUnitTestSupport {
         assertIsNotTarget("North child");
     }
 
+    @Test
+    public void testFiltersForRunningEntities() {
+        app.start(ImmutableList.of(westChildWithLocation, eastChildWithLocationAndWithPrivateHostname));
+        publishSensors(2, true, true, true);
+
+        TestEntity problemChild = Entities.descendants(app, TestEntity.class).iterator().next();
+        assertAttributeEventually(geoDns, AbstractGeoDnsService.TARGETS, CollectionFunctionals.<String>mapSizeEquals(2));
+        problemChild.sensors().set(Attributes.SERVICE_STATE_ACTUAL, Lifecycle.ON_FIRE);
+        assertAttributeEventually(geoDns, AbstractGeoDnsService.TARGETS, CollectionFunctionals.<String>mapSizeEquals(1));
+        problemChild.sensors().set(Attributes.SERVICE_STATE_ACTUAL, Lifecycle.RUNNING);
+        assertAttributeEventually(geoDns, AbstractGeoDnsService.TARGETS, CollectionFunctionals.<String>mapSizeEquals(2));
+    }
+
+    @Test
+    public void testCanDisableFilterForRunningEntities() throws Exception {
+        geoDns.config().set(AbstractGeoDnsService.FILTER_FOR_RUNNING, false);
+        app.start(ImmutableList.of(westChildWithLocation, eastChildWithLocationAndWithPrivateHostname));
+        publishSensors(2, true, true, true);
+
+        assertAttributeEventually(geoDns, AbstractGeoDnsService.TARGETS, CollectionFunctionals.<String>mapSizeEquals(2));
+        final Map<String, String> targets = ImmutableMap.copyOf(geoDns.sensors().get(AbstractGeoDnsService.TARGETS));
+        TestEntity problemChild = Entities.descendants(app, TestEntity.class).iterator().next();
+        problemChild.sensors().set(Attributes.SERVICE_STATE_ACTUAL, Lifecycle.ON_FIRE);
+        assertAttributeEqualsContinually(geoDns, AbstractGeoDnsService.TARGETS, targets);
+    }
+
     private void assertIsTarget(String target) {
         assertTrue(geoDns.getTargetHostsByName().containsKey(target), "targets=" + geoDns.getTargetHostsByName());
     }


[2/7] incubator-brooklyn git commit: Simplify GeoDns tests

Posted by he...@apache.org.
Simplify GeoDns tests


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

Branch: refs/heads/master
Commit: 06a8f610a8b57860b7a7016328e02eb5375d7116
Parents: c85c378
Author: Sam Corbett <sa...@cloudsoftcorp.com>
Authored: Wed Dec 9 16:31:19 2015 +0000
Committer: Sam Corbett <sa...@cloudsoftcorp.com>
Committed: Wed Dec 9 16:55:12 2015 +0000

----------------------------------------------------------------------
 .../geoscaling/GeoscalingDnsServiceImpl.java    |  18 +--
 .../entity/dns/AbstractGeoDnsServiceTest.java   | 125 +++++++++----------
 .../geoscaling/GeoscalingIntegrationTest.java   |  62 +++++----
 .../dns/geoscaling/GeoscalingWebClientTest.java |  41 ++++--
 4 files changed, 136 insertions(+), 110 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/06a8f610/software/webapp/src/main/java/org/apache/brooklyn/entity/dns/geoscaling/GeoscalingDnsServiceImpl.java
----------------------------------------------------------------------
diff --git a/software/webapp/src/main/java/org/apache/brooklyn/entity/dns/geoscaling/GeoscalingDnsServiceImpl.java b/software/webapp/src/main/java/org/apache/brooklyn/entity/dns/geoscaling/GeoscalingDnsServiceImpl.java
index 4273dac..e04b8ec 100644
--- a/software/webapp/src/main/java/org/apache/brooklyn/entity/dns/geoscaling/GeoscalingDnsServiceImpl.java
+++ b/software/webapp/src/main/java/org/apache/brooklyn/entity/dns/geoscaling/GeoscalingDnsServiceImpl.java
@@ -61,9 +61,11 @@ public class GeoscalingDnsServiceImpl extends AbstractGeoDnsServiceImpl implemen
         super.init();
         
         // defaulting to randomized subdomains makes deploying multiple applications easier
-        if (getConfig(RANDOMIZE_SUBDOMAIN_NAME)==null) config().set(RANDOMIZE_SUBDOMAIN_NAME, true); 
-        
-        Boolean trustAll = getConfig(SSL_TRUST_ALL);
+        if (config().get(RANDOMIZE_SUBDOMAIN_NAME) == null) {
+            config().set(RANDOMIZE_SUBDOMAIN_NAME, true);
+        }
+
+        Boolean trustAll = config().get(SSL_TRUST_ALL);
         if (Boolean.TRUE.equals(trustAll)) {
             webClient = new GeoscalingWebClient(HttpTool.httpClientBuilder().trustAll().build());
         } else {
@@ -88,11 +90,11 @@ public class GeoscalingDnsServiceImpl extends AbstractGeoDnsServiceImpl implemen
     boolean isConfigured = false;
     
     public synchronized void applyConfig() {        
-        randomizeSmartSubdomainName = getConfig(RANDOMIZE_SUBDOMAIN_NAME);
-        username = getConfig(GEOSCALING_USERNAME);
-        password = getConfig(GEOSCALING_PASSWORD);
-        primaryDomainName = getConfig(GEOSCALING_PRIMARY_DOMAIN_NAME);
-        smartSubdomainName = getConfig(GEOSCALING_SMART_SUBDOMAIN_NAME);
+        randomizeSmartSubdomainName = config().get(RANDOMIZE_SUBDOMAIN_NAME);
+        username = config().get(GEOSCALING_USERNAME);
+        password = config().get(GEOSCALING_PASSWORD);
+        primaryDomainName = config().get(GEOSCALING_PRIMARY_DOMAIN_NAME);
+        smartSubdomainName = config().get(GEOSCALING_SMART_SUBDOMAIN_NAME);
 
         // Ensure all mandatory configuration is provided.
         checkNotNull(username, "The GeoScaling username is not specified");

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/06a8f610/software/webapp/src/test/java/org/apache/brooklyn/entity/dns/AbstractGeoDnsServiceTest.java
----------------------------------------------------------------------
diff --git a/software/webapp/src/test/java/org/apache/brooklyn/entity/dns/AbstractGeoDnsServiceTest.java b/software/webapp/src/test/java/org/apache/brooklyn/entity/dns/AbstractGeoDnsServiceTest.java
index 5ce2c1b..2048680 100644
--- a/software/webapp/src/test/java/org/apache/brooklyn/entity/dns/AbstractGeoDnsServiceTest.java
+++ b/software/webapp/src/test/java/org/apache/brooklyn/entity/dns/AbstractGeoDnsServiceTest.java
@@ -18,6 +18,7 @@
  */
 package org.apache.brooklyn.entity.dns;
 
+import static org.testng.Assert.assertFalse;
 import static org.testng.Assert.assertTrue;
 
 import java.util.Collection;
@@ -35,31 +36,23 @@ 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.entity.Attributes;
-import org.apache.brooklyn.core.entity.Entities;
-import org.apache.brooklyn.core.entity.EntityInternal;
-import org.apache.brooklyn.core.entity.factory.ApplicationBuilder;
+import org.apache.brooklyn.core.entity.EntityAsserts;
 import org.apache.brooklyn.core.location.BasicLocationRegistry;
 import org.apache.brooklyn.core.location.LocationConfigKeys;
 import org.apache.brooklyn.core.location.Locations;
 import org.apache.brooklyn.core.location.Machines;
 import org.apache.brooklyn.core.location.SimulatedLocation;
 import org.apache.brooklyn.core.location.geo.HostGeoInfo;
-import org.apache.brooklyn.core.mgmt.internal.LocalManagementContext;
-import org.apache.brooklyn.core.test.entity.TestApplication;
+import org.apache.brooklyn.core.test.BrooklynAppUnitTestSupport;
 import org.apache.brooklyn.core.test.entity.TestEntity;
-import org.apache.brooklyn.entity.dns.AbstractGeoDnsService;
-import org.apache.brooklyn.entity.dns.AbstractGeoDnsServiceImpl;
-import org.apache.brooklyn.entity.dns.AbstractGeoDnsServiceTest;
 import org.apache.brooklyn.entity.group.DynamicFabric;
 import org.apache.brooklyn.entity.group.DynamicGroup;
 import org.apache.brooklyn.entity.group.DynamicRegionsFabric;
-import org.apache.brooklyn.test.EntityTestUtils;
 import org.apache.brooklyn.util.collections.CollectionFunctionals;
 import org.apache.brooklyn.util.exceptions.Exceptions;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.testng.Assert;
-import org.testng.annotations.AfterMethod;
 import org.testng.annotations.BeforeMethod;
 import org.testng.annotations.Test;
 import org.apache.brooklyn.location.ssh.SshMachineLocation;
@@ -69,7 +62,8 @@ import com.google.common.collect.ImmutableList;
 import com.google.common.collect.ImmutableMap;
 import com.google.common.collect.Iterables;
 
-public class AbstractGeoDnsServiceTest {
+public class AbstractGeoDnsServiceTest extends BrooklynAppUnitTestSupport {
+
     public static final Logger log = LoggerFactory.getLogger(AbstractGeoDnsServiceTest.class);
 
     private static final String WEST_IP = "100.0.0.1";
@@ -80,8 +74,6 @@ public class AbstractGeoDnsServiceTest {
     private static final String NORTH_IP = "10.0.0.1";
     private static final double NORTH_LATITUDE = 60, NORTH_LONGITUDE = 0;
     
-    private ManagementContext managementContext;
-    
     private Location westParent;
     private Location westChild;
     private Location westChildWithLocation; 
@@ -92,16 +84,15 @@ public class AbstractGeoDnsServiceTest {
     private Location northParent;
     private Location northChildWithLocation; 
 
-    private TestApplication app;
     private DynamicRegionsFabric fabric;
     private DynamicGroup testEntities;
     private GeoDnsTestService geoDns;
     
-
+    @Override
     @BeforeMethod(alwaysRun=true)
-    public void setup() {
-        managementContext = new LocalManagementContext();
-        
+    public void setUp() throws Exception {
+        super.setUp();
+
         westParent = newSimulatedLocation("West parent", WEST_LATITUDE, WEST_LONGITUDE);
         
         // west uses public IP for name, so is always picked up
@@ -116,7 +107,7 @@ public class AbstractGeoDnsServiceTest {
         // north has a private IP and private hostname so should not be picked up when we turn off ADD_ANYTHING
         northParent = newSimulatedLocation("North parent", NORTH_LATITUDE, NORTH_LONGITUDE);
         northChildWithLocation = newSshMachineLocation("North child", "localhost", NORTH_IP, northParent, NORTH_LATITUDE, NORTH_LONGITUDE);
-        ((BasicLocationRegistry)managementContext.getLocationRegistry()).registerResolver(new LocationResolver() {
+        ((BasicLocationRegistry) mgmt.getLocationRegistry()).registerResolver(new LocationResolver() {
             @Override
             public Location newLocationFromString(Map locationFlags, String spec, LocationRegistry registry) {
                 if (!spec.equals("test:north")) throw new IllegalStateException("unsupported");
@@ -135,41 +126,36 @@ public class AbstractGeoDnsServiceTest {
             }
         });
 
-        Locations.manage(westParent, managementContext);
-        Locations.manage(eastParent, managementContext);
-        Locations.manage(northParent, managementContext);
+        Locations.manage(westParent, mgmt);
+        Locations.manage(eastParent, mgmt);
+        Locations.manage(northParent, mgmt);
         
-        app = ApplicationBuilder.newManagedApp(TestApplication.class, managementContext);
         fabric = app.createAndManageChild(EntitySpec.create(DynamicRegionsFabric.class)
             .configure(DynamicFabric.MEMBER_SPEC, EntitySpec.create(TestEntity.class)));
-        
+
         testEntities = app.createAndManageChild(EntitySpec.create(DynamicGroup.class)
             .configure(DynamicGroup.ENTITY_FILTER, Predicates.instanceOf(TestEntity.class)));
-        geoDns = app.createAndManageChild(EntitySpec.create(GeoDnsTestService.class));
-        geoDns.setTargetEntityProvider(testEntities);
-    }
 
-    @AfterMethod(alwaysRun=true)
-    public void tearDown() throws Exception {
-        if (app != null) Entities.destroyAll(app.getManagementContext());
+        geoDns = app.createAndManageChild(EntitySpec.create(GeoDnsTestService.class)
+            .configure(AbstractGeoDnsService.ENTITY_PROVIDER, testEntities));
     }
 
     private SimulatedLocation newSimulatedLocation(String name, double lat, double lon) {
-        return managementContext.getLocationManager().createLocation(LocationSpec.create(SimulatedLocation.class)
+        return mgmt.getLocationManager().createLocation(LocationSpec.create(SimulatedLocation.class)
                 .displayName(name)
                 .configure("latitude", lat)
                 .configure("longitude", lon));
     }
     
     private Location newSshMachineLocation(String name, String address, Location parent) {
-        return managementContext.getLocationManager().createLocation(LocationSpec.create(SshMachineLocation.class)
+        return mgmt.getLocationManager().createLocation(LocationSpec.create(SshMachineLocation.class)
                 .parent(parent)
                 .displayName(name)
                 .configure("address", address));
     }
     
     private Location newSshMachineLocation(String name, String hostname, String address, Location parent, double lat, double lon) {
-        return managementContext.getLocationManager().createLocation(LocationSpec.create(SshMachineLocation.class)
+        return mgmt.getLocationManager().createLocation(LocationSpec.create(SshMachineLocation.class)
                 .parent(parent)
                 .displayName(name)
                 .configure("hostname", hostname)
@@ -183,85 +169,92 @@ public class AbstractGeoDnsServiceTest {
         app.start( ImmutableList.of(westChildWithLocation, eastChildWithLocationAndWithPrivateHostname) );
         publishSensors(2, true, true, true);
         
-        EntityTestUtils.assertAttributeEventually(geoDns, AbstractGeoDnsService.TARGETS, CollectionFunctionals.<String>mapSizeEquals(2));
-        assertTrue(geoDns.getTargetHostsByName().containsKey("West child with location"), "targets="+geoDns.getTargetHostsByName());
-        assertTrue(geoDns.getTargetHostsByName().containsKey("East child with location"), "targets="+geoDns.getTargetHostsByName());
+        assertAttributeEventually(geoDns, AbstractGeoDnsService.TARGETS, CollectionFunctionals.<String>mapSizeEquals(2));
+        assertIsTarget("West child with location");
+        assertIsTarget("East child with location");
     }
-    
+
     @Test
     public void testGeoInfoOnParentLocation() {
         app.start( ImmutableList.of(westChild, eastChild) );
         publishSensors(2, true, false, false);
-        
-        EntityTestUtils.assertAttributeEventually(geoDns, AbstractGeoDnsService.TARGETS, CollectionFunctionals.<String>mapSizeEquals(2));
-        assertTrue(geoDns.getTargetHostsByName().containsKey("West child"), "targets="+geoDns.getTargetHostsByName());
-        assertTrue(geoDns.getTargetHostsByName().containsKey("East child"), "targets="+geoDns.getTargetHostsByName());
+
+        assertAttributeEventually(geoDns, AbstractGeoDnsService.TARGETS, CollectionFunctionals.<String>mapSizeEquals(2));
+        assertIsTarget("West child");
+        assertIsTarget("East child");
     }
 
     @Test
     public void testSubscribesToHostname() {
-        ((EntityInternal)geoDns).config().set(GeoDnsTestServiceImpl.ADD_ANYTHING, false);
+        geoDns.config().set(GeoDnsTestServiceImpl.ADD_ANYTHING, false);
         app.start( ImmutableList.of(westChild, eastChildWithLocationAndWithPrivateHostname) );
         Assert.assertEquals(geoDns.getTargetHostsByName().size(), 0);
         publishSensors(2, true, true, true);
-        
-        EntityTestUtils.assertAttributeEventually(geoDns, AbstractGeoDnsService.TARGETS, CollectionFunctionals.<String>mapSizeEquals(2));
+
+        assertAttributeEventually(geoDns, AbstractGeoDnsService.TARGETS, CollectionFunctionals.<String>mapSizeEquals(2));
         Assert.assertEquals(geoDns.getTargetHostsByName().size(), 2);
-        assertTrue(geoDns.getTargetHostsByName().containsKey("West child"), "targets="+geoDns.getTargetHostsByName());
-        assertTrue(geoDns.getTargetHostsByName().containsKey("East child with location"), "targets="+geoDns.getTargetHostsByName());
+        assertIsTarget("West child");
+        assertIsTarget("East child with location");
     }
 
     protected void publishSensors(int expectedSize, boolean includeServiceUp, boolean includeHostname, boolean includeAddress) {
         // First wait for the right size of group; the dynamic group gets notified asynchronously
         // of nodes added/removed, so if we don't wait then might not set value for all members.
-        EntityTestUtils.assertGroupSizeEqualsEventually(testEntities, expectedSize);
-        
+        EntityAsserts.assertGroupSizeEqualsEventually(testEntities, expectedSize);
+
         for (Entity e: testEntities.getMembers()) {
             if (includeServiceUp)
-                ((EntityInternal)e).sensors().set(Attributes.SERVICE_UP, true);
-            
+                e.sensors().set(Attributes.SERVICE_UP, true);
+
             SshMachineLocation l = Machines.findUniqueMachineLocation(e.getLocations(), SshMachineLocation.class).get();
             if (includeAddress)
-                ((EntityInternal)e).sensors().set(Attributes.ADDRESS, l.getAddress().getHostAddress());
+                e.sensors().set(Attributes.ADDRESS, l.getAddress().getHostAddress());
             String h = (String) l.config().getBag().getStringKey("hostname");
             if (h==null) h = l.getAddress().getHostName();
             if (includeHostname)
-                ((EntityInternal)e).sensors().set(Attributes.HOSTNAME, h);
+                e.sensors().set(Attributes.HOSTNAME, h);
         }
     }
-    
+
     @Test
     public void testChildAddedLate() {
         app.start( ImmutableList.of(westChild, eastChildWithLocationAndWithPrivateHostname) );
         publishSensors(2, true, false, false);
-        EntityTestUtils.assertAttributeEventually(geoDns, AbstractGeoDnsService.TARGETS, CollectionFunctionals.<String>mapSizeEquals(2));
-        
+        assertAttributeEventually(geoDns, AbstractGeoDnsService.TARGETS, CollectionFunctionals.<String>mapSizeEquals(2));
+
         String id3 = fabric.addRegion("test:north");
         publishSensors(3, true, false, false);
         try {
-            EntityTestUtils.assertAttributeEventually(geoDns, AbstractGeoDnsService.TARGETS, CollectionFunctionals.<String>mapSizeEquals(3));
+            assertAttributeEventually(geoDns, AbstractGeoDnsService.TARGETS, CollectionFunctionals.<String>mapSizeEquals(3));
         } catch (Throwable e) {
             log.warn("Did not pick up third entity, targets are "+geoDns.getAttribute(AbstractGeoDnsService.TARGETS)+" (rethrowing): "+e);
             Exceptions.propagate(e);
         }
-        assertTrue(geoDns.getTargetHostsByName().containsKey("North child"), "targets="+geoDns.getTargetHostsByName());
-        
-        log.info("targets: "+geoDns.getTargetHostsByName());
-    }    
+        assertIsTarget("North child");
 
+        log.info("targets: "+geoDns.getTargetHostsByName());
+    }
 
     @Test
     public void testFiltersEntirelyPrivate() {
-        ((EntityInternal)geoDns).config().set(GeoDnsTestServiceImpl.ADD_ANYTHING, false);
+        geoDns.config().set(GeoDnsTestServiceImpl.ADD_ANYTHING, false);
         app.start( ImmutableList.of(westChild, eastChildWithLocationAndWithPrivateHostname, northChildWithLocation) );
         Assert.assertEquals(geoDns.getTargetHostsByName().size(), 0);
         publishSensors(3, true, true, true);
-        
-        EntityTestUtils.assertAttributeEventually(geoDns, AbstractGeoDnsService.TARGETS, CollectionFunctionals.<String>mapSizeEquals(2));
+
+        assertAttributeEventually(geoDns, AbstractGeoDnsService.TARGETS, CollectionFunctionals.<String>mapSizeEquals(2));
         Assert.assertEquals(geoDns.getTargetHostsByName().size(), 2);
-        assertTrue(geoDns.getTargetHostsByName().containsKey("West child"), "targets="+geoDns.getTargetHostsByName());
-        assertTrue(geoDns.getTargetHostsByName().containsKey("East child with location"), "targets="+geoDns.getTargetHostsByName());
-        assertTrue(!geoDns.getTargetHostsByName().containsKey("North child"), "targets="+geoDns.getTargetHostsByName());
+        assertIsTarget("West child");
+        assertIsTarget("East child with location");
+        assertIsNotTarget("North child");
+    }
+
+    private void assertIsTarget(String target) {
+        assertTrue(geoDns.getTargetHostsByName().containsKey(target), "targets=" + geoDns.getTargetHostsByName());
+    }
+
+    private void assertIsNotTarget(String target) {
+        assertFalse(geoDns.getTargetHostsByName().containsKey(target), "targets=" + geoDns.getTargetHostsByName());
     }
 
     @ImplementedBy(GeoDnsTestServiceImpl.class)

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/06a8f610/software/webapp/src/test/java/org/apache/brooklyn/entity/dns/geoscaling/GeoscalingIntegrationTest.java
----------------------------------------------------------------------
diff --git a/software/webapp/src/test/java/org/apache/brooklyn/entity/dns/geoscaling/GeoscalingIntegrationTest.java b/software/webapp/src/test/java/org/apache/brooklyn/entity/dns/geoscaling/GeoscalingIntegrationTest.java
index f030987..75c6c2f 100644
--- a/software/webapp/src/test/java/org/apache/brooklyn/entity/dns/geoscaling/GeoscalingIntegrationTest.java
+++ b/software/webapp/src/test/java/org/apache/brooklyn/entity/dns/geoscaling/GeoscalingIntegrationTest.java
@@ -22,20 +22,19 @@ import static org.testng.Assert.assertEquals;
 
 import java.net.InetAddress;
 
-import org.apache.brooklyn.api.entity.EntityLocal;
 import org.apache.brooklyn.api.entity.EntitySpec;
 import org.apache.brooklyn.api.location.LocationSpec;
 import org.apache.brooklyn.api.mgmt.ManagementContext;
 import org.apache.brooklyn.core.entity.Attributes;
-import org.apache.brooklyn.core.entity.Entities;
+import org.apache.brooklyn.core.internal.BrooklynProperties;
 import org.apache.brooklyn.core.location.geo.HostGeoInfo;
 import org.apache.brooklyn.core.location.geo.HostGeoLookup;
 import org.apache.brooklyn.core.location.geo.MaxMind2HostGeoLookup;
 import org.apache.brooklyn.core.location.geo.UtraceHostGeoLookup;
-import org.apache.brooklyn.core.test.entity.TestApplication;
+import org.apache.brooklyn.core.mgmt.internal.ManagementContextInternal;
+import org.apache.brooklyn.core.test.BrooklynAppUnitTestSupport;
+import org.apache.brooklyn.core.test.entity.LocalManagementContextForTests;
 import org.apache.brooklyn.core.test.entity.TestEntity;
-import org.apache.brooklyn.entity.dns.geoscaling.GeoscalingDnsService;
-import org.apache.brooklyn.entity.dns.geoscaling.GeoscalingScriptGenerator;
 import org.apache.brooklyn.entity.group.DynamicGroup;
 import org.apache.brooklyn.test.Asserts;
 import org.apache.brooklyn.util.collections.MutableMap;
@@ -44,6 +43,7 @@ import org.apache.brooklyn.util.internal.BrooklynSystemProperties;
 import org.apache.brooklyn.util.net.Networking;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
+import org.testng.SkipException;
 import org.testng.annotations.AfterMethod;
 import org.testng.annotations.BeforeMethod;
 import org.testng.annotations.Test;
@@ -55,7 +55,7 @@ import com.google.common.collect.ImmutableList;
 /**
  * {@link GeoscalingScriptGenerator} unit tests.
  */
-public class GeoscalingIntegrationTest {
+public class GeoscalingIntegrationTest extends BrooklynAppUnitTestSupport {
 
     private static final Logger LOG = LoggerFactory.getLogger(GeoscalingIntegrationTest.class);
 
@@ -64,8 +64,6 @@ public class GeoscalingIntegrationTest {
     private final InetAddress addrWithGeo = Networking.getLocalHost();
     private final InetAddress addrWithoutGeo = Networking.getInetAddressWithFixedName(StubHostGeoLookup.HOMELESS_IP);
     
-    private ManagementContext mgmt;
-    private TestApplication app;
     private TestEntity target;
     private DynamicGroup group;
     private GeoscalingDnsService geoDns;
@@ -73,28 +71,35 @@ public class GeoscalingIntegrationTest {
 
     private SshMachineLocation locWithGeo;
     private SshMachineLocation locWithoutGeo;
-    
+
+    @Override
     @BeforeMethod(alwaysRun=true)
     public void setUp() throws Exception {
+        // Want to load username and password from user's properties.
+        mgmt = LocalManagementContextForTests.newInstance(BrooklynProperties.Factory.newDefault());
+        super.setUp();
+
         origGeoLookupImpl = BrooklynSystemProperties.HOST_GEO_LOOKUP_IMPL.getValue();
         HostGeoInfo.clearCachedLookup();
 
-        app = TestApplication.Factory.newManagedInstanceForTests();
-        mgmt = app.getManagementContext();
-        
         target = app.createAndManageChild(EntitySpec.create(TestEntity.class));
-        
         group = app.createAndManageChild(EntitySpec.create(DynamicGroup.class)
                 .configure(DynamicGroup.ENTITY_FILTER, Predicates.instanceOf(TestEntity.class)));
-        
+
+        String username = getBrooklynProperty(mgmt, "brooklyn.geoscaling.username");
+        String password = getBrooklynProperty(mgmt, "brooklyn.geoscaling.password");
+        if (username == null || password == null) {
+            throw new SkipException("Set brooklyn.geoscaling.username and brooklyn.geoscaling.password in brooklyn.properties to enable test");
+        }
+
         geoDns = app.createAndManageChild(EntitySpec.create(GeoscalingDnsService.class)
                 .displayName("Geo-DNS")
-                .configure("username", "cloudsoft")
-                .configure("password", "cl0uds0ft")
-                .configure("primaryDomainName", primaryDomain)
-                .configure("smartSubdomainName", subDomain)
-                .configure("targetEntityProvider", group));
-        
+                .configure(GeoscalingDnsService.GEOSCALING_USERNAME, username)
+                .configure(GeoscalingDnsService.GEOSCALING_PASSWORD, password)
+                .configure(GeoscalingDnsService.GEOSCALING_PRIMARY_DOMAIN_NAME, primaryDomain)
+                .configure(GeoscalingDnsService.GEOSCALING_SMART_SUBDOMAIN_NAME, subDomain)
+                .configure(GeoscalingDnsService.ENTITY_PROVIDER, group));
+
         locWithGeo = mgmt.getLocationManager().createLocation(LocationSpec.create(SshMachineLocation.class)
                 .configure("address", addrWithGeo)
                 .configure("name", "Edinburgh")
@@ -106,22 +111,27 @@ public class GeoscalingIntegrationTest {
                 .configure("address", addrWithoutGeo)
                 .configure("name", "Nowhere"));
     }
-    
+
+    @Override
     @AfterMethod(alwaysRun=true)
     public void tearDown() throws Exception {
+        super.tearDown();
         if (origGeoLookupImpl != null) {
             System.setProperty(BrooklynSystemProperties.HOST_GEO_LOOKUP_IMPL.getPropertyName(), origGeoLookupImpl);
         } else {
             System.clearProperty(BrooklynSystemProperties.HOST_GEO_LOOKUP_IMPL.getPropertyName());
         }
-        if (mgmt != null) Entities.destroyAll(mgmt);
         HostGeoInfo.clearCachedLookup();
     }
-    
+
+    private String getBrooklynProperty(ManagementContext mgmt, String property) {
+        return ((ManagementContextInternal) mgmt).getBrooklynProperties().getFirst(property);
+    }
+
     @Test(groups={"Integration"})
     public void testRoutesToExpectedLocation() {
         // Without this config, running on a home network (i.e. no public IP) the entity will have a private IP and will be ignored
-        ((EntityLocal)geoDns).config().set(GeoscalingDnsService.INCLUDE_HOMELESS_ENTITIES, true);
+        geoDns.config().set(GeoscalingDnsService.INCLUDE_HOMELESS_ENTITIES, true);
         
         target.sensors().set(Attributes.HOSTNAME,addrWithGeo.getHostName());
         
@@ -135,7 +145,7 @@ public class GeoscalingIntegrationTest {
     @Test(groups={"Integration"})
     public void testIgnoresAddressWithoutGeography() throws Exception {
         System.setProperty(BrooklynSystemProperties.HOST_GEO_LOOKUP_IMPL.getPropertyName(), StubHostGeoLookup.class.getName());
-        ((EntityLocal)geoDns).config().set(GeoscalingDnsService.INCLUDE_HOMELESS_ENTITIES, false); // false is default
+        geoDns.config().set(GeoscalingDnsService.INCLUDE_HOMELESS_ENTITIES, false); // false is default
         
         app.start(ImmutableList.of(locWithoutGeo));
         target.sensors().set(Attributes.HOSTNAME, StubHostGeoLookup.HOMELESS_IP);
@@ -152,7 +162,7 @@ public class GeoscalingIntegrationTest {
     @Test(groups={"Integration"})
     public void testIncludesAddressWithoutGeography() {
         System.setProperty(BrooklynSystemProperties.HOST_GEO_LOOKUP_IMPL.getPropertyName(), StubHostGeoLookup.class.getName());
-        ((EntityLocal)geoDns).config().set(GeoscalingDnsService.INCLUDE_HOMELESS_ENTITIES, true);
+        geoDns.config().set(GeoscalingDnsService.INCLUDE_HOMELESS_ENTITIES, true);
         
         app.start(ImmutableList.of(locWithoutGeo));
         target.sensors().set(Attributes.HOSTNAME, StubHostGeoLookup.HOMELESS_IP);

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/06a8f610/software/webapp/src/test/java/org/apache/brooklyn/entity/dns/geoscaling/GeoscalingWebClientTest.java
----------------------------------------------------------------------
diff --git a/software/webapp/src/test/java/org/apache/brooklyn/entity/dns/geoscaling/GeoscalingWebClientTest.java b/software/webapp/src/test/java/org/apache/brooklyn/entity/dns/geoscaling/GeoscalingWebClientTest.java
index d29ae5b..325cd81 100644
--- a/software/webapp/src/test/java/org/apache/brooklyn/entity/dns/geoscaling/GeoscalingWebClientTest.java
+++ b/software/webapp/src/test/java/org/apache/brooklyn/entity/dns/geoscaling/GeoscalingWebClientTest.java
@@ -26,11 +26,17 @@ import static org.apache.brooklyn.entity.dns.geoscaling.GeoscalingWebClient.PROV
 import static org.testng.Assert.assertNotNull;
 import static org.testng.Assert.assertNull;
 
+import org.apache.brooklyn.api.mgmt.ManagementContext;
+import org.apache.brooklyn.core.internal.BrooklynProperties;
+import org.apache.brooklyn.core.mgmt.internal.ManagementContextInternal;
+import org.apache.brooklyn.core.test.BrooklynMgmtUnitTestSupport;
+import org.apache.brooklyn.core.test.entity.LocalManagementContextForTests;
 import org.apache.brooklyn.entity.dns.geoscaling.GeoscalingWebClient.Domain;
 import org.apache.brooklyn.entity.dns.geoscaling.GeoscalingWebClient.SmartSubdomain;
 import org.apache.brooklyn.util.http.HttpTool;
 import org.apache.brooklyn.util.text.Strings;
 import org.apache.http.client.HttpClient;
+import org.testng.SkipException;
 import org.testng.annotations.AfterMethod;
 import org.testng.annotations.BeforeMethod;
 import org.testng.annotations.Test;
@@ -100,12 +106,9 @@ at org.apache.brooklyn.entity.dns.geoscaling.GeoscalingWebClient.login(Geoscalin
 ... 31 more
  */
 @Test(groups="Broken", enabled=false)
-public class GeoscalingWebClientTest {
+public class GeoscalingWebClientTest extends BrooklynMgmtUnitTestSupport {
     
     private final static String GEOSCALING_URL = "https://www.geoscaling.com";
-    private final static String USERNAME = "cloudsoft";
-    private final static String PASSWORD = "cl0uds0ft";
-    
     private final static String PRIMARY_DOMAIN = "domain-" + Strings.makeRandomId(5) + ".test.org";
     private final static String SUBDOMAIN = "subdomain-" + Strings.makeRandomId(5);
     
@@ -115,18 +118,29 @@ public class GeoscalingWebClientTest {
     
     private Domain domain;
     private SmartSubdomain smartSubdomain;
-    
-    @BeforeMethod(alwaysRun=true)
-    public void setUp() {
+
+    @Override
+    @BeforeMethod(alwaysRun = true)
+    public void setUp() throws Exception {
+        // Want to load username and password from user's properties.
+        mgmt = LocalManagementContextForTests.newInstance(BrooklynProperties.Factory.newDefault());
+
+        String username = getBrooklynProperty(mgmt, "brooklyn.geoscaling.username");
+        String password = getBrooklynProperty(mgmt, "brooklyn.geoscaling.password");
+        if (username == null || password == null) {
+            throw new SkipException("Set brooklyn.geoscaling.username and brooklyn.geoscaling.password in brooklyn.properties to enable test");
+        }
+
         // Insecurely use "trustAll" so that don't need to import signature into trust store
         // before test will work on jenkins machine.
         HttpClient httpClient = HttpTool.httpClientBuilder().uri(GEOSCALING_URL).trustAll().build();
         geoscaling = new GeoscalingWebClient(httpClient);
-        geoscaling.login(USERNAME, PASSWORD);
+        geoscaling.login(username, password);
+        super.setUp();
     }
     
     @AfterMethod(alwaysRun=true)
-    public void tearDown() {
+    public void tearDown() throws Exception {
         if (smartSubdomain != null)
             smartSubdomain.delete();
         
@@ -135,8 +149,15 @@ public class GeoscalingWebClientTest {
         
         if (geoscaling != null)
             geoscaling.logout();
+
+        super.tearDown();
+
     }
-    
+
+    private String getBrooklynProperty(ManagementContext mgmt, String property) {
+        return ((ManagementContextInternal) mgmt).getBrooklynProperties().getFirst(property);
+    }
+
     @Test(groups = "Integration")
     public void testSimpleNames() {
         testWebClient(PRIMARY_DOMAIN, SUBDOMAIN);


[3/7] incubator-brooklyn git commit: Group to be tracked by GeoDns can be set at entity creation

Posted by he...@apache.org.
Group to be tracked by GeoDns can be set at entity creation

Which means the service can be configured in YAML


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

Branch: refs/heads/master
Commit: ecfca898c9508ba3bd4d78f94d8176c4e1c4b5c8
Parents: 06a8f61
Author: Sam Corbett <sa...@cloudsoftcorp.com>
Authored: Wed Dec 9 16:34:42 2015 +0000
Committer: Sam Corbett <sa...@cloudsoftcorp.com>
Committed: Wed Dec 9 16:55:57 2015 +0000

----------------------------------------------------------------------
 .../entity/dns/AbstractGeoDnsService.java       |  9 +++-
 .../entity/dns/AbstractGeoDnsServiceImpl.java   | 16 +++++--
 .../camp/brooklyn/AbstractYamlTest.java         | 10 ++---
 .../camp/brooklyn/GeoDnsServiceYamlTest.java    | 45 ++++++++++++++++++++
 .../apache/brooklyn/camp/brooklyn/geodns.yaml   | 42 ++++++++++++++++++
 5 files changed, 111 insertions(+), 11 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/ecfca898/software/webapp/src/main/java/org/apache/brooklyn/entity/dns/AbstractGeoDnsService.java
----------------------------------------------------------------------
diff --git a/software/webapp/src/main/java/org/apache/brooklyn/entity/dns/AbstractGeoDnsService.java b/software/webapp/src/main/java/org/apache/brooklyn/entity/dns/AbstractGeoDnsService.java
index 43c7b97..0535f2c 100644
--- a/software/webapp/src/main/java/org/apache/brooklyn/entity/dns/AbstractGeoDnsService.java
+++ b/software/webapp/src/main/java/org/apache/brooklyn/entity/dns/AbstractGeoDnsService.java
@@ -30,17 +30,24 @@ import org.apache.brooklyn.core.entity.lifecycle.Lifecycle;
 import org.apache.brooklyn.core.entity.trait.Startable;
 import org.apache.brooklyn.core.location.geo.HostGeoInfo;
 import org.apache.brooklyn.core.sensor.Sensors;
+import org.apache.brooklyn.util.core.flags.SetFromFlag;
 
 import com.google.common.reflect.TypeToken;
 
 public interface AbstractGeoDnsService extends Entity {
     
+    @SetFromFlag("includeHomelessEntities")
     ConfigKey<Boolean> INCLUDE_HOMELESS_ENTITIES = ConfigKeys.newBooleanConfigKey(
             "geodns.includeHomeless", "Whether to include entities whose geo-coordinates cannot be inferred", false);
 
+    @SetFromFlag("useHostnames")
     ConfigKey<Boolean> USE_HOSTNAMES = ConfigKeys.newBooleanConfigKey(
             "geodns.useHostnames", "Whether to use the hostname for the returned value for routing, rather than IP address (defaults to true)", true);
-    
+
+    @SetFromFlag("provider")
+    ConfigKey<Group> ENTITY_PROVIDER = ConfigKeys.newConfigKey(Group.class,
+            "geodns.entityProvider", "The group whose members should be tracked");
+
     AttributeSensor<Lifecycle> SERVICE_STATE_ACTUAL = Attributes.SERVICE_STATE_ACTUAL;
     AttributeSensor<Boolean> SERVICE_UP = Startable.SERVICE_UP;
     AttributeSensor<String> HOSTNAME = Attributes.HOSTNAME;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/ecfca898/software/webapp/src/main/java/org/apache/brooklyn/entity/dns/AbstractGeoDnsServiceImpl.java
----------------------------------------------------------------------
diff --git a/software/webapp/src/main/java/org/apache/brooklyn/entity/dns/AbstractGeoDnsServiceImpl.java b/software/webapp/src/main/java/org/apache/brooklyn/entity/dns/AbstractGeoDnsServiceImpl.java
index 729351a..e18d3e1 100644
--- a/software/webapp/src/main/java/org/apache/brooklyn/entity/dns/AbstractGeoDnsServiceImpl.java
+++ b/software/webapp/src/main/java/org/apache/brooklyn/entity/dns/AbstractGeoDnsServiceImpl.java
@@ -83,6 +83,15 @@ public abstract class AbstractGeoDnsServiceImpl extends AbstractEntity implement
     }
     
     @Override
+    public void init() {
+        super.init();
+        Group initialProvider = config().get(ENTITY_PROVIDER);
+        if (initialProvider != null) {
+            setTargetEntityProvider(initialProvider);
+        }
+    }
+
+    @Override
     public Map<Entity, HostGeoInfo> getTargetHosts() {
         return targetHosts;
     }
@@ -174,14 +183,13 @@ public abstract class AbstractGeoDnsServiceImpl extends AbstractEntity implement
             }
             // anything left in previousOnes is no longer applicable
             for (Entity e: previousOnes) {
-                changed = true;
-                removeTargetHost(e, false);
+                changed |= removeTargetHost(e, false);
             }
             
             // do a periodic full update hourly once we are active (the latter is probably not needed)
-            if (changed || (lastUpdate>0 && Time.hasElapsedSince(lastUpdate, Duration.ONE_HOUR)))
+            if (changed || (lastUpdate > 0 && Time.hasElapsedSince(lastUpdate, Duration.ONE_HOUR))) {
                 update();
-            
+            }
         } catch (Exception e) {
             log.error("Problem refreshing group membership: "+e, e);
         }

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/ecfca898/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/AbstractYamlTest.java
----------------------------------------------------------------------
diff --git a/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/AbstractYamlTest.java b/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/AbstractYamlTest.java
index 06dfaa3..909564c 100644
--- a/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/AbstractYamlTest.java
+++ b/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/AbstractYamlTest.java
@@ -110,13 +110,13 @@ public abstract class AbstractYamlTest {
         return createAndStartApplication(joinLines(multiLineYaml));
     }
     
-    protected Entity createAndStartApplication(String input) throws Exception {
-        return createAndStartApplication(new StringReader(input));
+    protected Entity createAndStartApplication(Reader input) throws Exception {
+        return createAndStartApplication(Streams.readFully(input));
     }
 
-    protected Entity createAndStartApplication(Reader input) throws Exception {
+    protected Entity createAndStartApplication(String input) throws Exception {
         EntitySpec<?> spec = 
-            mgmt().getTypeRegistry().createSpecFromPlan(CampTypePlanTransformer.FORMAT, Streams.readFully(input), RegisteredTypeLoadingContexts.spec(Application.class), EntitySpec.class);
+            mgmt().getTypeRegistry().createSpecFromPlan(CampTypePlanTransformer.FORMAT, input, RegisteredTypeLoadingContexts.spec(Application.class), EntitySpec.class);
         final Entity app = brooklynMgmt.getEntityManager().createEntity(spec);
         // start the app (happens automatically if we use camp to instantiate, but not if we use crate spec approach)
         app.invoke(Startable.START, MutableMap.<String,String>of()).get();
@@ -126,9 +126,7 @@ public abstract class AbstractYamlTest {
     protected Entity createStartWaitAndLogApplication(Reader input) throws Exception {
         Entity app = createAndStartApplication(input);
         waitForApplicationTasks(app);
-
         getLogger().info("App started: "+app);
-        
         return app;
     }
 

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/ecfca898/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/GeoDnsServiceYamlTest.java
----------------------------------------------------------------------
diff --git a/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/GeoDnsServiceYamlTest.java b/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/GeoDnsServiceYamlTest.java
new file mode 100644
index 0000000..3f41e8d
--- /dev/null
+++ b/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/GeoDnsServiceYamlTest.java
@@ -0,0 +1,45 @@
+/*
+ * 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.camp.brooklyn;
+
+import static org.testng.Assert.assertEquals;
+
+import org.apache.brooklyn.api.entity.Application;
+import org.apache.brooklyn.core.entity.Entities;
+import org.apache.brooklyn.core.mgmt.EntityManagementUtils;
+import org.apache.brooklyn.entity.dns.AbstractGeoDnsService;
+import org.apache.brooklyn.entity.dns.geoscaling.GeoscalingDnsService;
+import org.apache.brooklyn.entity.group.DynamicFabric;
+import org.apache.brooklyn.util.stream.Streams;
+import org.testng.annotations.Test;
+
+public class GeoDnsServiceYamlTest extends AbstractYamlTest {
+
+    @Test
+    public void testTargetGroupCanBeSetInYaml() throws Exception {
+        final String resourceName = "classpath:/" + getClass().getPackage().getName().replace('.', '/') + "/geodns.yaml";
+        final String blueprint = Streams.readFully(loadYaml(resourceName));
+        Application app = EntityManagementUtils.createUnstarted(mgmt(), blueprint);
+        GeoscalingDnsService geodns = Entities.descendants(app, GeoscalingDnsService.class).iterator().next();
+        DynamicFabric fabric = Entities.descendants(app, DynamicFabric.class).iterator().next();
+        assertEquals(geodns.config().get(AbstractGeoDnsService.ENTITY_PROVIDER), fabric);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/ecfca898/usage/camp/src/test/resources/org/apache/brooklyn/camp/brooklyn/geodns.yaml
----------------------------------------------------------------------
diff --git a/usage/camp/src/test/resources/org/apache/brooklyn/camp/brooklyn/geodns.yaml b/usage/camp/src/test/resources/org/apache/brooklyn/camp/brooklyn/geodns.yaml
new file mode 100644
index 0000000..3fdc7b7
--- /dev/null
+++ b/usage/camp/src/test/resources/org/apache/brooklyn/camp/brooklyn/geodns.yaml
@@ -0,0 +1,42 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#  http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+services:
+
+- name: Web cluster
+  type: org.apache.brooklyn.entity.group.DynamicRegionsFabric
+  id: web-fabric
+
+  # Location required but test should not do any provisioning.
+  locations:
+  - localhost
+
+  memberSpec:
+    $brooklyn:entitySpec:
+      type: org.apache.brooklyn.entity.webapp.ControlledDynamicWebAppCluster
+      brooklyn.config:
+        initialSize: 0
+
+- name: Geo DNS
+  type: org.apache.brooklyn.entity.dns.geoscaling.GeoscalingDnsService
+  brooklyn.config:
+    provider: $brooklyn:component("web-fabric")
+    username: madeUp
+    password: madeUp
+    primaryDomainName: example.com
+    smartSubdomainName: test