blob: bb3ef02e4d574efe02df4621660c98e7910d4610 [file] [log] [blame]
/*
* 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.entity.webapp;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertNotNull;
import java.util.List;
import java.util.concurrent.Callable;
import org.apache.brooklyn.core.entity.EntityAsserts;
import org.apache.brooklyn.test.Asserts;
import org.apache.brooklyn.test.HttpTestUtils;
import org.apache.brooklyn.test.entity.TestJavaWebAppEntity;
import org.apache.brooklyn.test.support.TestResourceUnavailableException;
import org.apache.brooklyn.util.collections.CollectionFunctionals;
import org.apache.brooklyn.util.collections.MutableMap;
import org.apache.brooklyn.api.entity.Entity;
import org.apache.brooklyn.api.entity.EntitySpec;
import org.apache.brooklyn.core.entity.Attributes;
import org.apache.brooklyn.core.entity.RecordingSensorEventListener;
import org.apache.brooklyn.core.entity.lifecycle.Lifecycle;
import org.apache.brooklyn.core.test.BrooklynAppLiveTestSupport;
import org.apache.brooklyn.entity.proxy.AbstractController;
import org.apache.brooklyn.entity.proxy.LoadBalancer;
import org.apache.brooklyn.entity.proxy.nginx.NginxController;
import org.apache.brooklyn.entity.webapp.tomcat.TomcatServer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;
import org.apache.brooklyn.location.localhost.LocalhostMachineProvisioningLocation;
import com.google.common.base.Suppliers;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Iterables;
public class ControlledDynamicWebAppClusterIntegrationTest extends BrooklynAppLiveTestSupport {
private static final Logger log = LoggerFactory.getLogger(ControlledDynamicWebAppClusterIntegrationTest.class);
private static final int TIMEOUT_MS = 10*1000;
private LocalhostMachineProvisioningLocation loc;
private List<LocalhostMachineProvisioningLocation> locs;
@BeforeMethod(alwaysRun=true)
public void setUp() throws Exception {
super.setUp();
loc = app.newLocalhostProvisioningLocation();
locs = ImmutableList.of(loc);
}
public String getTestWar() {
TestResourceUnavailableException.throwIfResourceUnavailable(getClass(), "/hello-world.war");
return "classpath://hello-world.war";
}
@Test(groups="Integration")
public void testPropogateHttpPorts() {
ControlledDynamicWebAppCluster cluster = app.createAndManageChild(EntitySpec.create(ControlledDynamicWebAppCluster.class)
.configure("initialSize", 1));
app.start(locs);
EntityAsserts.assertAttributeEventuallyNonNull(cluster, LoadBalancer.PROXY_HTTP_PORT);
EntityAsserts.assertAttributeEventuallyNonNull(cluster, LoadBalancer.PROXY_HTTPS_PORT);
}
@Test(groups="Integration")
public void testConfiguresController() {
ControlledDynamicWebAppCluster cluster = app.createAndManageChild(EntitySpec.create(ControlledDynamicWebAppCluster.class)
.configure("initialSize", 1)
.configure("memberSpec", EntitySpec.create(TomcatServer.class).configure("war", getTestWar())));
app.start(locs);
String url = cluster.getController().getAttribute(NginxController.ROOT_URL);
HttpTestUtils.assertHttpStatusCodeEventuallyEquals(url, 200);
HttpTestUtils.assertContentEventuallyContainsText(url, "Hello");
}
@Test(groups="Integration")
public void testSetsToplevelHostnameFromController() {
ControlledDynamicWebAppCluster cluster = app.createAndManageChild(EntitySpec.create(ControlledDynamicWebAppCluster.class)
.configure("initialSize", 1)
.configure("memberSpec", EntitySpec.create(TomcatServer.class).configure("war", getTestWar())));
app.start(locs);
String expectedHostname = cluster.getController().getAttribute(LoadBalancer.HOSTNAME);
String expectedRootUrl = cluster.getController().getAttribute(LoadBalancer.ROOT_URL);
boolean expectedServiceUp = true;
assertNotNull(expectedHostname);
assertNotNull(expectedRootUrl);
EntityAsserts.assertAttributeEqualsEventually(MutableMap.of("timeout", TIMEOUT_MS), cluster, ControlledDynamicWebAppCluster.HOSTNAME, expectedHostname);
EntityAsserts.assertAttributeEqualsEventually(MutableMap.of("timeout", TIMEOUT_MS), cluster, ControlledDynamicWebAppCluster.ROOT_URL, expectedRootUrl);
EntityAsserts.assertAttributeEqualsEventually(MutableMap.of("timeout", TIMEOUT_MS), cluster, ControlledDynamicWebAppCluster.SERVICE_UP, expectedServiceUp);
}
@Test(groups="Integration")
public void testCustomWebClusterSpecGetsMemberSpec() {
ControlledDynamicWebAppCluster cluster = app.createAndManageChild(EntitySpec.create(ControlledDynamicWebAppCluster.class)
.configure("initialSize", 1)
.configure(ControlledDynamicWebAppCluster.MEMBER_SPEC, EntitySpec.create(TomcatServer.class)
.configure(TomcatServer.ROOT_WAR, getTestWar()))
.configure(ControlledDynamicWebAppCluster.WEB_CLUSTER_SPEC, EntitySpec.create(DynamicWebAppCluster.class)
.displayName("mydisplayname")));
app.start(locs);
String url = cluster.getController().getAttribute(NginxController.ROOT_URL);
HttpTestUtils.assertContentEventuallyContainsText(url, "Hello");
// and make sure it really was using our custom spec
assertEquals(cluster.getCluster().getDisplayName(), "mydisplayname");
}
// Needs to be integration test because still using nginx controller; could pass in mock controller
@Test(groups="Integration")
public void testSetsServiceLifecycle() {
ControlledDynamicWebAppCluster cluster = app.createAndManageChild( EntitySpec.create(ControlledDynamicWebAppCluster.class)
.configure("initialSize", 1)
.configure(ControlledDynamicWebAppCluster.MEMBER_SPEC, EntitySpec.create(TestJavaWebAppEntity.class)) );
EntityAsserts.assertAttributeEqualsEventually(cluster, Attributes.SERVICE_STATE_ACTUAL, Lifecycle.STOPPED);
RecordingSensorEventListener<Lifecycle> listener = new RecordingSensorEventListener<Lifecycle>(true);
app.subscriptions().subscribe(cluster, Attributes.SERVICE_STATE_ACTUAL, listener);
app.start(locs);
Asserts.eventually(Suppliers.ofInstance(listener.getEventValues()), CollectionFunctionals.sizeEquals(2));
assertEquals(listener.getEventValues(), ImmutableList.of(Lifecycle.STARTING, Lifecycle.RUNNING), "vals="+listener.getEventValues());
listener.clearEvents();
app.stop();
EntityAsserts.assertAttributeEqualsEventually(cluster, Attributes.SERVICE_STATE_ACTUAL, Lifecycle.STOPPED);
Asserts.eventually(Suppliers.ofInstance(listener), CollectionFunctionals.sizeEquals(2));
assertEquals(listener.getEventValues(), ImmutableList.of(Lifecycle.STOPPING, Lifecycle.STOPPED), "vals="+listener.getEventValues());
}
@Test(groups="Integration")
public void testTomcatAbsoluteRedirect() {
final ControlledDynamicWebAppCluster cluster = app.createAndManageChild(EntitySpec.create(ControlledDynamicWebAppCluster.class)
.configure(ControlledDynamicWebAppCluster.MEMBER_SPEC, EntitySpec.create(TomcatServer.class)
.configure(TomcatServer.ROOT_WAR, getTestWar()))
.configure("initialSize", 1)
.configure(AbstractController.SERVICE_UP_URL_PATH, "hello/redirectAbsolute")
);
app.start(locs);
final NginxController nginxController = (NginxController) cluster.getController();
Asserts.succeedsEventually(new Callable<Boolean>() {
@Override
public Boolean call() throws Exception {
return nginxController.getServerPoolAddresses().size() == 1;
}
});
Entity tomcatServer = Iterables.getOnlyElement(cluster.getCluster().getMembers());
EntityAsserts.assertAttributeEqualsEventually(tomcatServer, Attributes.SERVICE_UP, true);
EntityAsserts.assertAttributeEqualsContinually(nginxController, Attributes.SERVICE_UP, true);
app.stop();
}
}