@Override
 public void init() {
   sensors().set(Attributes.HOSTNAME, "localhost");
   sensors()
       .set(
           UsesJmx.JMX_PORT,
           LocalhostMachineProvisioningLocation.obtainPort(
               PortRanges.fromString(
                   // just doing "40123+" was not enough to avoid collisions (on 40125),
                   // observed on jenkins, not sure why but
                   // maybe something else had a UDP connection we weren't detected,
                   // or the static lock our localhost uses was being bypassed;
                   // this should improve things (2016-01)
                   NetworkingTestUtils.randomPortAround(40000) + "+")));
   // only supports no-agent, at the moment
   config().set(UsesJmx.JMX_AGENT_MODE, JmxAgentModes.NONE);
   sensors().set(UsesJmx.RMI_REGISTRY_PORT, -1); // -1 means to use the JMX_PORT only
   ConfigToAttributes.apply(this, UsesJmx.JMX_CONTEXT);
 }
@Catalog(
    name = "Global Web Fabric",
    description = "Deploys a WAR to multiple clusters, showing how Brooklyn fabrics work",
    iconUrl = "classpath://brooklyn/demo/glossy-3d-blue-web-icon.png")
public class GlobalWebFabricExample extends AbstractApplication {

  public static final Logger log = LoggerFactory.getLogger(GlobalWebFabricExample.class);

  static final List<String> DEFAULT_LOCATIONS =
      ImmutableList.of("aws-ec2:eu-west-1", "aws-ec2:ap-southeast-1", "aws-ec2:us-west-1");

  public static final String DEFAULT_WAR_PATH =
      ResourceUtils.create(GlobalWebFabricExample.class)
          // take this war, from the classpath, or via maven if not on the classpath
          .firstAvailableUrl(
              "classpath://hello-world-webapp.war",
              BrooklynMavenArtifacts.localUrl(
                  "example", "brooklyn-example-hello-world-webapp", "war"))
          .or("classpath://hello-world-webapp.war");

  @CatalogConfig(label = "WAR (URL)", priority = 2)
  public static final ConfigKey<String> WAR_PATH =
      ConfigKeys.newConfigKey(
          "app.war", "URL to the application archive which should be deployed", DEFAULT_WAR_PATH);

  // load-balancer instances must run on some port to work with GeoDNS, port 80 to work without
  // special, so make that default
  // (but included here in case it runs on a different port on all machines, or use a range to work
  // with multiple localhosts)
  @CatalogConfig(label = "Proxy server HTTP port")
  public static final PortAttributeSensorAndConfigKey PROXY_HTTP_PORT =
      new PortAttributeSensorAndConfigKey(
          AbstractController.PROXY_HTTP_PORT, PortRanges.fromInteger(80));

  @Override
  public void initApp() {
    StringConfigMap config = getManagementContext().getConfig();

    GeoscalingDnsService geoDns =
        addChild(
            EntitySpec.create(GeoscalingDnsService.class)
                .displayName("GeoScaling DNS")
                .configure(
                    "username",
                    checkNotNull(config.getFirst("brooklyn.geoscaling.username"), "username"))
                .configure(
                    "password",
                    checkNotNull(config.getFirst("brooklyn.geoscaling.password"), "password"))
                .configure(
                    "primaryDomainName",
                    checkNotNull(
                        config.getFirst("brooklyn.geoscaling.primaryDomain"), "primaryDomain"))
                .configure("smartSubdomainName", "brooklyn"));

    DynamicRegionsFabric webFabric =
        addChild(
            EntitySpec.create(DynamicRegionsFabric.class)
                .displayName("Web Fabric")
                .configure(DynamicRegionsFabric.FACTORY, new ElasticJavaWebAppService.Factory())

                // specify the WAR file to use
                .configure(
                    JavaWebAppService.ROOT_WAR, Entities.getRequiredUrlConfig(this, WAR_PATH)));

    // tell GeoDNS what to monitor
    geoDns.setTargetEntityProvider(webFabric);
  }

  public static void main(String[] argv) {
    List<String> args = Lists.newArrayList(argv);
    String port = CommandLineUtil.getCommandLineOption(args, "--port", "8081+");
    String locations =
        CommandLineUtil.getCommandLineOption(
            args, "--locations", Joiner.on(",").join(DEFAULT_LOCATIONS));

    BrooklynLauncher launcher =
        BrooklynLauncher.newInstance()
            .application(
                EntitySpec.create(StartableApplication.class, GlobalWebFabricExample.class)
                    .displayName("Brooklyn Global Web Fabric Example"))
            .webconsolePort(port)
            .locations(Arrays.asList(locations))
            .start();

    Entities.dumpInfo(launcher.getApplications());
  }
}