geo-dns: update member list of entity.hostname changes - Useful for some private subnet examples, where the hostname/url gets transformed. - Transforms tests from groovy to Java.
Project: http://git-wip-us.apache.org/repos/asf/brooklyn-library/repo Commit: http://git-wip-us.apache.org/repos/asf/brooklyn-library/commit/8d1b5d2b Tree: http://git-wip-us.apache.org/repos/asf/brooklyn-library/tree/8d1b5d2b Diff: http://git-wip-us.apache.org/repos/asf/brooklyn-library/diff/8d1b5d2b Branch: refs/heads/0.5.0 Commit: 8d1b5d2b8e40a882f9f396ae9f4673ee1a30150b Parents: 387cc27 Author: Aled Sage <[email protected]> Authored: Wed Apr 17 14:38:04 2013 +0100 Committer: Aled Sage <[email protected]> Committed: Thu Apr 25 11:18:21 2013 +0100 ---------------------------------------------------------------------- .../entity/dns/AbstractGeoDnsServiceImpl.java | 78 +++++---- .../entity/dns/AbstractGeoDnsServiceTest.groovy | 152 ----------------- .../entity/dns/AbstractGeoDnsServiceTest.java | 166 +++++++++++++++++++ .../geoscaling/GeoscalingIntegrationTest.groovy | 67 -------- .../geoscaling/GeoscalingIntegrationTest.java | 86 ++++++++++ 5 files changed, 301 insertions(+), 248 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/brooklyn-library/blob/8d1b5d2b/software/webapp/src/main/java/brooklyn/entity/dns/AbstractGeoDnsServiceImpl.java ---------------------------------------------------------------------- diff --git a/software/webapp/src/main/java/brooklyn/entity/dns/AbstractGeoDnsServiceImpl.java b/software/webapp/src/main/java/brooklyn/entity/dns/AbstractGeoDnsServiceImpl.java index 55be2c0..959c277 100644 --- a/software/webapp/src/main/java/brooklyn/entity/dns/AbstractGeoDnsServiceImpl.java +++ b/software/webapp/src/main/java/brooklyn/entity/dns/AbstractGeoDnsServiceImpl.java @@ -3,6 +3,7 @@ package brooklyn.entity.dns; import static com.google.common.base.Preconditions.checkNotNull; import java.net.InetAddress; +import java.net.MalformedURLException; import java.net.URL; import java.util.Collection; import java.util.Collections; @@ -154,8 +155,8 @@ public abstract class AbstractGeoDnsServiceImpl extends AbstractEntity implement boolean changed = false; Set<Entity> previousOnes = MutableSet.copyOf(targetHosts.keySet()); for (Entity e: pool) { - if (previousOnes.remove(e)) continue; - changed |= addTargetHost(e, false); + previousOnes.remove(e); + changed |= addTargetHost(e); } //anything left in previousOnes is no longer applicable for (Entity e: previousOnes) { @@ -171,44 +172,39 @@ public abstract class AbstractGeoDnsServiceImpl extends AbstractEntity implement } } - /** returns if host is added */ - protected boolean addTargetHost(Entity e, boolean doUpdate) { - if (targetHosts.containsKey(e)) { - log.warn("GeoDns ignoring already-added entity {}", e); - return false; - } - //add it if it is valid + /** + * Adds this host, if it is absent or if its hostname has changed. + * + * @return true if host is added or changed + */ + protected boolean addTargetHost(Entity e) { try { - String hostname = e.getAttribute(Attributes.HOSTNAME); - String url = e.getAttribute(WebAppService.ROOT_URL); - if (url!=null) { - URL u = new URL(url); - if (hostname==null) { - if (!entitiesWithoutGeoInfo.contains(e)) //don't log repeatedly - log.warn("GeoDns using URL {} to redirect to {} (HOSTNAME attribute is preferred, but not available)", url, e); - hostname = u.getHost(); - } - if (u.getPort() > 0 && u.getPort() != 80 && u.getPort() != 443) { - if (!entitiesWithoutGeoInfo.contains(e)) //don't log repeatedly - log.warn("GeoDns detected non-standard port in URL {} for {}; forwarding may not work", url, e); - } - } - if (hostname==null) { + HostGeoInfo oldGeo = targetHosts.get(e); + String hostname = inferHostname(e); + HostGeoInfo geoH = (hostname == null) ? null : HostGeoInfo.fromIpAddress(InetAddress.getByName(hostname)); + + if (hostname == null) { if (entitiesWithoutGeoInfo.add(e)) { log.debug("GeoDns ignoring {}, will continue scanning (no hostname or URL available)", e); } return false; } - HostGeoInfo geoH = HostGeoInfo.fromIpAddress(InetAddress.getByName(hostname)); + if (geoH == null) { if (entitiesWithoutGeoInfo.add(e)) { log.warn("GeoDns ignoring {} (no geography info available for {})", e, hostname); } return false; } + + // If we already knew about it, and it hasn't changed, then nothing to do + if (oldGeo != null && geoH.getAddress().equals(oldGeo.getAddress())) { + return false; + } + + // Check if location has lat/lon explicitly set; use geo-dns but warn if dramatically different HostGeoInfo geoE = HostGeoInfo.fromEntity(e); - if (geoE!=null) { - //geo info set for both; prefer H, but warn if they differ dramatially + if (geoE != null) { if ((Math.abs(geoH.latitude-geoE.latitude)>3) || (Math.abs(geoH.longitude-geoE.longitude)>3) ) { log.warn("GeoDns mismatch, {} is in {} but hosts URL in {}", new Object[] {e, geoE, geoH}); @@ -216,10 +212,10 @@ public abstract class AbstractGeoDnsServiceImpl extends AbstractEntity implement } entitiesWithoutGeoInfo.remove(e); - log.info("GeoDns adding "+e+" at "+geoH+(url!=null ? " (downstream listening on "+url+")" : "")); + log.info("GeoDns adding "+e+" at "+geoH+(oldGeo != null ? " (previously "+oldGeo+")" : "")); targetHosts.put(e, geoH); - if (doUpdate) update(); return true; + } catch (Exception ee) { log.warn("GeoDns ignoring {} (error analysing location, {}", e, ee); return false; @@ -250,4 +246,28 @@ public abstract class AbstractGeoDnsServiceImpl extends AbstractEntity implement setAttribute(TARGETS, entityIdToUrl); } + protected String inferHostname(Entity entity) { + String hostname = entity.getAttribute(Attributes.HOSTNAME); + String url = entity.getAttribute(WebAppService.ROOT_URL); + if (url!=null) { + try { + URL u = new URL(url); + + if (hostname==null) { + if (!entitiesWithoutGeoInfo.contains(entity)) //don't log repeatedly + log.warn("GeoDns using URL {} to redirect to {} (HOSTNAME attribute is preferred, but not available)", url, entity); + hostname = u.getHost(); + } + + if (u.getPort() > 0 && u.getPort() != 80 && u.getPort() != 443) { + if (!entitiesWithoutGeoInfo.contains(entity)) //don't log repeatedly + log.warn("GeoDns 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; + } } http://git-wip-us.apache.org/repos/asf/brooklyn-library/blob/8d1b5d2b/software/webapp/src/test/java/brooklyn/entity/dns/AbstractGeoDnsServiceTest.groovy ---------------------------------------------------------------------- diff --git a/software/webapp/src/test/java/brooklyn/entity/dns/AbstractGeoDnsServiceTest.groovy b/software/webapp/src/test/java/brooklyn/entity/dns/AbstractGeoDnsServiceTest.groovy deleted file mode 100644 index bba6b3b..0000000 --- a/software/webapp/src/test/java/brooklyn/entity/dns/AbstractGeoDnsServiceTest.groovy +++ /dev/null @@ -1,152 +0,0 @@ -package brooklyn.entity.dns; - -import static java.util.concurrent.TimeUnit.* -import static org.testng.Assert.* - -import java.util.concurrent.TimeUnit - -import org.slf4j.Logger -import org.slf4j.LoggerFactory -import org.testng.annotations.AfterMethod -import org.testng.annotations.BeforeMethod -import org.testng.annotations.Test - -import brooklyn.entity.Entity -import brooklyn.entity.basic.ApplicationBuilder -import brooklyn.entity.basic.DynamicGroup -import brooklyn.entity.basic.Entities -import brooklyn.entity.group.DynamicFabric -import brooklyn.entity.proxying.EntitySpecs -import brooklyn.location.Location -import brooklyn.location.basic.SimulatedLocation -import brooklyn.location.basic.SshMachineLocation -import brooklyn.location.geo.HostGeoInfo -import brooklyn.test.entity.TestApplication -import brooklyn.test.entity.TestEntity -import brooklyn.test.entity.TestEntityImpl -import brooklyn.util.internal.Repeater -import brooklyn.util.internal.TimeExtras - -import com.google.common.base.Predicates -import com.google.common.collect.Iterables - -public class AbstractGeoDnsServiceTest { - public static final Logger log = LoggerFactory.getLogger(AbstractGeoDnsServiceTest.class); - static { TimeExtras.init() } - - private static final String WEST_IP = "208.95.232.123"; - private static final String EAST_IP = "216.150.144.82"; - private static final double WEST_LATITUDE = 37.43472, WEST_LONGITUDE = -121.89500; - private static final double EAST_LATITUDE = 41.10361, EAST_LONGITUDE = -73.79583; - - private static final Location WEST_PARENT = new SimulatedLocation( - name: "West parent", latitude: WEST_LATITUDE, longitude: WEST_LONGITUDE); - private static final Location WEST_CHILD = new SshMachineLocation( - name: "West child", address: WEST_IP, parentLocation: WEST_PARENT); - private static final Location WEST_CHILD_WITH_LOCATION = new SshMachineLocation( - name: "West child with location", address: WEST_IP, parentLocation: WEST_PARENT, - latitude: WEST_LATITUDE, longitude: WEST_LONGITUDE); - - private static final Location EAST_PARENT = new SimulatedLocation( - name: "East parent", latitude: EAST_LATITUDE, longitude: EAST_LONGITUDE); - private static final Location EAST_CHILD = new SshMachineLocation( - name: "East child", address: EAST_IP, parentLocation: EAST_PARENT); - private static final Location EAST_CHILD_WITH_LOCATION = new SshMachineLocation( - name: "East child with location", address: EAST_IP, parentLocation: EAST_PARENT, - latitude: EAST_LATITUDE, longitude: EAST_LONGITUDE); - - private TestApplication app; - private DynamicFabric fabric; - private DynamicGroup testEntities; - private GeoDnsTestService geoDns; - - - @BeforeMethod(alwaysRun=true) - public void setup() { - app = ApplicationBuilder.newManagedApp(TestApplication.class); - fabric = app.createAndManageChild(EntitySpecs.spec(DynamicFabric.class) - .configure("factory", { properties -> new TestEntityImpl(properties) })); - - testEntities = app.createAndManageChild(EntitySpecs.spec(DynamicGroup.class) - .configure(DynamicGroup.ENTITY_FILTER, Predicates.instanceOf(TestEntity.class))); - geoDns = new GeoDnsTestService(app, polPeriod:10); - geoDns.setTargetEntityProvider(testEntities); - Entities.startManagement(geoDns); - } - - @AfterMethod(alwaysRun=true) - public void shutdown() { - if (app != null) Entities.destroy(app); - } - - - @Test - public void testGeoInfoOnLocation() { - app.start( [ WEST_CHILD_WITH_LOCATION, EAST_CHILD_WITH_LOCATION ] ); - - waitForTargetHosts(geoDns); - assertTrue(geoDns.targetHostsByName.containsKey("West child with location"), "targets="+geoDns.targetHostsByName); - assertTrue(geoDns.targetHostsByName.containsKey("East child with location"), "targets="+geoDns.targetHostsByName); - } - - @Test - public void testGeoInfoOnParentLocation() { - app.start( [ WEST_CHILD, EAST_CHILD ] ); - - waitForTargetHosts(geoDns); - assertTrue(geoDns.targetHostsByName.containsKey("West child"), "targets="+geoDns.targetHostsByName); - assertTrue(geoDns.targetHostsByName.containsKey("East child"), "targets="+geoDns.targetHostsByName); - } - - //TODO -// @Test -// public void testMissingGeoInfo() { -// } -// -// @Test -// public void testEmptyGroup() { -// } - - private static void waitForTargetHosts(GeoDnsTestService service) { - new Repeater("Wait for target hosts") - .repeat() - .every(500 * MILLISECONDS) - .until { service.targetHostsByName.size() == 2 } - .limitIterationsTo(20) - .run(); - } - - - private static class GeoDnsTestService extends AbstractGeoDnsServiceImpl { - public Map<String, HostGeoInfo> targetHostsByName = new LinkedHashMap<String, HostGeoInfo>(); - - public GeoDnsTestService(properties=[:], Entity parent) { - super(properties, parent); - } - - protected boolean addTargetHost(Entity e, boolean doUpdate) { - //ignore geo lookup, override parent menu - log.info("TestService adding target host $e"); - Location l = Iterables.getOnlyElement(e.locations); - HostGeoInfo geoInfo = new HostGeoInfo("127.0.0.1", l.name, - l.findLocationProperty("latitude"), l.findLocationProperty("longitude")); - targetHosts.put(e, geoInfo); - if (doUpdate) update(); - return true; - } - - @Override - protected void reconfigureService(Collection<HostGeoInfo> targetHosts) { - targetHostsByName.clear(); - for (HostGeoInfo host : targetHosts) { - if (host != null) targetHostsByName.put(host.displayName, host); - } - } - - @Override - public String getHostname() { - return "localhost"; - } - } - -} http://git-wip-us.apache.org/repos/asf/brooklyn-library/blob/8d1b5d2b/software/webapp/src/test/java/brooklyn/entity/dns/AbstractGeoDnsServiceTest.java ---------------------------------------------------------------------- diff --git a/software/webapp/src/test/java/brooklyn/entity/dns/AbstractGeoDnsServiceTest.java b/software/webapp/src/test/java/brooklyn/entity/dns/AbstractGeoDnsServiceTest.java new file mode 100644 index 0000000..b365a6a --- /dev/null +++ b/software/webapp/src/test/java/brooklyn/entity/dns/AbstractGeoDnsServiceTest.java @@ -0,0 +1,166 @@ +package brooklyn.entity.dns; + +import static org.testng.Assert.assertTrue; + +import java.util.Collection; +import java.util.LinkedHashMap; +import java.util.Map; +import java.util.concurrent.Callable; +import java.util.concurrent.TimeUnit; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.testng.annotations.AfterMethod; +import org.testng.annotations.BeforeMethod; +import org.testng.annotations.Test; + +import brooklyn.entity.Entity; +import brooklyn.entity.basic.ApplicationBuilder; +import brooklyn.entity.basic.DynamicGroup; +import brooklyn.entity.basic.Entities; +import brooklyn.entity.group.DynamicFabric; +import brooklyn.entity.proxying.EntitySpecs; +import brooklyn.location.Location; +import brooklyn.location.basic.SimulatedLocation; +import brooklyn.location.basic.SshMachineLocation; +import brooklyn.location.geo.HostGeoInfo; +import brooklyn.test.entity.TestApplication; +import brooklyn.test.entity.TestEntity; +import brooklyn.util.MutableMap; +import brooklyn.util.internal.Repeater; + +import com.google.common.base.Predicates; +import com.google.common.collect.ImmutableList; +import com.google.common.collect.Iterables; + +public class AbstractGeoDnsServiceTest { + public static final Logger log = LoggerFactory.getLogger(AbstractGeoDnsServiceTest.class); + + private static final String WEST_IP = "208.95.232.123"; + private static final String EAST_IP = "216.150.144.82"; + private static final double WEST_LATITUDE = 37.43472, WEST_LONGITUDE = -121.89500; + private static final double EAST_LATITUDE = 41.10361, EAST_LONGITUDE = -73.79583; + + private static SimulatedLocation newSimulatedLocation(String name, double lat, double lon) { + return new SimulatedLocation(MutableMap.of("name", name, "latitude", lat, "longitude", lon)); + } + + private static Location newSshMachineLocation(String name, String address, Location parent) { + return new SshMachineLocation(MutableMap.of("name", name, "address", address, "parentLocation", parent)); + } + + private static Location newSshMachineLocation(String name, String address, Location parent, double lat, double lon) { + return new SshMachineLocation(MutableMap.of("name", name, "address", address, "parentLocation", parent, "latitude", lat, "longitude", lon)); + } + + private static final Location WEST_PARENT = newSimulatedLocation("West parent", WEST_LATITUDE, WEST_LONGITUDE); + + private static final Location WEST_CHILD = newSshMachineLocation("West child", WEST_IP, WEST_PARENT); + private static final Location WEST_CHILD_WITH_LOCATION = newSshMachineLocation("West child with location", WEST_IP, WEST_PARENT, WEST_LATITUDE, WEST_LONGITUDE); + + private static final Location EAST_PARENT = newSimulatedLocation("East parent", EAST_LATITUDE, EAST_LONGITUDE); + private static final Location EAST_CHILD = newSshMachineLocation("East child", EAST_IP, EAST_PARENT); + private static final Location EAST_CHILD_WITH_LOCATION = newSshMachineLocation("East child with location", EAST_IP, EAST_PARENT, EAST_LATITUDE, EAST_LONGITUDE); + + private TestApplication app; + private DynamicFabric fabric; + private DynamicGroup testEntities; + private GeoDnsTestService geoDns; + + + @BeforeMethod(alwaysRun=true) + public void setup() { + app = ApplicationBuilder.newManagedApp(TestApplication.class); + fabric = app.createAndManageChild(EntitySpecs.spec(DynamicFabric.class) + .configure(DynamicFabric.MEMBER_SPEC, EntitySpecs.spec(TestEntity.class))); + + testEntities = app.createAndManageChild(EntitySpecs.spec(DynamicGroup.class) + .configure(DynamicGroup.ENTITY_FILTER, Predicates.instanceOf(TestEntity.class))); + geoDns = new GeoDnsTestService(MutableMap.of("pollPeriod", 10), app); + geoDns.setTargetEntityProvider(testEntities); + Entities.startManagement(geoDns); + } + + @AfterMethod(alwaysRun=true) + public void shutdown() { + if (app != null) Entities.destroy(app); + } + + + @Test + public void testGeoInfoOnLocation() { + app.start( ImmutableList.of(WEST_CHILD_WITH_LOCATION, EAST_CHILD_WITH_LOCATION) ); + + waitForTargetHosts(geoDns); + assertTrue(geoDns.targetHostsByName.containsKey("West child with location"), "targets="+geoDns.targetHostsByName); + assertTrue(geoDns.targetHostsByName.containsKey("East child with location"), "targets="+geoDns.targetHostsByName); + } + + @Test + public void testGeoInfoOnParentLocation() { + app.start( ImmutableList.of(WEST_CHILD, EAST_CHILD) ); + + waitForTargetHosts(geoDns); + assertTrue(geoDns.targetHostsByName.containsKey("West child"), "targets="+geoDns.targetHostsByName); + assertTrue(geoDns.targetHostsByName.containsKey("East child"), "targets="+geoDns.targetHostsByName); + } + + //TODO +// @Test +// public void testMissingGeoInfo() { +// } +// +// @Test +// public void testEmptyGroup() { +// } + + private static void waitForTargetHosts(final GeoDnsTestService service) { + new Repeater("Wait for target hosts") + .repeat() + .every(500, TimeUnit.MILLISECONDS) + .until(new Callable<Boolean>() { + public Boolean call() { + return service.targetHostsByName.size() == 2; + }}) + .limitIterationsTo(20) + .run(); + } + + + private static class GeoDnsTestService extends AbstractGeoDnsServiceImpl { + public Map<String, HostGeoInfo> targetHostsByName = new LinkedHashMap<String, HostGeoInfo>(); + + public GeoDnsTestService(Entity parent) { + super(MutableMap.of(), parent); + } + + public GeoDnsTestService(Map properties, Entity parent) { + super(properties, parent); + } + + @Override + protected boolean addTargetHost(Entity e) { + //ignore geo lookup, override parent menu + log.info("TestService adding target host $e"); + Location l = Iterables.getOnlyElement(e.getLocations()); + HostGeoInfo geoInfo = new HostGeoInfo("127.0.0.1", l.getName(), + (Double) l.findLocationProperty("latitude"), (Double) l.findLocationProperty("longitude")); + targetHosts.put(e, geoInfo); + return true; + } + + @Override + protected void reconfigureService(Collection<HostGeoInfo> targetHosts) { + targetHostsByName.clear(); + for (HostGeoInfo host : targetHosts) { + if (host != null) targetHostsByName.put(host.displayName, host); + } + } + + @Override + public String getHostname() { + return "localhost"; + } + } + +} http://git-wip-us.apache.org/repos/asf/brooklyn-library/blob/8d1b5d2b/software/webapp/src/test/java/brooklyn/entity/dns/geoscaling/GeoscalingIntegrationTest.groovy ---------------------------------------------------------------------- diff --git a/software/webapp/src/test/java/brooklyn/entity/dns/geoscaling/GeoscalingIntegrationTest.groovy b/software/webapp/src/test/java/brooklyn/entity/dns/geoscaling/GeoscalingIntegrationTest.groovy deleted file mode 100644 index bae975f..0000000 --- a/software/webapp/src/test/java/brooklyn/entity/dns/geoscaling/GeoscalingIntegrationTest.groovy +++ /dev/null @@ -1,67 +0,0 @@ -package brooklyn.entity.dns.geoscaling - -import static java.util.concurrent.TimeUnit.* -import static org.testng.Assert.* - -import org.testng.annotations.Test - -import brooklyn.entity.basic.ApplicationBuilder -import brooklyn.entity.basic.Attributes -import brooklyn.entity.basic.DynamicGroup -import brooklyn.entity.proxying.EntitySpecs -import brooklyn.location.basic.SshMachineLocation -import brooklyn.location.geo.HostGeoInfo -import brooklyn.test.entity.TestApplication -import brooklyn.test.entity.TestEntity -import brooklyn.util.internal.Repeater -import brooklyn.util.internal.TimeExtras - -import com.google.common.base.Predicates - -/** - * {@link GeoscalingScriptGenerator} unit tests. - */ -class GeoscalingIntegrationTest { - static { TimeExtras.init() } - - private final static Set<HostGeoInfo> HOSTS = [ - new HostGeoInfo("1.2.3.100", "Server 1", 40.0, -80.0), - new HostGeoInfo("1.2.3.101", "Server 2", 30.0, 20.0) - ] - - private final String primaryDomain = "geopaas.org"//"domain"+((int)(Math.random()*10000))+".test.org"; - private final String subDomain = "subdomain"+((int)(Math.random()*10000)); - private final InetAddress addr = InetAddress.localHost - private final SshMachineLocation loc = new SshMachineLocation(address:addr, name:'Edinburgh', latitude : 55.94944, longitude : -3.16028, iso3166 : ["GB-EDH"]) - - @Test(groups=["Integration"]) - public void testRoutesToExpectedLocation() { - TestApplication app = ApplicationBuilder.newManagedApp(TestApplication.class); - TestEntity target = app.createAndManageChild(EntitySpecs.spec(TestEntity.class)); - target.setAttribute(Attributes.HOSTNAME,addr.getHostName()) - - DynamicGroup group = app.createAndManageChild(EntitySpecs.spec(DynamicGroup.class) - .configure(DynamicGroup.ENTITY_FILTER, Predicates.instanceOf(TestEntity.class))); - - GeoscalingDnsService geoDns = app.createAndManageChild(EntitySpecs.spec(GeoscalingDnsService.class) - .displayName("Geo-DNS") - .configure("username", "cloudsoft") - .configure("password", "cl0uds0ft") - .configure("primaryDomainName", primaryDomain) - .configure("smartSubdomainName", subDomain) - .configure("targetEntityProvider", group)); - - app.start([loc]) - - println("geo-scaling test, using $subDomain.$primaryDomain; expect to be wired to $addr") - - new Repeater("Wait for target hosts") - .repeat() - .every(500 * MILLISECONDS) - .until { geoDns.getTargetHosts().size() == 1 } - .limitIterationsTo(20) - .run(); - - assertEquals(geoDns.getTargetHosts().size(), 1); - } -} http://git-wip-us.apache.org/repos/asf/brooklyn-library/blob/8d1b5d2b/software/webapp/src/test/java/brooklyn/entity/dns/geoscaling/GeoscalingIntegrationTest.java ---------------------------------------------------------------------- diff --git a/software/webapp/src/test/java/brooklyn/entity/dns/geoscaling/GeoscalingIntegrationTest.java b/software/webapp/src/test/java/brooklyn/entity/dns/geoscaling/GeoscalingIntegrationTest.java new file mode 100644 index 0000000..bfae0b5 --- /dev/null +++ b/software/webapp/src/test/java/brooklyn/entity/dns/geoscaling/GeoscalingIntegrationTest.java @@ -0,0 +1,86 @@ +package brooklyn.entity.dns.geoscaling; + +import static org.testng.Assert.assertEquals; + +import java.net.InetAddress; +import java.util.Set; +import java.util.concurrent.Callable; +import java.util.concurrent.TimeUnit; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.testng.annotations.Test; + +import brooklyn.entity.basic.ApplicationBuilder; +import brooklyn.entity.basic.Attributes; +import brooklyn.entity.basic.DynamicGroup; +import brooklyn.entity.proxying.EntitySpecs; +import brooklyn.location.basic.SshMachineLocation; +import brooklyn.location.geo.HostGeoInfo; +import brooklyn.test.entity.TestApplication; +import brooklyn.test.entity.TestEntity; +import brooklyn.util.MutableMap; +import brooklyn.util.NetworkUtils; +import brooklyn.util.internal.Repeater; + +import com.google.common.base.Predicates; +import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableSet; + +/** + * {@link GeoscalingScriptGenerator} unit tests. + */ +public class GeoscalingIntegrationTest { + + protected static final Logger LOG = LoggerFactory.getLogger(GeoscalingIntegrationTest.class); + + private final static Set<HostGeoInfo> HOSTS = ImmutableSet.of( + new HostGeoInfo("1.2.3.100", "Server 1", 40.0, -80.0), + new HostGeoInfo("1.2.3.101", "Server 2", 30.0, 20.0) + ); + + private final String primaryDomain = "geopaas.org";//"domain"+((int)(Math.random()*10000))+".test.org"; + private final String subDomain = "subdomain"+((int)(Math.random()*10000)); + private final InetAddress addr = NetworkUtils.getLocalHost(); + private final SshMachineLocation loc = new SshMachineLocation(MutableMap.builder() + .put("address", addr) + .put("name", "Edinburgh") + .put("latitude", 55.94944) + .put("longitude", -3.16028) + .put("iso3166", ImmutableList.of("GB-EDH")) + .build()); + + @Test(groups={"Integration"}) + public void testRoutesToExpectedLocation() { + TestApplication app = ApplicationBuilder.newManagedApp(TestApplication.class); + TestEntity target = app.createAndManageChild(EntitySpecs.spec(TestEntity.class)); + target.setAttribute(Attributes.HOSTNAME,addr.getHostName()); + + DynamicGroup group = app.createAndManageChild(EntitySpecs.spec(DynamicGroup.class) + .configure(DynamicGroup.ENTITY_FILTER, Predicates.instanceOf(TestEntity.class))); + + final GeoscalingDnsService geoDns = app.createAndManageChild(EntitySpecs.spec(GeoscalingDnsService.class) + .displayName("Geo-DNS") + .configure("username", "cloudsoft") + .configure("password", "cl0uds0ft") + .configure("primaryDomainName", primaryDomain) + .configure("smartSubdomainName", subDomain) + .configure("targetEntityProvider", group)); + + app.start(ImmutableList.of(loc)); + + LOG.info("geo-scaling test, using {}.{}; expect to be wired to {}", new Object[] {subDomain, primaryDomain, addr}); + + new Repeater("Wait for target hosts") + .repeat() + .every(500, TimeUnit.MILLISECONDS) + .until(new Callable<Boolean>() { + public Boolean call() { + return geoDns.getTargetHosts().size() == 1; + }}) + .limitIterationsTo(20) + .run(); + + assertEquals(geoDns.getTargetHosts().size(), 1); + } +}
