@AfterMethod(alwaysRun = true)
 @Override
 public void tearDown() throws Exception {
   for (WebAppMonitor monitor : webAppMonitors) {
     monitor.terminate();
   }
   if (executor != null) executor.shutdownNow();
   super.tearDown();
 }
  @Test(groups = "Integration")
  public void testRestoresSimpleApp() throws Exception {
    origApp.start(ImmutableList.of(origLoc));

    assertAppFunctional(origApp);

    String clusterUrl =
        checkNotNull(origApp.getAttribute(WebClusterDatabaseExampleApp.ROOT_URL), "cluster url");
    WebAppMonitor monitor = newWebAppMonitor(clusterUrl, 200);

    newApp = rebind(RebindOptions.create().terminateOrigManagementContext(true));
    assertAppFunctional(newApp);

    // expect no failures during rebind
    monitor.assertNoFailures("hitting nginx url");
    monitor.terminate();
  }
  private void assertAppFunctional(StartableApplication app) throws Exception {
    // expect standard config to (still) be set
    assertNotNull(app.getConfig(WebClusterDatabaseExampleApp.WAR_PATH));
    assertEquals(app.getConfig(WebClusterDatabaseExampleApp.USE_HTTPS), Boolean.FALSE);
    assertNotNull(app.getConfig(WebClusterDatabaseExampleApp.DB_SETUP_SQL_URL));

    // expect entities to be there
    MySqlNode mysql =
        (MySqlNode) Iterables.find(app.getChildren(), Predicates.instanceOf(MySqlNode.class));
    ControlledDynamicWebAppCluster web =
        (ControlledDynamicWebAppCluster)
            Iterables.find(
                app.getChildren(), Predicates.instanceOf(ControlledDynamicWebAppCluster.class));
    final NginxController nginx =
        (NginxController)
            Iterables.find(web.getChildren(), Predicates.instanceOf(NginxController.class));
    DynamicWebAppCluster webCluster =
        (DynamicWebAppCluster)
            Iterables.find(web.getChildren(), Predicates.instanceOf(DynamicWebAppCluster.class));
    Collection<Entity> appservers = web.getMembers();
    assertEquals(appservers.size(), 2);
    String clusterUrl =
        checkNotNull(app.getAttribute(WebClusterDatabaseExampleApp.ROOT_URL), "cluster url");
    String dbUrl = checkNotNull(mysql.getAttribute(MySqlNode.DATASTORE_URL), "database url");
    final String expectedJdbcUrl =
        String.format(
            "jdbc:%s%s?user=%s\\&password=%s",
            dbUrl,
            WebClusterDatabaseExampleApp.DB_TABLE,
            WebClusterDatabaseExampleApp.DB_USERNAME,
            WebClusterDatabaseExampleApp.DB_PASSWORD);

    // expect web-app to be reachable, and wired up to database
    HttpTestUtils.assertHttpStatusCodeEventuallyEquals(clusterUrl, 200);
    for (Entity appserver : appservers) {
      String appserverUrl =
          checkNotNull(
              appserver.getAttribute(JBoss7Server.ROOT_URL), "appserver url of " + appserver);

      HttpTestUtils.assertHttpStatusCodeEventuallyEquals(appserverUrl, 200);
      assertEquals(
          expectedJdbcUrl,
          appserver.getConfig(JavaEntityMethods.javaSysProp("brooklyn.example.db.url")),
          "of " + appserver);
    }

    WebAppMonitor monitor = newWebAppMonitor(clusterUrl, 200);

    // expect auto-scaler policy to be there, and to be functional (e.g. can trigger resize)
    AutoScalerPolicy autoScalerPolicy =
        (AutoScalerPolicy)
            Iterables.find(webCluster.getPolicies(), Predicates.instanceOf(AutoScalerPolicy.class));

    autoScalerPolicy.config().set(AutoScalerPolicy.MIN_POOL_SIZE, 3);
    EntityTestUtils.assertGroupSizeEqualsEventually(web, 3);
    final Collection<Entity> webMembersAfterGrow = web.getMembers();

    for (final Entity appserver : webMembersAfterGrow) {
      Asserts.succeedsEventually(
          MutableMap.of("timeout", Duration.TWO_MINUTES),
          new Runnable() {
            @Override
            public void run() {
              String appserverUrl =
                  checkNotNull(
                      appserver.getAttribute(JBoss7Server.ROOT_URL),
                      "appserver url of " + appserver);
              HttpTestUtils.assertHttpStatusCodeEquals(appserverUrl, 200);
              assertEquals(
                  expectedJdbcUrl,
                  appserver.getConfig(JavaEntityMethods.javaSysProp("brooklyn.example.db.url")),
                  "of " + appserver);
              Asserts.assertEqualsIgnoringOrder(
                  nginx.getAttribute(NginxController.SERVER_POOL_TARGETS).keySet(),
                  webMembersAfterGrow);
            }
          });
    }

    // expect enrichers to be there
    Iterables.find(web.getEnrichers(), Predicates.instanceOf(HttpLatencyDetector.class));
    Iterable<Enricher> propagatorEnrichers =
        Iterables.filter(web.getEnrichers(), Predicates.instanceOf(Propagator.class));
    assertEquals(
        Iterables.size(propagatorEnrichers), 2, "propagatorEnrichers=" + propagatorEnrichers);

    // Check we see evidence of the enrichers having an effect.
    // Relying on WebAppMonitor to stimulate activity.
    EntityTestUtils.assertAttributeEqualsEventually(
        app, WebClusterDatabaseExampleApp.APPSERVERS_COUNT, 3);
    EntityTestUtils.assertAttributeChangesEventually(
        web, DynamicWebAppCluster.REQUESTS_PER_SECOND_IN_WINDOW);
    EntityTestUtils.assertAttributeChangesEventually(
        app, DynamicWebAppCluster.REQUESTS_PER_SECOND_IN_WINDOW);
    EntityTestUtils.assertAttributeChangesEventually(
        web, HttpLatencyDetector.REQUEST_LATENCY_IN_SECONDS_MOST_RECENT);
    EntityTestUtils.assertAttributeChangesEventually(
        web, HttpLatencyDetector.REQUEST_LATENCY_IN_SECONDS_IN_WINDOW);

    // Restore the web-cluster to its original size of 2
    autoScalerPolicy.config().set(AutoScalerPolicy.MIN_POOL_SIZE, 2);
    EntityTestUtils.assertGroupSizeEqualsEventually(web, 2);

    final Entity removedAppserver =
        Iterables.getOnlyElement(
            Sets.difference(
                ImmutableSet.copyOf(webMembersAfterGrow), ImmutableSet.copyOf(web.getMembers())));
    Asserts.succeedsEventually(
        new Runnable() {
          @Override
          public void run() {
            assertFalse(Entities.isManaged(removedAppserver));
          }
        });

    monitor.assertNoFailures("hitting nginx url");
    monitor.terminate();
  }