You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@brooklyn.apache.org by al...@apache.org on 2014/08/21 18:02:47 UTC

[4/5] git commit: Convert nginx tests from groovy to java

Convert nginx tests from groovy to java


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

Branch: refs/heads/master
Commit: 4d86f06c873697cdaed7424be8d5c236f195fa95
Parents: 8643fbc
Author: Aled Sage <al...@gmail.com>
Authored: Wed Jul 16 15:20:51 2014 +0100
Committer: Aled Sage <al...@gmail.com>
Committed: Thu Aug 21 16:49:43 2014 +0100

----------------------------------------------------------------------
 .../brooklyn/entity/proxy/ProxySslConfig.java   |  79 +++
 .../nginx/NginxClusterIntegrationTest.java      |  49 +-
 .../nginx/NginxHttpsSslIntegrationTest.groovy   | 171 ------
 .../nginx/NginxHttpsSslIntegrationTest.java     | 182 +++++++
 .../proxy/nginx/NginxIntegrationTest.groovy     | 432 ---------------
 .../proxy/nginx/NginxIntegrationTest.java       | 449 ++++++++++++++++
 .../proxy/nginx/NginxLightIntegrationTest.java  |  21 +-
 .../proxy/nginx/NginxRebindIntegrationTest.java |   3 -
 .../nginx/NginxUrlMappingIntegrationTest.groovy | 503 ------------------
 .../nginx/NginxUrlMappingIntegrationTest.java   | 523 +++++++++++++++++++
 .../nginx/NginxWebClusterEc2LiveTest.groovy     | 107 ----
 .../proxy/nginx/NginxWebClusterEc2LiveTest.java | 113 ++++
 .../main/java/brooklyn/test/HttpTestUtils.java  |  15 +
 13 files changed, 1383 insertions(+), 1264 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/4d86f06c/software/webapp/src/main/java/brooklyn/entity/proxy/ProxySslConfig.java
----------------------------------------------------------------------
diff --git a/software/webapp/src/main/java/brooklyn/entity/proxy/ProxySslConfig.java b/software/webapp/src/main/java/brooklyn/entity/proxy/ProxySslConfig.java
index 28dddd5..0d1be84 100644
--- a/software/webapp/src/main/java/brooklyn/entity/proxy/ProxySslConfig.java
+++ b/software/webapp/src/main/java/brooklyn/entity/proxy/ProxySslConfig.java
@@ -34,7 +34,10 @@ import com.google.common.base.Objects;
 
 public class ProxySslConfig implements Serializable {
 
+    private static final long serialVersionUID = -2692754611458939617L;
+    
     private static final Logger LOG = LoggerFactory.getLogger(ProxySslConfig.class);
+    
     private static final AtomicBoolean initialized = new AtomicBoolean(false);
 
     /** Setup type coercion. */
@@ -72,6 +75,42 @@ public class ProxySslConfig implements Serializable {
         init();
     }
 
+    public static Builder builder() {
+        return new Builder();
+    }
+    
+    public static class Builder {
+        protected String certificateSourceUrl;
+        protected String keySourceUrl;
+        protected String certificateDestination;
+        protected String keyDestination;
+        protected boolean targetIsSsl = false;
+        protected boolean reuseSessions = false;
+        
+        public Builder certificateSourceUrl(String val) {
+            certificateSourceUrl = val; return this;
+        }
+        public Builder keySourceUrl(String val) {
+            keySourceUrl = val; return this;
+        }
+        public Builder certificateDestination(String val) {
+            certificateDestination = val; return this;
+        }
+        public Builder keyDestination(String val) {
+            keyDestination = val; return this;
+        }
+        public Builder targetIsSsl(boolean val) {
+            targetIsSsl = val; return this;
+        }
+        public Builder reuseSessions(boolean val) {
+            reuseSessions = val; return this;
+        }
+        public ProxySslConfig build() {
+            ProxySslConfig result = new ProxySslConfig(this);
+            return result;
+        }
+    }
+    
     /** 
      * url's for the SSL certificates required at the server
      * <p>
@@ -121,10 +160,30 @@ public class ProxySslConfig implements Serializable {
      * corresponds to nginx setting: proxy_ssl_session_reuse on|off */
     boolean reuseSessions = false;
 
+    /**
+     * @deprecated since 0.7.0; use {@link ProxySslConfig#builder()}
+     */
+    @Deprecated
+    public ProxySslConfig() {
+    }
+    
+    protected ProxySslConfig(Builder builder) {
+        certificateSourceUrl = builder.certificateSourceUrl;
+        keySourceUrl = builder.keySourceUrl;
+        certificateDestination = builder.certificateDestination;
+        keyDestination = builder.keyDestination;
+        targetIsSsl = builder.targetIsSsl;
+        reuseSessions = builder.reuseSessions;
+    }
+    
     public String getCertificateSourceUrl() {
         return certificateSourceUrl;
     }
 
+    /**
+     * @deprecated since 0.7.0; use {@link ProxySslConfig#builder()}
+     */
+    @Deprecated
     public void setCertificateSourceUrl(String certificateSourceUrl) {
         this.certificateSourceUrl = certificateSourceUrl;
     }
@@ -133,6 +192,10 @@ public class ProxySslConfig implements Serializable {
         return keySourceUrl;
     }
 
+    /**
+     * @deprecated since 0.7.0; use {@link ProxySslConfig#builder()}
+     */
+    @Deprecated
     public void setKeySourceUrl(String keySourceUrl) {
         this.keySourceUrl = keySourceUrl;
     }
@@ -141,6 +204,10 @@ public class ProxySslConfig implements Serializable {
         return certificateDestination;
     }
 
+    /**
+     * @deprecated since 0.7.0; use {@link ProxySslConfig#builder()}
+     */
+    @Deprecated
     public void setCertificateDestination(String certificateDestination) {
         this.certificateDestination = certificateDestination;
     }
@@ -149,6 +216,10 @@ public class ProxySslConfig implements Serializable {
         return keyDestination;
     }
 
+    /**
+     * @deprecated since 0.7.0; use {@link ProxySslConfig#builder()}
+     */
+    @Deprecated
     public void setKeyDestination(String keyDestination) {
         this.keyDestination = keyDestination;
     }
@@ -157,6 +228,10 @@ public class ProxySslConfig implements Serializable {
         return targetIsSsl;
     }
 
+    /**
+     * @deprecated since 0.7.0; use {@link ProxySslConfig#builder()}
+     */
+    @Deprecated
     public void setTargetIsSsl(boolean targetIsSsl) {
         this.targetIsSsl = targetIsSsl;
     }
@@ -165,6 +240,10 @@ public class ProxySslConfig implements Serializable {
         return reuseSessions;
     }
 
+    /**
+     * @deprecated since 0.7.0; use {@link ProxySslConfig#builder()}
+     */
+    @Deprecated
     public void setReuseSessions(boolean reuseSessions) {
         this.reuseSessions = reuseSessions;
     }

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/4d86f06c/software/webapp/src/test/java/brooklyn/entity/proxy/nginx/NginxClusterIntegrationTest.java
----------------------------------------------------------------------
diff --git a/software/webapp/src/test/java/brooklyn/entity/proxy/nginx/NginxClusterIntegrationTest.java b/software/webapp/src/test/java/brooklyn/entity/proxy/nginx/NginxClusterIntegrationTest.java
index 24660d7..5c6b115 100644
--- a/software/webapp/src/test/java/brooklyn/entity/proxy/nginx/NginxClusterIntegrationTest.java
+++ b/software/webapp/src/test/java/brooklyn/entity/proxy/nginx/NginxClusterIntegrationTest.java
@@ -18,7 +18,6 @@
  */
 package brooklyn.entity.proxy.nginx;
 
-import static brooklyn.test.TestUtils.urlRespondsStatusCode;
 import static com.google.common.base.Preconditions.checkNotNull;
 import static org.testng.Assert.assertEquals;
 import static org.testng.Assert.assertTrue;
@@ -29,12 +28,11 @@ import java.util.List;
 
 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.BrooklynAppLiveTestSupport;
 import brooklyn.entity.Group;
-import brooklyn.entity.basic.ApplicationBuilder;
 import brooklyn.entity.basic.BasicGroup;
 import brooklyn.entity.basic.Entities;
 import brooklyn.entity.group.DynamicCluster;
@@ -43,11 +41,12 @@ import brooklyn.entity.proxying.EntitySpec;
 import brooklyn.entity.trait.Startable;
 import brooklyn.entity.webapp.JavaWebAppService;
 import brooklyn.entity.webapp.jboss.JBoss7Server;
-import brooklyn.location.basic.LocalhostMachineProvisioningLocation;
+import brooklyn.location.Location;
 import brooklyn.location.basic.PortRanges;
 import brooklyn.management.EntityManager;
-import brooklyn.test.TestUtils;
-import brooklyn.test.entity.TestApplication;
+import brooklyn.test.Asserts;
+import brooklyn.test.EntityTestUtils;
+import brooklyn.test.HttpTestUtils;
 import brooklyn.util.collections.MutableMap;
 
 import com.google.common.base.Predicates;
@@ -59,27 +58,26 @@ import com.google.common.collect.Lists;
 /**
  * Test the operation of the {@link NginxController} class.
  */
-public class NginxClusterIntegrationTest {
+public class NginxClusterIntegrationTest extends BrooklynAppLiveTestSupport {
+    @SuppressWarnings("unused")
     private static final Logger log = LoggerFactory.getLogger(NginxClusterIntegrationTest.class);
 
     private static final long TIMEOUT_MS = 60*1000;
     
     private URL war;
-    private LocalhostMachineProvisioningLocation localhostProvisioningLoc;
-    private TestApplication app;
+    private Location localhostProvisioningLoc;
     private EntityManager entityManager;
     private LoadBalancerCluster loadBalancerCluster;
     private EntitySpec<NginxController> nginxSpec;
     private Group urlMappings;
 
-
-    
-    @BeforeMethod(groups = "Integration")
-    public void setup() throws Exception {
+    @BeforeMethod(alwaysRun=true)
+    @Override
+    public void setUp() throws Exception {
+        super.setUp();
         war = checkNotNull(getClass().getClassLoader().getResource("hello-world.war"), "hello-world.war not on classpath");
-        localhostProvisioningLoc = new LocalhostMachineProvisioningLocation(MutableMap.of("address", "localhost"));
+        localhostProvisioningLoc = mgmt.getLocationRegistry().resolve("localhost");
         
-        app = ApplicationBuilder.newManagedApp(TestApplication.class);
         urlMappings = app.createAndManageChild(EntitySpec.create(BasicGroup.class)
                 .configure("childrenAsMembers", true));
         entityManager = app.getManagementContext().getEntityManager();
@@ -87,11 +85,6 @@ public class NginxClusterIntegrationTest {
         nginxSpec = EntitySpec.create(NginxController.class);
     }
 
-    @AfterMethod(groups = "Integration", alwaysRun=true)
-    public void shutdown() {
-        if (app != null) Entities.destroyAll(app.getManagementContext());
-    }
-
     @Test(groups = "Integration")
     public void testCreatesNginxInstancesAndResizes() {
         loadBalancerCluster = app.createAndManageChild(EntitySpec.create(LoadBalancerCluster.class)
@@ -169,13 +162,13 @@ public class NginxClusterIntegrationTest {
                 .configure(NginxController.DOMAIN_NAME, "localhost"));
         
         app.start(ImmutableList.of(localhostProvisioningLoc));
-        TestUtils.assertAttributeContinually(loadBalancerCluster, Startable.SERVICE_UP, false);
+        EntityTestUtils.assertAttributeEqualsContinually(loadBalancerCluster, Startable.SERVICE_UP, false);
         
         loadBalancerCluster.resize(1);
-        TestUtils.assertAttributeEventually(loadBalancerCluster, Startable.SERVICE_UP, true);
+        EntityTestUtils.assertAttributeEqualsEventually(loadBalancerCluster, Startable.SERVICE_UP, true);
 
         loadBalancerCluster.resize(0);
-        TestUtils.assertAttributeEventually(loadBalancerCluster, Startable.SERVICE_UP, false);
+        EntityTestUtils.assertAttributeEqualsEventually(loadBalancerCluster, Startable.SERVICE_UP, false);
     }
     
     // Warning: test is a little brittle for if a previous run leaves something on these required ports
@@ -217,12 +210,8 @@ public class NginxClusterIntegrationTest {
         assertNginxsResponsiveEvenutally(nginxs, null, Collections.<String>emptyList());
     }
 
-    private void assertNginxsResponsiveEvenutally(final Iterable<NginxController> nginxs, final List<String> pathsFor200) {
-        assertNginxsResponsiveEvenutally(nginxs, null, pathsFor200);
-    }
-    
     private void assertNginxsResponsiveEvenutally(final Iterable<NginxController> nginxs, final String hostname, final List<String> pathsFor200) {
-        TestUtils.executeUntilSucceeds(MutableMap.of("timeout", TIMEOUT_MS), new Runnable() {
+        Asserts.succeedsEventually(MutableMap.of("timeout", TIMEOUT_MS), new Runnable() {
             public void run() {
                 for (NginxController nginx : nginxs) {
                     assertTrue(nginx.getAttribute(NginxController.SERVICE_UP));
@@ -232,11 +221,11 @@ public class NginxClusterIntegrationTest {
                     String rootUrl = (hostname != null) ? ("http://"+hostname+":"+port+"/") : normalRootUrl;
                     
                     String wrongUrl = rootUrl+"doesnotexist";
-                    assertEquals(urlRespondsStatusCode(wrongUrl), 404, "url="+wrongUrl);
+                    HttpTestUtils.assertHttpStatusCodeEquals(wrongUrl, 404);
                     
                     for (String pathFor200 : pathsFor200) {
                         String url = rootUrl+pathFor200;
-                        assertEquals(urlRespondsStatusCode(url), 200, "url="+url);
+                        HttpTestUtils.assertHttpStatusCodeEquals(url, 200);
                     }
                 }
             }});

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/4d86f06c/software/webapp/src/test/java/brooklyn/entity/proxy/nginx/NginxHttpsSslIntegrationTest.groovy
----------------------------------------------------------------------
diff --git a/software/webapp/src/test/java/brooklyn/entity/proxy/nginx/NginxHttpsSslIntegrationTest.groovy b/software/webapp/src/test/java/brooklyn/entity/proxy/nginx/NginxHttpsSslIntegrationTest.groovy
deleted file mode 100644
index 7cb0423..0000000
--- a/software/webapp/src/test/java/brooklyn/entity/proxy/nginx/NginxHttpsSslIntegrationTest.groovy
+++ /dev/null
@@ -1,171 +0,0 @@
-/*
- * 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 brooklyn.entity.proxy.nginx;
-
-import static brooklyn.test.TestUtils.*
-import static org.testng.Assert.*
-
-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 brooklyn.entity.basic.ApplicationBuilder
-import brooklyn.entity.basic.Entities
-import brooklyn.entity.basic.SoftwareProcess
-import brooklyn.entity.group.DynamicCluster
-import brooklyn.entity.proxy.ProxySslConfig
-import brooklyn.entity.proxying.EntitySpec
-import brooklyn.entity.webapp.JavaWebAppService
-import brooklyn.entity.webapp.WebAppService
-import brooklyn.entity.webapp.jboss.JBoss7Server
-import brooklyn.location.basic.LocalhostMachineProvisioningLocation
-import brooklyn.test.HttpTestUtils
-import brooklyn.test.entity.TestApplication
-import brooklyn.util.internal.TimeExtras
-
-/**
- * Test the operation of the {@link NginxController} class.
- */
-public class NginxHttpsSslIntegrationTest {
-    private static final Logger log = LoggerFactory.getLogger(NginxHttpsSslIntegrationTest.class)
-
-    static { TimeExtras.init() }
-
-    private TestApplication app
-    private NginxController nginx
-    private DynamicCluster cluster
-
-    private static final String WAR_URL = "classpath://hello-world.war";
-    private static final String CERTIFICATE_URL = "classpath://ssl/certs/localhost/server.crt";
-    private static final String KEY_URL = "classpath://ssl/certs/localhost/server.key";
-    
-    @BeforeMethod(alwaysRun=true)
-    public void setup() {
-        app = ApplicationBuilder.newManagedApp(TestApplication.class);
-    }
-
-    @AfterMethod(alwaysRun=true)
-    public void shutdown() {
-        if (app != null) Entities.destroyAll(app.getManagementContext());
-    }
-
-    /**
-     * Test that the Nginx proxy starts up and sets SERVICE_UP correctly.
-     */
-    @Test(groups = "Integration")
-    public void testStartsWithGlobalSsl_withCertificateAndKeyCopy() {
-        cluster = app.createAndManageChild(EntitySpec.create(DynamicCluster.class)
-            .configure(DynamicCluster.MEMBER_SPEC, EntitySpec.create(JBoss7Server.class))
-            .configure("initialSize", 1)
-            .configure(JavaWebAppService.ROOT_WAR, WAR_URL));
-        
-        ProxySslConfig ssl = new ProxySslConfig(
-                certificateSourceUrl:CERTIFICATE_URL,
-                keySourceUrl:KEY_URL);
-        
-        nginx = app.createAndManageChild(EntitySpec.create(NginxController.class)
-                .configure("sticky", false)
-                .configure("serverPool", cluster)
-                .configure("domain", "localhost")
-                .configure("port", "8443+")
-                .configure("ssl", ssl));
-        
-        app.start([ new LocalhostMachineProvisioningLocation() ])
-
-        String url = nginx.getAttribute(WebAppService.ROOT_URL);
-        if (!url.startsWith("https://")) Assert.fail("URL should be https: "+url);
-        
-        executeUntilSucceeds() {
-            // Services are running
-            assertTrue cluster.getAttribute(SoftwareProcess.SERVICE_UP)
-            cluster.members.each { assertTrue it.getAttribute(SoftwareProcess.SERVICE_UP) }
-            
-            assertTrue nginx.getAttribute(SoftwareProcess.SERVICE_UP)
-
-            // Nginx URL is available
-            HttpTestUtils.assertHttpStatusCodeEquals(url, 200);
-
-            // Web-server URL is available
-            cluster.members.each {
-                HttpTestUtils.assertHttpStatusCodeEquals(it.getAttribute(WebAppService.ROOT_URL), 200);
-            }
-        }
-        
-        app.stop()
-
-        // Services have stopped
-        assertFalse nginx.getAttribute(SoftwareProcess.SERVICE_UP)
-        assertFalse cluster.getAttribute(SoftwareProcess.SERVICE_UP)
-        cluster.members.each { assertFalse it.getAttribute(SoftwareProcess.SERVICE_UP) }
-    }
-
-    private String getFile(String file) {
-           return new File(getClass().getResource("/" + file).getFile()).getAbsolutePath();
-       }
-
-    @Test(groups = "Integration")
-    public void testStartsWithGlobalSsl_withPreinstalledCertificateAndKey() {
-        cluster = app.createAndManageChild(EntitySpec.create(DynamicCluster.class)
-            .configure(DynamicCluster.MEMBER_SPEC, EntitySpec.create(JBoss7Server.class))
-            .configure("initialSize", 1)
-            .configure(JavaWebAppService.ROOT_WAR, WAR_URL));
-        
-        ProxySslConfig ssl = new ProxySslConfig(
-                certificateDestination: getFile("ssl/certs/localhost/server.crt"),
-                keyDestination: getFile("ssl/certs/localhost/server.key"));
-        
-        nginx = app.createAndManageChild(EntitySpec.create(NginxController.class)
-                .configure("sticky", false)
-                .configure("serverPool", cluster)
-                .configure("domain", "localhost")
-                .configure("port", "8443+")
-                .configure("ssl", ssl));
-
-        app.start([ new LocalhostMachineProvisioningLocation() ])
-
-        String url = nginx.getAttribute(WebAppService.ROOT_URL);
-        if (!url.startsWith("https://")) Assert.fail("URL should be https: "+url);
-
-        executeUntilSucceeds() {
-            // Services are running
-            assertTrue cluster.getAttribute(SoftwareProcess.SERVICE_UP)
-            cluster.members.each { assertTrue it.getAttribute(SoftwareProcess.SERVICE_UP) }
-
-            assertTrue nginx.getAttribute(SoftwareProcess.SERVICE_UP)
-
-            // Nginx URL is available
-            HttpTestUtils.assertHttpStatusCodeEquals(url, 200);
-
-            // Web-server URL is available
-            cluster.members.each {
-                HttpTestUtils.assertHttpStatusCodeEquals(it.getAttribute(WebAppService.ROOT_URL), 200)
-            }
-        }
-
-        app.stop()
-
-        // Services have stopped
-        assertFalse nginx.getAttribute(SoftwareProcess.SERVICE_UP)
-        assertFalse cluster.getAttribute(SoftwareProcess.SERVICE_UP)
-        cluster.members.each { assertFalse it.getAttribute(SoftwareProcess.SERVICE_UP) }
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/4d86f06c/software/webapp/src/test/java/brooklyn/entity/proxy/nginx/NginxHttpsSslIntegrationTest.java
----------------------------------------------------------------------
diff --git a/software/webapp/src/test/java/brooklyn/entity/proxy/nginx/NginxHttpsSslIntegrationTest.java b/software/webapp/src/test/java/brooklyn/entity/proxy/nginx/NginxHttpsSslIntegrationTest.java
new file mode 100644
index 0000000..826bd0f
--- /dev/null
+++ b/software/webapp/src/test/java/brooklyn/entity/proxy/nginx/NginxHttpsSslIntegrationTest.java
@@ -0,0 +1,182 @@
+/*
+ * 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 brooklyn.entity.proxy.nginx;
+
+import static org.testng.Assert.assertFalse;
+import static org.testng.Assert.assertTrue;
+
+import java.io.File;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.testng.Assert;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+import brooklyn.entity.BrooklynAppLiveTestSupport;
+import brooklyn.entity.Entity;
+import brooklyn.entity.basic.SoftwareProcess;
+import brooklyn.entity.group.DynamicCluster;
+import brooklyn.entity.proxy.ProxySslConfig;
+import brooklyn.entity.proxying.EntitySpec;
+import brooklyn.entity.webapp.JavaWebAppService;
+import brooklyn.entity.webapp.WebAppService;
+import brooklyn.entity.webapp.jboss.JBoss7Server;
+import brooklyn.location.Location;
+import brooklyn.test.Asserts;
+import brooklyn.test.HttpTestUtils;
+import brooklyn.test.entity.TestApplication;
+
+import com.google.common.collect.ImmutableList;
+
+/**
+ * Test the operation of the {@link NginxController} class.
+ */
+public class NginxHttpsSslIntegrationTest extends BrooklynAppLiveTestSupport {
+    @SuppressWarnings("unused")
+    private static final Logger log = LoggerFactory.getLogger(NginxHttpsSslIntegrationTest.class);
+
+    private NginxController nginx;
+    private DynamicCluster cluster;
+    private Location localLoc;
+
+    private static final String WAR_URL = "classpath://hello-world.war";
+    private static final String CERTIFICATE_URL = "classpath://ssl/certs/localhost/server.crt";
+    private static final String KEY_URL = "classpath://ssl/certs/localhost/server.key";
+    
+    @BeforeMethod(alwaysRun=true)
+    @Override
+    public void setUp() throws Exception {
+        super.setUp();
+        localLoc = mgmt.getLocationRegistry().resolve("localhost");
+    }
+
+    /**
+     * Test that the Nginx proxy starts up and sets SERVICE_UP correctly.
+     */
+    @Test(groups = "Integration")
+    public void testStartsWithGlobalSsl_withCertificateAndKeyCopy() {
+        cluster = app.createAndManageChild(EntitySpec.create(DynamicCluster.class)
+            .configure(DynamicCluster.MEMBER_SPEC, EntitySpec.create(JBoss7Server.class))
+            .configure("initialSize", 1)
+            .configure(JavaWebAppService.ROOT_WAR, WAR_URL));
+        
+        ProxySslConfig ssl = ProxySslConfig.builder()
+                .certificateSourceUrl(CERTIFICATE_URL)
+                .keySourceUrl(KEY_URL)
+                .build();
+        
+        nginx = app.createAndManageChild(EntitySpec.create(NginxController.class)
+                .configure("sticky", false)
+                .configure("serverPool", cluster)
+                .configure("domain", "localhost")
+                .configure("port", "8443+")
+                .configure("ssl", ssl));
+        
+        app.start(ImmutableList.of(localLoc));
+
+        final String url = nginx.getAttribute(WebAppService.ROOT_URL);
+        if (!url.startsWith("https://")) Assert.fail("URL should be https: "+url);
+        
+        Asserts.succeedsEventually(new Runnable() {
+            public void run() {
+                // Services are running
+                assertTrue(cluster.getAttribute(SoftwareProcess.SERVICE_UP));
+                for (Entity member : cluster.getMembers()) {
+                    assertTrue(member.getAttribute(SoftwareProcess.SERVICE_UP));
+                }
+                
+                assertTrue(nginx.getAttribute(SoftwareProcess.SERVICE_UP));
+    
+                // Nginx URL is available
+                HttpTestUtils.assertHttpStatusCodeEquals(url, 200);
+    
+                // Web-server URL is available
+                for (Entity member : cluster.getMembers()) {
+                    HttpTestUtils.assertHttpStatusCodeEquals(member.getAttribute(WebAppService.ROOT_URL), 200);
+                }
+            }});
+        
+        app.stop();
+
+        // Services have stopped
+        assertFalse(nginx.getAttribute(SoftwareProcess.SERVICE_UP));
+        assertFalse(cluster.getAttribute(SoftwareProcess.SERVICE_UP));
+        for (Entity member : cluster.getMembers()) {
+            assertFalse(member.getAttribute(SoftwareProcess.SERVICE_UP));
+        }
+    }
+
+    private String getFile(String file) {
+           return new File(getClass().getResource("/" + file).getFile()).getAbsolutePath();
+       }
+
+    @Test(groups = "Integration")
+    public void testStartsWithGlobalSsl_withPreinstalledCertificateAndKey() {
+        cluster = app.createAndManageChild(EntitySpec.create(DynamicCluster.class)
+            .configure(DynamicCluster.MEMBER_SPEC, EntitySpec.create(JBoss7Server.class))
+            .configure("initialSize", 1)
+            .configure(JavaWebAppService.ROOT_WAR, WAR_URL));
+        
+        ProxySslConfig ssl = ProxySslConfig.builder()
+                .certificateDestination(getFile("ssl/certs/localhost/server.crt"))
+                .keyDestination(getFile("ssl/certs/localhost/server.key"))
+                .build();
+        
+        nginx = app.createAndManageChild(EntitySpec.create(NginxController.class)
+                .configure("sticky", false)
+                .configure("serverPool", cluster)
+                .configure("domain", "localhost")
+                .configure("port", "8443+")
+                .configure("ssl", ssl));
+
+        app.start(ImmutableList.of(localLoc));
+
+        final String url = nginx.getAttribute(WebAppService.ROOT_URL);
+        if (!url.startsWith("https://")) Assert.fail("URL should be https: "+url);
+
+        Asserts.succeedsEventually(new Runnable() {
+            public void run() {
+                // Services are running
+                assertTrue(cluster.getAttribute(SoftwareProcess.SERVICE_UP));
+                for (Entity member : cluster.getMembers()) {
+                    assertTrue(member.getAttribute(SoftwareProcess.SERVICE_UP));
+                }
+    
+                assertTrue(nginx.getAttribute(SoftwareProcess.SERVICE_UP));
+    
+                // Nginx URL is available
+                HttpTestUtils.assertHttpStatusCodeEquals(url, 200);
+    
+                // Web-server URL is available
+                for (Entity member : cluster.getMembers()) {
+                    HttpTestUtils.assertHttpStatusCodeEquals(member.getAttribute(WebAppService.ROOT_URL), 200);
+                }
+            }});
+
+        app.stop();
+
+        // Services have stopped
+        assertFalse(nginx.getAttribute(SoftwareProcess.SERVICE_UP));
+        assertFalse(cluster.getAttribute(SoftwareProcess.SERVICE_UP));
+        for (Entity member : cluster.getMembers()) {
+            assertFalse(member.getAttribute(SoftwareProcess.SERVICE_UP));
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/4d86f06c/software/webapp/src/test/java/brooklyn/entity/proxy/nginx/NginxIntegrationTest.groovy
----------------------------------------------------------------------
diff --git a/software/webapp/src/test/java/brooklyn/entity/proxy/nginx/NginxIntegrationTest.groovy b/software/webapp/src/test/java/brooklyn/entity/proxy/nginx/NginxIntegrationTest.groovy
deleted file mode 100644
index 9249548..0000000
--- a/software/webapp/src/test/java/brooklyn/entity/proxy/nginx/NginxIntegrationTest.groovy
+++ /dev/null
@@ -1,432 +0,0 @@
-/*
- * 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 brooklyn.entity.proxy.nginx;
-
-import static brooklyn.test.HttpTestUtils.*
-import static brooklyn.test.TestUtils.*
-import static java.util.concurrent.TimeUnit.*
-import static org.testng.Assert.*
-
-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.basic.ApplicationBuilder
-import brooklyn.entity.basic.Entities
-import brooklyn.entity.basic.SoftwareProcess
-import brooklyn.entity.group.DynamicCluster
-import brooklyn.entity.proxying.EntitySpec
-import brooklyn.entity.webapp.JavaWebAppService
-import brooklyn.entity.webapp.WebAppService
-import brooklyn.entity.webapp.jboss.JBoss7Server
-import brooklyn.location.basic.LocalhostMachineProvisioningLocation
-import brooklyn.test.HttpTestUtils
-import brooklyn.test.WebAppMonitor
-import brooklyn.test.entity.TestApplication
-import brooklyn.util.internal.TimeExtras
-import brooklyn.util.time.Duration;
-import brooklyn.util.time.Time;
-/**
- * Test the operation of the {@link NginxController} class.
- */
-public class NginxIntegrationTest {
-    private static final Logger log = LoggerFactory.getLogger(NginxIntegrationTest.class)
-
-    static final String HELLO_WAR_URL = "classpath://hello-world.war";
-    static { TimeExtras.init() }
-
-    private TestApplication app
-    private NginxController nginx
-    private DynamicCluster serverPool
-
-    @BeforeMethod(alwaysRun=true)
-    public void setup() {
-        app = ApplicationBuilder.newManagedApp(TestApplication.class);
-    }
-
-    @AfterMethod(alwaysRun=true)
-    public void shutdown() {
-        if (app != null) Entities.destroyAll(app.getManagementContext());
-    }
-
-    /**
-     * Test that the Nginx proxy starts up and sets SERVICE_UP correctly.
-     */
-    @Test(groups = "Integration")
-    public void testWhenNoServersReturns404() {
-        serverPool = app.createAndManageChild(EntitySpec.create(DynamicCluster.class)
-                .configure(DynamicCluster.FACTORY, { throw new UnsupportedOperationException(); })
-                .configure("initialSize", 0));
-        
-        nginx = app.createAndManageChild(EntitySpec.create(NginxController.class)
-                .configure("serverPool", serverPool)
-                .configure("domain", "localhost"));
-        
-        app.start([ new LocalhostMachineProvisioningLocation() ])
-        
-        assertAttributeEventually(nginx, SoftwareProcess.SERVICE_UP, true);
-        assertUrlStatusCodeEventually(nginx.getAttribute(NginxController.ROOT_URL), 404);
-    }
-
-    @Test(groups = "Integration")
-    public void testRestart() {
-        serverPool = app.createAndManageChild(EntitySpec.create(DynamicCluster.class)
-                .configure(DynamicCluster.FACTORY, { throw new UnsupportedOperationException(); })
-                .configure("initialSize", 0));
-        
-        nginx = app.createAndManageChild(EntitySpec.create(NginxController.class)
-                .configure("serverPool", serverPool)
-                .configure("domain", "localhost"));
-        
-        app.start([ new LocalhostMachineProvisioningLocation() ])
-
-        nginx.restart();
-        
-        assertAttributeEventually(nginx, SoftwareProcess.SERVICE_UP, true);
-        assertUrlStatusCodeEventually(nginx.getAttribute(NginxController.ROOT_URL), 404);
-    }
-
-    /**
-     * Test that the Nginx proxy starts up and sets SERVICE_UP correctly.
-     */
-    @Test(groups = "Integration")
-    public void testCanStartupAndShutdown() {
-        serverPool = app.createAndManageChild(EntitySpec.create(DynamicCluster.class)
-                .configure(DynamicCluster.MEMBER_SPEC, EntitySpec.create(JBoss7Server.class))
-                .configure("initialSize", 1)
-                .configure(JavaWebAppService.ROOT_WAR, HELLO_WAR_URL));
-        
-        nginx = app.createAndManageChild(EntitySpec.create(NginxController.class)
-                .configure("serverPool", serverPool)
-                .configure("domain", "localhost")
-                .configure("portNumberSensor", WebAppService.HTTP_PORT));
-        
-        app.start([ new LocalhostMachineProvisioningLocation() ])
-        
-        // App-servers and nginx has started
-        assertEventually {        
-            serverPool.members.each { 
-                assertTrue it.getAttribute(SoftwareProcess.SERVICE_UP);
-            }
-            assertTrue nginx.getAttribute(SoftwareProcess.SERVICE_UP);
-        }
-
-        // URLs reachable        
-        assertUrlStatusCodeEventually(nginx.getAttribute(NginxController.ROOT_URL), 200);
-        serverPool.members.each {
-            assertUrlStatusCodeEventually(it.getAttribute(WebAppService.ROOT_URL), 200);
-        }
-
-        app.stop();
-
-        // Services have stopped
-        assertFalse(nginx.getAttribute(SoftwareProcess.SERVICE_UP));
-        assertFalse(serverPool.getAttribute(SoftwareProcess.SERVICE_UP));
-        serverPool.members.each {
-            assertFalse(it.getAttribute(SoftwareProcess.SERVICE_UP));
-        }
-    }
-
-    /**
-     * Test that the Nginx proxy starts up and sets SERVICE_UP correctly using the config file template.
-     */
-    @Test(groups = "Integration")
-    public void testCanStartupAndShutdownUsingTemplate() {
-        serverPool = app.createAndManageChild(EntitySpec.create(DynamicCluster.class)
-                .configure(DynamicCluster.MEMBER_SPEC, EntitySpec.create(JBoss7Server.class))
-                .configure("initialSize", 1)
-                .configure(JavaWebAppService.ROOT_WAR, HELLO_WAR_URL));
-
-        nginx = app.createAndManageChild(EntitySpec.create(NginxController.class)
-                .configure("serverPool", serverPool)
-                .configure("domain", "localhost")
-                .configure("portNumberSensor", WebAppService.HTTP_PORT)
-                .configure("configTemplate", "classpath://brooklyn/entity/proxy/nginx/server.conf"));
-
-        app.start([ new LocalhostMachineProvisioningLocation() ])
-
-        // App-servers and nginx has started
-        assertEventually {
-            serverPool.members.each {
-                assertTrue it.getAttribute(SoftwareProcess.SERVICE_UP);
-            }
-            assertTrue nginx.getAttribute(SoftwareProcess.SERVICE_UP);
-        }
-
-        // URLs reachable
-        assertUrlStatusCodeEventually(nginx.getAttribute(NginxController.ROOT_URL), 200);
-        serverPool.members.each {
-            assertUrlStatusCodeEventually(it.getAttribute(WebAppService.ROOT_URL), 200);
-        }
-
-        app.stop();
-
-        // Services have stopped
-        assertFalse(nginx.getAttribute(SoftwareProcess.SERVICE_UP));
-        assertFalse(serverPool.getAttribute(SoftwareProcess.SERVICE_UP));
-        serverPool.members.each {
-            assertFalse(it.getAttribute(SoftwareProcess.SERVICE_UP));
-        }
-    }
-
-    /**
-     * Test that the Nginx proxy works, serving all domains, if no domain is set
-     */
-    @Test(groups = "Integration")
-    public void testDomainless() {
-        serverPool = app.createAndManageChild(EntitySpec.create(DynamicCluster.class)
-                .configure(DynamicCluster.MEMBER_SPEC, EntitySpec.create(JBoss7Server.class))
-                .configure("initialSize", 1)
-                .configure(JavaWebAppService.ROOT_WAR, HELLO_WAR_URL));
-        
-        nginx = app.createAndManageChild(EntitySpec.create(NginxController.class)
-                .configure("serverPool", serverPool)
-                .configure("domain", "localhost")
-                .configure("portNumberSensor", WebAppService.HTTP_PORT));
-        
-        app.start([ new LocalhostMachineProvisioningLocation() ])
-        
-        // App-servers and nginx has started
-        assertAttributeEventually(serverPool, SoftwareProcess.SERVICE_UP, true);
-        serverPool.members.each {
-            assertAttributeEventually(it, SoftwareProcess.SERVICE_UP, true);
-        }
-        assertAttributeEventually(nginx, SoftwareProcess.SERVICE_UP, true);
-
-        // URLs reachable
-        assertUrlStatusCodeEventually(nginx.getAttribute(NginxController.ROOT_URL), 200);
-        serverPool.members.each {
-            assertUrlStatusCodeEventually(it.getAttribute(WebAppService.ROOT_URL), 200);
-        }
-
-        app.stop();
-
-        // Services have stopped
-        assertFalse(nginx.getAttribute(SoftwareProcess.SERVICE_UP));
-        assertFalse(serverPool.getAttribute(SoftwareProcess.SERVICE_UP));
-        serverPool.members.each {
-            assertFalse(it.getAttribute(SoftwareProcess.SERVICE_UP));
-        }
-    }
-    
-    @Test(groups = "Integration")
-    public void testTwoNginxesGetDifferentPorts() {
-        serverPool = app.createAndManageChild(EntitySpec.create(DynamicCluster.class)
-                .configure(DynamicCluster.FACTORY, { throw new UnsupportedOperationException(); })
-                .configure("initialSize", 0));
-        
-        NginxController nginx1 = app.createAndManageChild(EntitySpec.create(NginxController.class)
-                .configure("serverPool", serverPool)
-                .configure("domain", "localhost")
-                .configure("port", "14000+"));
-        
-        NginxController nginx2 = app.createAndManageChild(EntitySpec.create(NginxController.class)
-                .configure("serverPool", serverPool)
-                .configure("domain", "localhost")
-                .configure("port", "14000+"));
-        
-        app.start([ new LocalhostMachineProvisioningLocation() ])
-
-        String url1 = nginx1.getAttribute(NginxController.ROOT_URL)
-        String url2 = nginx2.getAttribute(NginxController.ROOT_URL)
-
-        assertTrue(url1.contains(":1400"), url1);
-        assertTrue(url2.contains(":1400"), url2);
-        assertNotEquals(url1, url2, "Two nginxs should listen on different ports, not both on "+url1);
-        
-        // Nginx has started
-        assertAttributeEventually(nginx1, SoftwareProcess.SERVICE_UP, true);
-        assertAttributeEventually(nginx2, SoftwareProcess.SERVICE_UP, true);
-
-        // Nginx reachable (returning default 404)
-        assertUrlStatusCodeEventually(url1, 404);
-        assertUrlStatusCodeEventually(url2, 404);
-    }
-    
-    /** Test that site access does not fail even while nginx is reloaded */
-    // FIXME test disabled -- reload isn't a problem, but #365 is
-    @Test(enabled = false, groups = "Integration")
-    public void testServiceContinuity() {
-        serverPool = app.createAndManageChild(EntitySpec.create(DynamicCluster.class)
-                .configure(DynamicCluster.MEMBER_SPEC, EntitySpec.create(JBoss7Server.class))
-                .configure("initialSize", 1)
-                .configure(JavaWebAppService.ROOT_WAR, HELLO_WAR_URL));
-        
-        nginx = app.createAndManageChild(EntitySpec.create(NginxController.class)
-                .configure("serverPool", serverPool));
-        
-        app.start([ new LocalhostMachineProvisioningLocation() ])
-
-        assertEventually {        
-            serverPool.members.each { 
-                assertHttpStatusCodeEquals it.getAttribute(WebAppService.ROOT_URL), 200;
-            }
-            assertHttpStatusCodeEquals nginx.getAttribute(WebAppService.ROOT_URL), 200;
-        }
-
-        WebAppMonitor monitor = new WebAppMonitor(nginx.getAttribute(WebAppService.ROOT_URL)).
-            logFailures(LOG).
-            delayMillis(0);
-        Thread t = new Thread(monitor);
-        t.start();
-
-        try {
-            Thread.sleep(1*1000);
-            LOG.info("service continuity test, startup, "+monitor.getAttempts()+" requests made");
-            monitor.assertAttemptsMade(10, "startup").assertNoFailures("startup").resetCounts();
-            
-            for (int i=0; i<20; i++) {
-                nginx.reload();
-                Thread.sleep(500);
-                LOG.info("service continuity test, iteration "+i+", "+monitor.getAttempts()+" requests made");
-                monitor.assertAttemptsMade(10, "reloaded").assertNoFailures("reloaded").resetCounts();
-            }
-            
-        } finally {
-            t.interrupt();
-        }
-        
-        app.stop();
-
-        // Services have stopped
-        assertFalse(nginx.getAttribute(SoftwareProcess.SERVICE_UP));
-        assertFalse(serverPool.getAttribute(SoftwareProcess.SERVICE_UP));
-        serverPool.members.each {
-            assertFalse(it.getAttribute(SoftwareProcess.SERVICE_UP));
-        }
-    }
-
-    // FIXME test disabled -- issue #365
-    /*
-     * This currently makes no assertions, but writes out the number of sequential reqs per sec
-     * supported with nginx and jboss.
-     * <p>
-     * jboss is (now) steady, at 6k+, since we close the connections in HttpTestUtils.getHttpStatusCode.
-     * but nginx still hits problems, after about 15k reqs, something is getting starved in nginx.
-     */
-    @Test(enabled=false, groups = "Integration")
-    public void testContinuityNginxAndJboss() {
-        serverPool = app.createAndManageChild(EntitySpec.create(DynamicCluster.class)
-                .configure(DynamicCluster.MEMBER_SPEC, EntitySpec.create(JBoss7Server.class))
-                .configure("initialSize", 1)
-                .configure(JavaWebAppService.ROOT_WAR, HELLO_WAR_URL));
-        
-        nginx = app.createAndManageChild(EntitySpec.create(NginxController.class)
-                .configure("serverPool", serverPool));
-        
-        app.start([ new LocalhostMachineProvisioningLocation() ])
-
-        String nginxUrl = nginx.getAttribute(WebAppService.ROOT_URL);
-        String jbossUrl;
-        assertEventually {
-            serverPool.members.each {
-                jbossUrl = it.getAttribute(WebAppService.ROOT_URL);
-                assertHttpStatusCodeEquals jbossUrl, 200;
-            }
-            assertHttpStatusCodeEquals nginxUrl, 200;
-        }
-
-        Thread t = new Thread() {
-            public void run() {
-                long lastReportTime = System.currentTimeMillis();
-                int num = 0;
-                while (true) {
-                    try {
-                        num++;
-                        int code = HttpTestUtils.getHttpStatusCode(nginxUrl);
-                        if (code!=200) LOG.info("NGINX GOT: "+code);
-                        else LOG.debug("NGINX GOT: "+code);
-                        if (System.currentTimeMillis()>=lastReportTime+1000) {
-                            LOG.info("NGINX DID "+num+" requests in last "+(System.currentTimeMillis()-lastReportTime)+"ms");
-                            num=0;
-                            lastReportTime = System.currentTimeMillis();
-                        }
-                    } catch (Exception e) {
-                        LOG.info("NGINX GOT: "+e);
-                    }
-                }
-            }
-        };
-        t.start();
-        
-        Thread t2 = new Thread() {
-            public void run() {
-                long lastReportTime = System.currentTimeMillis();
-                int num = 0;
-        while (true) {
-            try {
-                num++;
-                int code = HttpTestUtils.getHttpStatusCode(jbossUrl);
-                if (code!=200) LOG.info("JBOSS GOT: "+code);
-                else LOG.debug("JBOSS GOT: "+code);
-                if (System.currentTimeMillis()>=1000+lastReportTime) {
-                    LOG.info("JBOSS DID "+num+" requests in last "+(System.currentTimeMillis()-lastReportTime)+"ms");
-                    num=0;
-                    lastReportTime = System.currentTimeMillis();
-                }
-            } catch (Exception e) {
-                LOG.info("JBOSS GOT: "+e);
-            }
-        }
-            }
-        };
-        t2.start();
-        
-        t2.join();
-    }
-
-    /**
-     * Test that the Nginx proxy starts up and sets SERVICE_UP correctly.
-     */
-    @Test(groups = "Integration")
-    public void testCanRestart() {
-        nginx = app.createAndManageChild(EntitySpec.create(NginxController.class)
-                .configure("serverPool", serverPool)
-                .configure("domain", "localhost")
-                .configure("portNumberSensor", WebAppService.HTTP_PORT));
-        
-        app.start([ new LocalhostMachineProvisioningLocation() ])
-        
-        // App-servers and nginx has started
-        assertEventually {
-            assertTrue nginx.getAttribute(SoftwareProcess.SERVICE_UP);
-        }
-
-        log.info("started, will restart soon");
-        Time.sleep(Duration.ONE_SECOND);
-        
-        nginx.restart()
-
-        Time.sleep(Duration.ONE_SECOND);
-        assertEventually {
-            assertTrue nginx.getAttribute(SoftwareProcess.SERVICE_UP);
-        }
-        log.info("restarted and got service up");
-    }
-    
-//    public static void main(String[] args) {
-//        NginxIntegrationTest t = new NginxIntegrationTest();
-//        t.setup();
-//        t.testCanRestart();
-//        t.shutdown();        
-//    }
-
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/4d86f06c/software/webapp/src/test/java/brooklyn/entity/proxy/nginx/NginxIntegrationTest.java
----------------------------------------------------------------------
diff --git a/software/webapp/src/test/java/brooklyn/entity/proxy/nginx/NginxIntegrationTest.java b/software/webapp/src/test/java/brooklyn/entity/proxy/nginx/NginxIntegrationTest.java
new file mode 100644
index 0000000..2dd5567
--- /dev/null
+++ b/software/webapp/src/test/java/brooklyn/entity/proxy/nginx/NginxIntegrationTest.java
@@ -0,0 +1,449 @@
+/*
+ * 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 brooklyn.entity.proxy.nginx;
+
+import static brooklyn.test.EntityTestUtils.assertAttributeEqualsEventually;
+import static brooklyn.test.HttpTestUtils.assertHttpStatusCodeEquals;
+import static brooklyn.test.HttpTestUtils.assertHttpStatusCodeEventuallyEquals;
+import static org.testng.Assert.assertFalse;
+import static org.testng.Assert.assertNotEquals;
+import static org.testng.Assert.assertTrue;
+
+import java.util.Map;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+import brooklyn.entity.BrooklynAppLiveTestSupport;
+import brooklyn.entity.Entity;
+import brooklyn.entity.basic.EntityFactory;
+import brooklyn.entity.basic.SoftwareProcess;
+import brooklyn.entity.group.DynamicCluster;
+import brooklyn.entity.proxying.EntitySpec;
+import brooklyn.entity.webapp.JavaWebAppService;
+import brooklyn.entity.webapp.WebAppService;
+import brooklyn.entity.webapp.jboss.JBoss7Server;
+import brooklyn.location.Location;
+import brooklyn.test.Asserts;
+import brooklyn.test.HttpTestUtils;
+import brooklyn.test.WebAppMonitor;
+import brooklyn.util.time.Duration;
+import brooklyn.util.time.Time;
+
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.Iterables;
+/**
+ * Test the operation of the {@link NginxController} class.
+ */
+public class NginxIntegrationTest extends BrooklynAppLiveTestSupport {
+    private static final Logger log = LoggerFactory.getLogger(NginxIntegrationTest.class);
+
+    static final String HELLO_WAR_URL = "classpath://hello-world.war";
+
+    private NginxController nginx;
+    private DynamicCluster serverPool;
+    private Location localLoc;
+
+    @BeforeMethod(alwaysRun=true)
+    @Override
+    public void setUp() throws Exception {
+        super.setUp();
+        localLoc = mgmt.getLocationRegistry().resolve("localhost");
+    }
+
+    /**
+     * Test that the Nginx proxy starts up and sets SERVICE_UP correctly.
+     */
+    @Test(groups = "Integration")
+    public void testWhenNoServersReturns404() {
+        serverPool = app.createAndManageChild(EntitySpec.create(DynamicCluster.class)
+                .configure("initialSize", 0)
+                .configure(DynamicCluster.FACTORY, new EntityFactory<Entity>() {
+                    @Override public Entity newEntity(Map flags, Entity parent) {
+                        throw new UnsupportedOperationException();
+                    }}));
+        
+        nginx = app.createAndManageChild(EntitySpec.create(NginxController.class)
+                .configure("serverPool", serverPool)
+                .configure("domain", "localhost"));
+        
+        app.start(ImmutableList.of(localLoc));
+        
+        assertAttributeEqualsEventually(nginx, SoftwareProcess.SERVICE_UP, true);
+        assertHttpStatusCodeEventuallyEquals(nginx.getAttribute(NginxController.ROOT_URL), 404);
+    }
+
+    @Test(groups = "Integration")
+    public void testRestart() {
+        serverPool = app.createAndManageChild(EntitySpec.create(DynamicCluster.class)
+                .configure("initialSize", 0)
+                .configure(DynamicCluster.FACTORY, new EntityFactory<Entity>() {
+                    @Override public Entity newEntity(Map flags, Entity parent) {
+                        throw new UnsupportedOperationException();
+                    }}));
+        
+        nginx = app.createAndManageChild(EntitySpec.create(NginxController.class)
+                .configure("serverPool", serverPool)
+                .configure("domain", "localhost"));
+        
+        app.start(ImmutableList.of(localLoc));
+
+        nginx.restart();
+        
+        assertAttributeEqualsEventually(nginx, SoftwareProcess.SERVICE_UP, true);
+        assertHttpStatusCodeEventuallyEquals(nginx.getAttribute(NginxController.ROOT_URL), 404);
+    }
+
+    /**
+     * Test that the Nginx proxy starts up and sets SERVICE_UP correctly.
+     */
+    @Test(groups = "Integration")
+    public void testCanStartupAndShutdown() {
+        serverPool = app.createAndManageChild(EntitySpec.create(DynamicCluster.class)
+                .configure(DynamicCluster.MEMBER_SPEC, EntitySpec.create(JBoss7Server.class))
+                .configure("initialSize", 1)
+                .configure(JavaWebAppService.ROOT_WAR, HELLO_WAR_URL));
+        
+        nginx = app.createAndManageChild(EntitySpec.create(NginxController.class)
+                .configure("serverPool", serverPool)
+                .configure("domain", "localhost")
+                .configure("portNumberSensor", WebAppService.HTTP_PORT));
+        
+        app.start(ImmutableList.of(localLoc));
+        
+        // App-servers and nginx has started
+        Asserts.succeedsEventually(new Runnable() {
+            public void run() {
+                for (Entity member : serverPool.getMembers()) {
+                    assertTrue(member.getAttribute(SoftwareProcess.SERVICE_UP));
+                }
+                assertTrue(nginx.getAttribute(SoftwareProcess.SERVICE_UP));
+            }});
+
+        // URLs reachable
+        assertHttpStatusCodeEventuallyEquals(nginx.getAttribute(NginxController.ROOT_URL), 200);
+        for (Entity member : serverPool.getMembers()) {
+            assertHttpStatusCodeEventuallyEquals(member.getAttribute(WebAppService.ROOT_URL), 200);
+        }
+
+        app.stop();
+
+        // Services have stopped
+        assertFalse(nginx.getAttribute(SoftwareProcess.SERVICE_UP));
+        assertFalse(serverPool.getAttribute(SoftwareProcess.SERVICE_UP));
+        for (Entity member : serverPool.getMembers()) {
+            assertFalse(member.getAttribute(SoftwareProcess.SERVICE_UP));
+        }
+    }
+
+    /**
+     * Test that the Nginx proxy starts up and sets SERVICE_UP correctly using the config file template.
+     */
+    @Test(groups = "Integration")
+    public void testCanStartupAndShutdownUsingTemplate() {
+        serverPool = app.createAndManageChild(EntitySpec.create(DynamicCluster.class)
+                .configure(DynamicCluster.MEMBER_SPEC, EntitySpec.create(JBoss7Server.class))
+                .configure("initialSize", 1)
+                .configure(JavaWebAppService.ROOT_WAR, HELLO_WAR_URL));
+
+        nginx = app.createAndManageChild(EntitySpec.create(NginxController.class)
+                .configure("serverPool", serverPool)
+                .configure("domain", "localhost")
+                .configure("portNumberSensor", WebAppService.HTTP_PORT)
+                .configure("configTemplate", "classpath://brooklyn/entity/proxy/nginx/server.conf"));
+
+        app.start(ImmutableList.of(localLoc));
+
+        // App-servers and nginx has started
+        Asserts.succeedsEventually(new Runnable() {
+            public void run() {
+                for (Entity member : serverPool.getMembers()) {
+                    assertTrue(member.getAttribute(SoftwareProcess.SERVICE_UP));
+                }
+                assertTrue(nginx.getAttribute(SoftwareProcess.SERVICE_UP));
+            }});
+
+        // URLs reachable
+        assertHttpStatusCodeEventuallyEquals(nginx.getAttribute(NginxController.ROOT_URL), 200);
+        for (Entity member : serverPool.getMembers()) {
+            assertHttpStatusCodeEventuallyEquals(member.getAttribute(WebAppService.ROOT_URL), 200);
+        }
+
+        app.stop();
+
+        // Services have stopped
+        assertFalse(nginx.getAttribute(SoftwareProcess.SERVICE_UP));
+        assertFalse(serverPool.getAttribute(SoftwareProcess.SERVICE_UP));
+        for (Entity member : serverPool.getMembers()) {
+            assertFalse(member.getAttribute(SoftwareProcess.SERVICE_UP));
+        }
+    }
+
+    /**
+     * Test that the Nginx proxy works, serving all domains, if no domain is set
+     */
+    @Test(groups = "Integration")
+    public void testDomainless() {
+        serverPool = app.createAndManageChild(EntitySpec.create(DynamicCluster.class)
+                .configure(DynamicCluster.MEMBER_SPEC, EntitySpec.create(JBoss7Server.class))
+                .configure("initialSize", 1)
+                .configure(JavaWebAppService.ROOT_WAR, HELLO_WAR_URL));
+        
+        nginx = app.createAndManageChild(EntitySpec.create(NginxController.class)
+                .configure("serverPool", serverPool)
+                .configure("domain", "localhost")
+                .configure("portNumberSensor", WebAppService.HTTP_PORT));
+        
+        app.start(ImmutableList.of(localLoc));
+        
+        // App-servers and nginx has started
+        assertAttributeEqualsEventually(serverPool, SoftwareProcess.SERVICE_UP, true);
+        for (Entity member : serverPool.getMembers()) {
+            assertAttributeEqualsEventually(member, SoftwareProcess.SERVICE_UP, true);
+        }
+        assertAttributeEqualsEventually(nginx, SoftwareProcess.SERVICE_UP, true);
+
+        // URLs reachable
+        assertHttpStatusCodeEventuallyEquals(nginx.getAttribute(NginxController.ROOT_URL), 200);
+        for (Entity member : serverPool.getMembers()) {
+            assertHttpStatusCodeEventuallyEquals(member.getAttribute(WebAppService.ROOT_URL), 200);
+        }
+
+        app.stop();
+
+        // Services have stopped
+        assertFalse(nginx.getAttribute(SoftwareProcess.SERVICE_UP));
+        assertFalse(serverPool.getAttribute(SoftwareProcess.SERVICE_UP));
+        for (Entity member : serverPool.getMembers()) {
+            assertFalse(member.getAttribute(SoftwareProcess.SERVICE_UP));
+        }
+    }
+    
+    @Test(groups = "Integration")
+    public void testTwoNginxesGetDifferentPorts() {
+        serverPool = app.createAndManageChild(EntitySpec.create(DynamicCluster.class)
+                .configure("initialSize", 0)
+                .configure(DynamicCluster.FACTORY, new EntityFactory<Entity>() {
+                    @Override public Entity newEntity(Map flags, Entity parent) {
+                        throw new UnsupportedOperationException();
+                    }}));
+        
+        NginxController nginx1 = app.createAndManageChild(EntitySpec.create(NginxController.class)
+                .configure("serverPool", serverPool)
+                .configure("domain", "localhost")
+                .configure("port", "14000+"));
+        
+        NginxController nginx2 = app.createAndManageChild(EntitySpec.create(NginxController.class)
+                .configure("serverPool", serverPool)
+                .configure("domain", "localhost")
+                .configure("port", "14000+"));
+        
+        app.start(ImmutableList.of(localLoc));
+
+        String url1 = nginx1.getAttribute(NginxController.ROOT_URL);
+        String url2 = nginx2.getAttribute(NginxController.ROOT_URL);
+
+        assertTrue(url1.contains(":1400"), url1);
+        assertTrue(url2.contains(":1400"), url2);
+        assertNotEquals(url1, url2, "Two nginxs should listen on different ports, not both on "+url1);
+        
+        // Nginx has started
+        assertAttributeEqualsEventually(nginx1, SoftwareProcess.SERVICE_UP, true);
+        assertAttributeEqualsEventually(nginx2, SoftwareProcess.SERVICE_UP, true);
+
+        // Nginx reachable (returning default 404)
+        assertHttpStatusCodeEventuallyEquals(url1, 404);
+        assertHttpStatusCodeEventuallyEquals(url2, 404);
+    }
+    
+    /** Test that site access does not fail even while nginx is reloaded */
+    // FIXME test disabled -- reload isn't a problem, but #365 is
+    @Test(enabled = false, groups = "Integration")
+    public void testServiceContinuity() throws Exception {
+        serverPool = app.createAndManageChild(EntitySpec.create(DynamicCluster.class)
+                .configure(DynamicCluster.MEMBER_SPEC, EntitySpec.create(JBoss7Server.class))
+                .configure("initialSize", 1)
+                .configure(JavaWebAppService.ROOT_WAR, HELLO_WAR_URL));
+        
+        nginx = app.createAndManageChild(EntitySpec.create(NginxController.class)
+                .configure("serverPool", serverPool));
+        
+        app.start(ImmutableList.of(localLoc));
+
+        Asserts.succeedsEventually(new Runnable() {
+            public void run() {
+                for (Entity member : serverPool.getMembers()) {
+                    assertHttpStatusCodeEquals(member.getAttribute(WebAppService.ROOT_URL), 200);
+                }
+                assertHttpStatusCodeEquals(nginx.getAttribute(WebAppService.ROOT_URL), 200);
+            }});
+
+        WebAppMonitor monitor = new WebAppMonitor(nginx.getAttribute(WebAppService.ROOT_URL))
+            .logFailures(log)
+            .delayMillis(0);
+        Thread t = new Thread(monitor);
+        t.start();
+
+        try {
+            Thread.sleep(1*1000);
+            log.info("service continuity test, startup, "+monitor.getAttempts()+" requests made");
+            monitor.assertAttemptsMade(10, "startup").assertNoFailures("startup").resetCounts();
+            
+            for (int i=0; i<20; i++) {
+                nginx.reload();
+                Thread.sleep(500);
+                log.info("service continuity test, iteration "+i+", "+monitor.getAttempts()+" requests made");
+                monitor.assertAttemptsMade(10, "reloaded").assertNoFailures("reloaded").resetCounts();
+            }
+            
+        } finally {
+            t.interrupt();
+        }
+        
+        app.stop();
+
+        // Services have stopped
+        assertFalse(nginx.getAttribute(SoftwareProcess.SERVICE_UP));
+        assertFalse(serverPool.getAttribute(SoftwareProcess.SERVICE_UP));
+        for (Entity member : serverPool.getMembers()) {
+            assertFalse(member.getAttribute(SoftwareProcess.SERVICE_UP));
+        }
+    }
+
+    // FIXME test disabled -- issue #365
+    /*
+     * This currently makes no assertions, but writes out the number of sequential reqs per sec
+     * supported with nginx and jboss.
+     * <p>
+     * jboss is (now) steady, at 6k+, since we close the connections in HttpTestUtils.getHttpStatusCode.
+     * but nginx still hits problems, after about 15k reqs, something is getting starved in nginx.
+     */
+    @Test(enabled=false, groups = "Integration")
+    public void testContinuityNginxAndJboss() throws Exception {
+        serverPool = app.createAndManageChild(EntitySpec.create(DynamicCluster.class)
+                .configure(DynamicCluster.MEMBER_SPEC, EntitySpec.create(JBoss7Server.class))
+                .configure("initialSize", 1)
+                .configure(JavaWebAppService.ROOT_WAR, HELLO_WAR_URL));
+        
+        nginx = app.createAndManageChild(EntitySpec.create(NginxController.class)
+                .configure("serverPool", serverPool));
+        
+        app.start(ImmutableList.of(localLoc));
+
+        final String nginxUrl = nginx.getAttribute(WebAppService.ROOT_URL);
+
+        Asserts.succeedsEventually(new Runnable() {
+            public void run() {
+                for (Entity member : serverPool.getMembers()) {
+                    String jbossUrl = member.getAttribute(WebAppService.ROOT_URL);
+                    assertHttpStatusCodeEquals(jbossUrl, 200);
+                }
+                assertHttpStatusCodeEquals(nginxUrl, 200);
+            }});
+
+        final String jbossUrl = Iterables.get(serverPool.getMembers(), 0).getAttribute(WebAppService.ROOT_URL);
+        
+        Thread t = new Thread(new Runnable() {
+            public void run() {
+                long lastReportTime = System.currentTimeMillis();
+                int num = 0;
+                while (true) {
+                    try {
+                        num++;
+                        int code = HttpTestUtils.getHttpStatusCode(nginxUrl);
+                        if (code!=200) log.info("NGINX GOT: "+code);
+                        else log.debug("NGINX GOT: "+code);
+                        if (System.currentTimeMillis()>=lastReportTime+1000) {
+                            log.info("NGINX DID "+num+" requests in last "+(System.currentTimeMillis()-lastReportTime)+"ms");
+                            num=0;
+                            lastReportTime = System.currentTimeMillis();
+                        }
+                    } catch (Exception e) {
+                        log.info("NGINX GOT: "+e);
+                    }
+                }
+            }});
+        t.start();
+        
+        Thread t2 = new Thread(new Runnable() {
+            public void run() {
+                long lastReportTime = System.currentTimeMillis();
+                int num = 0;
+                while (true) {
+                    try {
+                        num++;
+                        int code = HttpTestUtils.getHttpStatusCode(jbossUrl);
+                        if (code!=200) log.info("JBOSS GOT: "+code);
+                        else log.debug("JBOSS GOT: "+code);
+                        if (System.currentTimeMillis()>=1000+lastReportTime) {
+                            log.info("JBOSS DID "+num+" requests in last "+(System.currentTimeMillis()-lastReportTime)+"ms");
+                            num=0;
+                            lastReportTime = System.currentTimeMillis();
+                        }
+                    } catch (Exception e) {
+                        log.info("JBOSS GOT: "+e);
+                    }
+                }
+            }});
+        t2.start();
+        
+        t2.join();
+    }
+
+    /**
+     * Test that the Nginx proxy starts up and sets SERVICE_UP correctly.
+     */
+    @Test(groups = "Integration")
+    public void testCanRestart() {
+        nginx = app.createAndManageChild(EntitySpec.create(NginxController.class)
+                .configure("serverPool", serverPool)
+                .configure("domain", "localhost")
+                .configure("portNumberSensor", WebAppService.HTTP_PORT));
+        
+        app.start(ImmutableList.of(localLoc));
+        
+        // App-servers and nginx has started
+        Asserts.succeedsEventually(new Runnable() {
+            public void run() {
+                assertTrue(nginx.getAttribute(SoftwareProcess.SERVICE_UP));
+            }});
+
+        log.info("started, will restart soon");
+        Time.sleep(Duration.ONE_SECOND);
+        
+        nginx.restart();
+
+        Time.sleep(Duration.ONE_SECOND);
+        Asserts.succeedsEventually(new Runnable() {
+            public void run() {
+                assertTrue(nginx.getAttribute(SoftwareProcess.SERVICE_UP));
+            }});
+        log.info("restarted and got service up");
+    }
+    
+//    public static void main(String[] args) {
+//        NginxIntegrationTest t = new NginxIntegrationTest();
+//        t.setup();
+//        t.testCanRestart();
+//        t.shutdown();        
+//    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/4d86f06c/software/webapp/src/test/java/brooklyn/entity/proxy/nginx/NginxLightIntegrationTest.java
----------------------------------------------------------------------
diff --git a/software/webapp/src/test/java/brooklyn/entity/proxy/nginx/NginxLightIntegrationTest.java b/software/webapp/src/test/java/brooklyn/entity/proxy/nginx/NginxLightIntegrationTest.java
index b12bfa8..4605735 100644
--- a/software/webapp/src/test/java/brooklyn/entity/proxy/nginx/NginxLightIntegrationTest.java
+++ b/software/webapp/src/test/java/brooklyn/entity/proxy/nginx/NginxLightIntegrationTest.java
@@ -23,45 +23,30 @@ import static org.testng.Assert.assertEquals;
 import java.net.URL;
 import java.util.Map;
 
-import org.testng.annotations.AfterMethod;
-import org.testng.annotations.BeforeMethod;
 import org.testng.annotations.Test;
 
+import brooklyn.entity.BrooklynAppUnitTestSupport;
 import brooklyn.entity.Entity;
-import brooklyn.entity.basic.ApplicationBuilder;
 import brooklyn.entity.basic.Attributes;
 import brooklyn.entity.basic.BasicConfigurableEntityFactory;
-import brooklyn.entity.basic.Entities;
 import brooklyn.entity.basic.EntityFactory;
 import brooklyn.entity.group.DynamicCluster;
 import brooklyn.entity.proxy.StubAppServer;
 import brooklyn.entity.proxying.EntitySpec;
 import brooklyn.location.basic.LocalhostMachineProvisioningLocation;
 import brooklyn.test.Asserts;
-import brooklyn.test.entity.TestApplication;
 
 import com.google.common.collect.ImmutableList;
 import com.google.common.collect.Maps;
 
-public class NginxLightIntegrationTest {
+public class NginxLightIntegrationTest extends BrooklynAppUnitTestSupport {
 
-    private TestApplication app;
     private NginxController nginx;
     private DynamicCluster cluster;
 
     private URL war;
-    private static String WAR_URL = "classpath://hello-world.war";
+    private static final String WAR_URL = "classpath://hello-world.war";
     
-    @BeforeMethod
-    public void setup() {
-        app = ApplicationBuilder.newManagedApp(TestApplication.class);
-    }
-
-    @AfterMethod(alwaysRun=true)
-    public void shutdown() {
-        if (app != null) Entities.destroyAll(app.getManagementContext());
-    }
-
     // FIXME Fails because getting addEntity callback for group members while nginx is still starting,
     // so important nginx fields are still null. Therefore get NPE for cluster members, and thus targets
     // is of size zero.

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/4d86f06c/software/webapp/src/test/java/brooklyn/entity/proxy/nginx/NginxRebindIntegrationTest.java
----------------------------------------------------------------------
diff --git a/software/webapp/src/test/java/brooklyn/entity/proxy/nginx/NginxRebindIntegrationTest.java b/software/webapp/src/test/java/brooklyn/entity/proxy/nginx/NginxRebindIntegrationTest.java
index 9bf4244..a119130 100644
--- a/software/webapp/src/test/java/brooklyn/entity/proxy/nginx/NginxRebindIntegrationTest.java
+++ b/software/webapp/src/test/java/brooklyn/entity/proxy/nginx/NginxRebindIntegrationTest.java
@@ -54,7 +54,6 @@ import brooklyn.management.internal.LocalManagementContext;
 import brooklyn.test.Asserts;
 import brooklyn.test.WebAppMonitor;
 import brooklyn.test.entity.TestApplication;
-import brooklyn.util.internal.TimeExtras;
 
 import com.google.common.base.Predicates;
 import com.google.common.collect.ImmutableList;
@@ -68,8 +67,6 @@ import com.google.common.io.Files;
 public class NginxRebindIntegrationTest {
     private static final Logger LOG = LoggerFactory.getLogger(NginxRebindIntegrationTest.class);
 
-    static { TimeExtras.init(); }
-
     private URL warUrl;
     private LocalhostMachineProvisioningLocation localhostProvisioningLocation;
     private ClassLoader classLoader = getClass().getClassLoader();