http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/9b8bde02/examples/simple-web-cluster/src/test/java/org/apache/brooklyn/demo/RebindWebClusterDatabaseExampleAppIntegrationTest.java
----------------------------------------------------------------------
diff --git 
a/examples/simple-web-cluster/src/test/java/org/apache/brooklyn/demo/RebindWebClusterDatabaseExampleAppIntegrationTest.java
 
b/examples/simple-web-cluster/src/test/java/org/apache/brooklyn/demo/RebindWebClusterDatabaseExampleAppIntegrationTest.java
new file mode 100644
index 0000000..f032d95
--- /dev/null
+++ 
b/examples/simple-web-cluster/src/test/java/org/apache/brooklyn/demo/RebindWebClusterDatabaseExampleAppIntegrationTest.java
@@ -0,0 +1,206 @@
+/*
+ * 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.demo;
+
+import org.apache.brooklyn.demo.WebClusterDatabaseExampleApp;
+import static com.google.common.base.Preconditions.checkNotNull;
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertFalse;
+import static org.testng.Assert.assertNotNull;
+
+import java.util.Collection;
+import java.util.List;
+import java.util.concurrent.CopyOnWriteArrayList;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+
+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.enricher.HttpLatencyDetector;
+import brooklyn.enricher.basic.Propagator;
+import brooklyn.entity.Entity;
+import brooklyn.entity.basic.Entities;
+import brooklyn.entity.basic.StartableApplication;
+import brooklyn.entity.database.mysql.MySqlNode;
+import brooklyn.entity.group.DynamicCluster;
+import brooklyn.entity.java.JavaEntityMethods;
+import brooklyn.entity.proxy.nginx.NginxController;
+import brooklyn.entity.proxying.EntitySpec;
+import brooklyn.entity.rebind.RebindOptions;
+import brooklyn.entity.rebind.RebindTestFixture;
+import brooklyn.entity.webapp.ControlledDynamicWebAppCluster;
+import brooklyn.entity.webapp.DynamicWebAppCluster;
+import brooklyn.entity.webapp.tomcat.Tomcat8Server;
+import brooklyn.location.Location;
+import brooklyn.policy.Enricher;
+import brooklyn.policy.autoscaling.AutoScalerPolicy;
+import brooklyn.test.Asserts;
+import brooklyn.test.EntityTestUtils;
+import brooklyn.test.HttpTestUtils;
+import brooklyn.test.WebAppMonitor;
+import brooklyn.util.collections.MutableMap;
+import brooklyn.util.time.Duration;
+
+import com.google.common.base.Predicates;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Iterables;
+import com.google.common.collect.Sets;
+
+
+public class RebindWebClusterDatabaseExampleAppIntegrationTest extends 
RebindTestFixture<StartableApplication> {
+
+    private static final Logger LOG = 
LoggerFactory.getLogger(RebindWebClusterDatabaseExampleAppIntegrationTest.class);
+
+    private Location origLoc;
+    private List<WebAppMonitor> webAppMonitors = new 
CopyOnWriteArrayList<WebAppMonitor>();
+    private ExecutorService executor;
+
+    @BeforeMethod(alwaysRun=true)
+    @Override
+    public void setUp() throws Exception {
+        super.setUp();
+        origLoc = 
origManagementContext.getLocationRegistry().resolve("localhost");
+        executor = Executors.newCachedThreadPool();
+        webAppMonitors.clear();
+    }
+    
+    @AfterMethod(alwaysRun=true)
+    @Override
+    public void tearDown() throws Exception {
+        for (WebAppMonitor monitor : webAppMonitors) {
+            monitor.terminate();
+        }
+        if (executor != null) executor.shutdownNow();
+        super.tearDown();
+    }
+    
+    @Override
+    protected StartableApplication createApp() {
+        StartableApplication result = 
origManagementContext.getEntityManager().createEntity(EntitySpec.create(StartableApplication.class)
+                .impl(WebClusterDatabaseExampleApp.class)
+                .configure(DynamicCluster.INITIAL_SIZE, 2));
+        Entities.startManagement(result, origManagementContext);
+        return result;
+    }
+    
+    private WebAppMonitor newWebAppMonitor(String url, int 
expectedResponseCode) {
+        WebAppMonitor monitor = new WebAppMonitor(url)
+//              .delayMillis(0) FIXME Re-enable to fast polling
+                .expectedResponseCode(expectedResponseCode)
+                .logFailures(LOG);
+        webAppMonitors.add(monitor);
+        executor.execute(monitor);
+        return monitor;
+    }
+    
+    @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(Tomcat8Server.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(Tomcat8Server.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), 3, 
"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();
+    }
+}

Reply via email to