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 2015/07/16 01:09:45 UTC
[01/12] incubator-brooklyn git commit: brooklyn-qa: add org.apache
package prefix
Repository: incubator-brooklyn
Updated Branches:
refs/heads/master 726bebca3 -> 12625d82c
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/bd44bb8f/usage/qa/src/test/java/org/apache/brooklyn/qa/load/LoadTest.java
----------------------------------------------------------------------
diff --git a/usage/qa/src/test/java/org/apache/brooklyn/qa/load/LoadTest.java b/usage/qa/src/test/java/org/apache/brooklyn/qa/load/LoadTest.java
new file mode 100644
index 0000000..d6c479c
--- /dev/null
+++ b/usage/qa/src/test/java/org/apache/brooklyn/qa/load/LoadTest.java
@@ -0,0 +1,244 @@
+/*
+ * 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.qa.load;
+
+import org.apache.brooklyn.qa.load.SimulatedTheeTierApp;
+import static org.testng.Assert.assertEquals;
+
+import java.io.File;
+import java.util.Collections;
+import java.util.List;
+import java.util.concurrent.Callable;
+import java.util.concurrent.Executors;
+import java.util.concurrent.Future;
+import java.util.concurrent.TimeUnit;
+
+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.Entities;
+import brooklyn.entity.basic.StartableApplication;
+import brooklyn.entity.proxying.EntitySpec;
+import brooklyn.entity.rebind.persister.PersistMode;
+import brooklyn.entity.trait.Startable;
+import brooklyn.launcher.BrooklynLauncher;
+import brooklyn.location.Location;
+import brooklyn.management.ManagementContext;
+import brooklyn.management.ha.HighAvailabilityMode;
+import brooklyn.management.internal.LocalManagementContext;
+import brooklyn.test.PerformanceTestUtils;
+import brooklyn.util.os.Os;
+import brooklyn.util.time.Duration;
+
+import com.google.common.base.Stopwatch;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.Lists;
+import com.google.common.io.Files;
+import com.google.common.util.concurrent.Futures;
+import com.google.common.util.concurrent.ListenableFuture;
+import com.google.common.util.concurrent.ListeningExecutorService;
+import com.google.common.util.concurrent.MoreExecutors;
+
+/**
+ * Customers ask about the scalability of Brooklyn. These load tests investigate how many
+ * concurrent apps can be deployed and managed by a single Brooklyn management node.
+ *
+ * The apps are "simulated" in that they don't create the underlying resources
+ * (we are not checking if the test machine can run 100s of app-servers simultaneously!)
+ * The install/customize/launch will instead execute ssh commands of comparable length,
+ * but that just echo rather than execute the actual commands.
+ *
+ * "SIMULATE_EXTERNAL_MONITORING" means that we do not poll the entities directly (over ssh, http or
+ * whatever). Instead we simulate the metrics being injected directly to be set on the entity (e.g.
+ * having been collected from a Graphite server).
+ *
+ * "SKIP_SSH_ON_START" means don't do the normal install+customize+launch ssh commands. Instead, just
+ * startup the entities so we can monitor their resource usage.
+ */
+public class LoadTest {
+
+ // TODO Could/should issue provisioning request through REST api, rather than programmatically;
+ // and poll to detect completion.
+
+ /*
+ * Useful commands when investigating:
+ * LOG_FILE=usage/qa/brooklyn-camp-tests.log
+ * grep -E "OutOfMemoryError|[P|p]rovisioning time|sleeping before|CPU fraction|LoadTest using" $LOG_FILE | less
+ * grep -E "OutOfMemoryError|[P|p]rovisioning time" $LOG_FILE; grep "CPU fraction" $LOG_FILE | tail -1; grep "LoadTest using" $LOG_FILE | tail -1
+ * grep -E "OutOfMemoryError|LoadTest using" $LOG_FILE
+ */
+ private static final Logger LOG = LoggerFactory.getLogger(LoadTest.class);
+
+ private File persistenceDir;
+ private BrooklynLauncher launcher;
+ private String webServerUrl;
+ private ManagementContext managementContext;
+ private ListeningExecutorService executor;
+ private Future<?> cpuFuture;
+
+ private Location localhost;
+
+ List<Duration> provisioningTimes;
+
+
+ @BeforeMethod(alwaysRun=true)
+ public void setUp() throws Exception {
+ // Create management node
+ persistenceDir = Files.createTempDir();
+ launcher = BrooklynLauncher.newInstance()
+ .persistMode(PersistMode.CLEAN)
+ .highAvailabilityMode(HighAvailabilityMode.MASTER)
+ .persistenceDir(persistenceDir)
+ .start();
+ webServerUrl = launcher.getServerDetails().getWebServerUrl();
+ managementContext = launcher.getServerDetails().getManagementContext();
+
+ localhost = managementContext.getLocationRegistry().resolve("localhost");
+
+ provisioningTimes = Collections.synchronizedList(Lists.<Duration>newArrayList());
+
+ // Create executors
+ executor = MoreExecutors.listeningDecorator(Executors.newCachedThreadPool());
+
+ // Monitor utilisation (memory/CPU) while tests run
+ executor.submit(new Callable<Void>() {
+ public Void call() {
+ try {
+ while (true) {
+ managementContext.getExecutionManager(); // force GC to be instantiated
+ String usage = ((LocalManagementContext)managementContext).getGarbageCollector().getUsageString();
+ LOG.info("LoadTest using "+usage);
+ Thread.sleep(1000);
+ }
+ } catch (InterruptedException e) {
+ Thread.currentThread().interrupt(); // exit gracefully
+ } catch (Exception e) {
+ LOG.error("Error getting usage info", e);
+ }
+ return null;
+ }});
+
+ cpuFuture = PerformanceTestUtils.sampleProcessCpuTime(Duration.ONE_SECOND, "during testProvisionAppsConcurrently");
+
+ }
+
+ @AfterMethod(alwaysRun=true)
+ public void tearDown() throws Exception {
+ if (cpuFuture != null) cpuFuture.cancel(true);
+ if (executor != null) executor.shutdownNow();
+ if (launcher != null) launcher.terminate();
+ if (persistenceDir != null) Os.deleteRecursively(persistenceDir);
+ }
+
+ /**
+ * Creates multiple apps simultaneously.
+ *
+ * Long-term target is 50 concurrent provisioning requests (which may be issued while there are
+ * many existing applications under management). Until we reach that point, we can partition the
+ * load across multiple (separate) brooklyn management nodes.
+ * TODO TBD: is that 50 VMs worth, or 50 apps with 4 VMs in each?
+ *
+ * TODO Does not measure the cost of jclouds for creating all the VMs/containers.
+ */
+ @Test(groups="Acceptance")
+ public void testLocalhostProvisioningAppsConcurrently() throws Exception {
+ final int NUM_CONCURRENT_APPS_PROVISIONING = 20;
+
+ List<ListenableFuture<StartableApplication>> futures = Lists.newArrayList();
+ for (int i = 0; i < NUM_CONCURRENT_APPS_PROVISIONING; i++) {
+ ListenableFuture<StartableApplication> future = executor.submit(newProvisionAppTask(managementContext,
+ EntitySpec.create(StartableApplication.class, SimulatedTheeTierApp.class)
+ .configure(SimulatedTheeTierApp.SIMULATE_EXTERNAL_MONITORING, true)
+ .displayName("Simulated app "+i)));
+ futures.add(future);
+ }
+
+ List<StartableApplication> apps = Futures.allAsList(futures).get();
+
+ for (StartableApplication app : apps) {
+ assertEquals(app.getAttribute(Startable.SERVICE_UP), (Boolean)true);
+ }
+ }
+
+ /**
+ * Creates many apps, to monitor resource usage etc.
+ *
+ * "SIMULATE_EXTERNAL_MONITORING" means that we do not poll the entities directly (over ssh, http or
+ * whatever). Instead we simulate the metrics being injected directly to be set on the entity (e.g.
+ * having been collected from a Graphite server).
+ *
+ * Long-term target is 2500 VMs under management.
+ * Until we reach that point, we can partition the load across multiple (separate) brooklyn management nodes.
+ */
+ @Test(groups="Acceptance")
+ public void testLocalhostManyApps() throws Exception {
+ final int NUM_APPS = 630; // target is 2500 VMs; each blueprint has 4 (rounding up)
+ final int NUM_APPS_PER_BATCH = 10;
+ final int SLEEP_BETWEEN_BATCHES = 10*1000;
+ final boolean SKIP_SSH_ON_START = true; // getting ssh errors otherwise!
+
+ int counter = 0;
+
+ for (int i = 0; i < NUM_APPS / NUM_APPS_PER_BATCH; i++) {
+ List<ListenableFuture<StartableApplication>> futures = Lists.newArrayList();
+ for (int j = 0; j < NUM_APPS_PER_BATCH; j++) {
+ ListenableFuture<StartableApplication> future = executor.submit(newProvisionAppTask(
+ managementContext,
+ EntitySpec.create(StartableApplication.class, SimulatedTheeTierApp.class)
+ .configure(SimulatedTheeTierApp.SIMULATE_EXTERNAL_MONITORING, true)
+ .configure(SimulatedTheeTierApp.SKIP_SSH_ON_START, SKIP_SSH_ON_START)
+ .displayName("Simulated app "+(++counter))));
+ futures.add(future);
+ }
+
+ List<StartableApplication> apps = Futures.allAsList(futures).get();
+
+ for (StartableApplication app : apps) {
+ assertEquals(app.getAttribute(Startable.SERVICE_UP), (Boolean)true);
+ }
+
+ synchronized (provisioningTimes) {
+ LOG.info("cycle="+i+"; numApps="+counter+": provisioning times: "+provisioningTimes);
+ provisioningTimes.clear();
+ }
+
+ LOG.info("cycle="+i+"; numApps="+counter+": sleeping before next batch of apps");
+ Thread.sleep(SLEEP_BETWEEN_BATCHES);
+ }
+ }
+
+ protected <T extends StartableApplication> Callable<T> newProvisionAppTask(final ManagementContext managementContext, final EntitySpec<T> entitySpec) {
+ return new Callable<T>() {
+ public T call() {
+ Stopwatch stopwatch = Stopwatch.createStarted();
+ T app = managementContext.getEntityManager().createEntity(entitySpec);
+ Entities.startManagement(app, managementContext);
+ app.start(ImmutableList.of(localhost));
+ Duration duration = Duration.of(stopwatch.elapsed(TimeUnit.MILLISECONDS), TimeUnit.MILLISECONDS);
+ LOG.info("Provisioning time: "+duration);
+ provisioningTimes.add(duration);
+
+ return app;
+ }
+ };
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/bd44bb8f/usage/qa/src/test/java/org/apache/brooklyn/qa/longevity/MonitorUtilsTest.java
----------------------------------------------------------------------
diff --git a/usage/qa/src/test/java/org/apache/brooklyn/qa/longevity/MonitorUtilsTest.java b/usage/qa/src/test/java/org/apache/brooklyn/qa/longevity/MonitorUtilsTest.java
new file mode 100644
index 0000000..cf377e9
--- /dev/null
+++ b/usage/qa/src/test/java/org/apache/brooklyn/qa/longevity/MonitorUtilsTest.java
@@ -0,0 +1,166 @@
+/*
+ * 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.qa.longevity;
+
+import org.apache.brooklyn.qa.longevity.MonitorUtils;
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertFalse;
+import static org.testng.Assert.assertTrue;
+import static org.testng.Assert.fail;
+
+import java.io.File;
+import java.io.IOException;
+import java.net.URL;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+
+import org.testng.annotations.Test;
+
+import org.apache.brooklyn.qa.longevity.MonitorUtils.ProcessHasStderr;
+import brooklyn.util.os.Os;
+import brooklyn.util.text.Strings;
+
+import com.google.common.base.Charsets;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.io.Files;
+
+public class MonitorUtilsTest {
+
+ @Test(enabled=false, timeOut=1000) // Demonstrates that process.waitFor() hangs for big output streams
+ public void testExecuteAndWaitFor() throws Exception {
+ Process process = createDumpingProcess(false);
+ process.waitFor();
+ fail("Should block while waiting to consume process output");
+ }
+
+ @Test(enabled=false, timeOut=1000) // Demonstrates that process.waitFor() hangs for big err streams
+ public void testExecuteAndWaitForErr() throws Exception {
+ Process process = createDumpingProcess(true);
+ process.waitFor();
+ fail("Should block while waiting to consume process output");
+ }
+
+ @Test(timeOut=1000)
+ public void testExecuteAndWaitForConsumingOutputStream() throws Exception {
+ Process process = createDumpingProcess(false);
+ String out = MonitorUtils.waitFor(process);
+ assertTrue(out.length() > 100000, "out.size="+out.length());
+ }
+
+ @Test(timeOut=1000, expectedExceptions=IllegalStateException.class)
+ public void testExecuteAndWaitForConsumingErrorStream() throws Exception {
+ Process process = createDumpingProcess(true);
+ MonitorUtils.waitFor(process);
+ }
+
+ private Process createDumpingProcess(boolean writeToErr) throws IOException {
+ String errSuffix = writeToErr ? " >&2" : "";
+ //Windows limits the length of the arguments so echo multiple times instead
+ String bigstr = Strings.repeat("a", 8000);
+ String bigcmd = Strings.repeat(getSilentPrefix() + "echo " + bigstr + errSuffix + Os.LINE_SEPARATOR, 15);
+ File file = Os.newTempFile("test-consume", ".bat");
+ file.setExecutable(true);
+ Files.write(bigcmd, file, Charsets.UTF_8);
+ Process process = MonitorUtils.exec(file.getAbsolutePath());
+ return process;
+ }
+
+ @Test(groups="UNIX")
+ public void testFindOwnPid() throws Exception {
+ int ownpid = MonitorUtils.findOwnPid();
+ assertTrue(ownpid > 0, "ownpid=$ownpid");
+ assertTrue(MonitorUtils.isPidRunning(ownpid, "java"),"java is not running");
+ }
+
+ @Test(groups="UNIX")
+ public void testIsPidRunning() throws Exception {
+ int usedPid = MonitorUtils.findOwnPid();
+
+ //the child process will terminate freeing it PID
+ String[] cmd = new String[]{"bash", "-c", "echo $$"};
+ Process process = Runtime.getRuntime().exec(cmd);
+ String out = MonitorUtils.waitFor(process);
+ int unusedPid = Integer.parseInt(out.trim());
+
+ assertTrue(MonitorUtils.isPidRunning(usedPid));
+ assertFalse(MonitorUtils.isPidRunning(unusedPid));
+
+ try {
+ assertFalse(MonitorUtils.isPidRunning(1234567)); // too large
+ } catch (ProcessHasStderr e) {
+ // expected on osx
+ }
+ }
+
+ @Test(groups="UNIX")
+ public void testGetRunningPids() throws Exception {
+ int ownpid = MonitorUtils.findOwnPid();
+
+ List<Integer> javapids = MonitorUtils.getRunningPids("java");
+
+ assertTrue(javapids.contains(ownpid), "javapids="+javapids+"; ownpid="+ownpid);
+ }
+
+ @Test
+ public void testIsUrlUp() throws Exception {
+ assertFalse(MonitorUtils.isUrlUp(new URL("http://localhost/thispathdoesnotexist")));
+ }
+
+ @Test(groups="UNIX")
+ public void testSearchLog() throws Exception {
+ String fileContents = "line1\nline2\nline3\n";
+ File file = File.createTempFile("monitorUtilsTest.testSearchLog", ".txt");
+ Files.write(fileContents, file, Charsets.UTF_8);
+
+ try {
+ assertEquals(MonitorUtils.searchLog(file, "line1"), Arrays.asList("line1"));
+ assertEquals(MonitorUtils.searchLog(file, "line1|line2"), Arrays.asList("line1", "line2"));
+ assertEquals(MonitorUtils.searchLog(file, "textnotthere"), Collections.emptyList());
+ assertEquals(MonitorUtils.searchLog(file, "line"), Arrays.asList("line1", "line2", "line3"));
+ } finally {
+ file.delete();
+ }
+ }
+
+ @Test(groups="Integration")
+ public void testMemoryUsage() throws Exception {
+ int ownpid = MonitorUtils.findOwnPid();
+
+ MonitorUtils.MemoryUsage memUsage = MonitorUtils.getMemoryUsage(ownpid);
+ assertTrue(memUsage.totalInstances > 0, memUsage.toString());
+ assertTrue(memUsage.totalMemoryBytes > 0, memUsage.toString());
+ assertEquals(memUsage.getInstanceCounts(), Collections.emptyMap());
+
+ MonitorUtils.MemoryUsage memUsage2 = MonitorUtils.getMemoryUsage(ownpid, MonitorUtilsTest.class.getCanonicalName(),0);
+ assertEquals(memUsage2.getInstanceCounts(), ImmutableMap.of(MonitorUtilsTest.class.getCanonicalName(), 1));
+
+ MonitorUtils.MemoryUsage memUsage3 = MonitorUtils.getMemoryUsage(ownpid, MonitorUtilsTest.class.getCanonicalName(), 2);
+ assertEquals(memUsage3.getInstanceCounts(), Collections.emptyMap());
+ }
+
+ private String getSilentPrefix() {
+ if (Os.isMicrosoftWindows()) {
+ return "@";
+ } else {
+ return "";
+ }
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/bd44bb8f/usage/qa/src/test/java/org/apache/brooklyn/qa/longevity/webcluster/SinusoidalLoadGenerator.java
----------------------------------------------------------------------
diff --git a/usage/qa/src/test/java/org/apache/brooklyn/qa/longevity/webcluster/SinusoidalLoadGenerator.java b/usage/qa/src/test/java/org/apache/brooklyn/qa/longevity/webcluster/SinusoidalLoadGenerator.java
new file mode 100644
index 0000000..17e7a32
--- /dev/null
+++ b/usage/qa/src/test/java/org/apache/brooklyn/qa/longevity/webcluster/SinusoidalLoadGenerator.java
@@ -0,0 +1,90 @@
+/*
+ * 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.qa.longevity.webcluster;
+
+import java.util.concurrent.Executors;
+import java.util.concurrent.ScheduledExecutorService;
+import java.util.concurrent.TimeUnit;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import brooklyn.config.ConfigKey;
+import brooklyn.enricher.basic.AbstractEnricher;
+import brooklyn.entity.basic.ConfigKeys;
+import brooklyn.entity.basic.EntityLocal;
+import brooklyn.event.AttributeSensor;
+
+import com.google.common.base.Throwables;
+import com.google.common.reflect.TypeToken;
+
+/**
+ * Periodically publishes values in the range of 0 to #amplitude.
+ * The value varies sinusoidally over time.
+ */
+public class SinusoidalLoadGenerator extends AbstractEnricher {
+
+ private static final Logger LOG = LoggerFactory.getLogger(SinusoidalLoadGenerator.class);
+
+ public static final ConfigKey<AttributeSensor<Double>> TARGET = ConfigKeys.newConfigKey(new TypeToken<AttributeSensor<Double>>() {}, "target");
+
+ public static final ConfigKey<Long> PUBLISH_PERIOD_MS = ConfigKeys.newLongConfigKey("publishPeriodMs");
+
+ public static final ConfigKey<Long> SIN_PERIOD_MS = ConfigKeys.newLongConfigKey("sinPeriodMs");
+
+ public static final ConfigKey<Double> SIN_AMPLITUDE = ConfigKeys.newDoubleConfigKey("sinAmplitude");
+
+ private final ScheduledExecutorService executor;
+
+ public SinusoidalLoadGenerator() {
+ this.executor = Executors.newSingleThreadScheduledExecutor();
+ }
+
+ public SinusoidalLoadGenerator(AttributeSensor<Double> target, long publishPeriodMs, long sinPeriodMs, double sinAmplitude) {
+ config().set(TARGET, target);
+ config().set(PUBLISH_PERIOD_MS, publishPeriodMs);
+ config().set(SIN_PERIOD_MS, sinPeriodMs);
+ config().set(SIN_AMPLITUDE, sinAmplitude);
+ this.executor = Executors.newSingleThreadScheduledExecutor();
+ }
+
+ @Override
+ public void setEntity(final EntityLocal entity) {
+ super.setEntity(entity);
+
+ executor.scheduleAtFixedRate(new Runnable() {
+ @Override public void run() {
+ try {
+ long time = System.currentTimeMillis();
+ double val = getRequiredConfig(SIN_AMPLITUDE) * (1 + Math.sin( (1.0*time) / getRequiredConfig(SIN_PERIOD_MS) * Math.PI * 2 - Math.PI/2 )) / 2;
+ entity.setAttribute(getRequiredConfig(TARGET), val);
+ } catch (Throwable t) {
+ LOG.warn("Error generating sinusoidal-load metric", t);
+ throw Throwables.propagate(t);
+ }
+ }
+
+ }, 0, getRequiredConfig(PUBLISH_PERIOD_MS), TimeUnit.MILLISECONDS);
+ }
+
+ @Override
+ public void destroy() {
+ executor.shutdownNow();
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/bd44bb8f/usage/qa/src/test/java/org/apache/brooklyn/qa/longevity/webcluster/WebClusterApp.java
----------------------------------------------------------------------
diff --git a/usage/qa/src/test/java/org/apache/brooklyn/qa/longevity/webcluster/WebClusterApp.java b/usage/qa/src/test/java/org/apache/brooklyn/qa/longevity/webcluster/WebClusterApp.java
new file mode 100644
index 0000000..0d3d694
--- /dev/null
+++ b/usage/qa/src/test/java/org/apache/brooklyn/qa/longevity/webcluster/WebClusterApp.java
@@ -0,0 +1,101 @@
+/*
+ * 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.qa.longevity.webcluster;
+
+import java.util.List;
+
+import brooklyn.config.BrooklynProperties;
+import brooklyn.enricher.Enrichers;
+import brooklyn.entity.basic.AbstractApplication;
+import brooklyn.entity.basic.Entities;
+import brooklyn.entity.basic.StartableApplication;
+import brooklyn.entity.proxy.nginx.NginxController;
+import brooklyn.entity.proxying.EntitySpec;
+import brooklyn.entity.webapp.ControlledDynamicWebAppCluster;
+import brooklyn.entity.webapp.jboss.JBoss7Server;
+import brooklyn.event.AttributeSensor;
+import brooklyn.event.basic.Sensors;
+import brooklyn.launcher.BrooklynLauncher;
+import brooklyn.policy.EnricherSpec;
+import brooklyn.policy.autoscaling.AutoScalerPolicy;
+import brooklyn.util.CommandLineUtil;
+
+import com.google.common.collect.Lists;
+
+public class WebClusterApp extends AbstractApplication {
+
+ static BrooklynProperties config = BrooklynProperties.Factory.newDefault();
+
+ public static final String WAR_PATH = "classpath://hello-world.war";
+
+ private static final long loadCyclePeriodMs = 2 * 60 * 1000L;
+
+ @Override
+ public void initApp() {
+ final AttributeSensor<Double> sinusoidalLoad =
+ Sensors.newDoubleSensor("brooklyn.qa.sinusoidalLoad", "Sinusoidal server load");
+ AttributeSensor<Double> averageLoad =
+ Sensors.newDoubleSensor("brooklyn.qa.averageLoad", "Average load in cluster");
+
+ NginxController nginxController = addChild(EntitySpec.create(NginxController.class)
+ // .configure("domain", "webclusterexample.brooklyn.local")
+ .configure("port", "8000+"));
+
+ EntitySpec<JBoss7Server> jbossSpec = EntitySpec.create(JBoss7Server.class)
+ .configure("httpPort", "8080+")
+ .configure("war", WAR_PATH)
+ .enricher(EnricherSpec.create(SinusoidalLoadGenerator.class)
+ .configure(SinusoidalLoadGenerator.TARGET, sinusoidalLoad)
+ .configure(SinusoidalLoadGenerator.PUBLISH_PERIOD_MS, 500L)
+ .configure(SinusoidalLoadGenerator.SIN_PERIOD_MS, loadCyclePeriodMs)
+ .configure(SinusoidalLoadGenerator.SIN_AMPLITUDE, 1d));
+
+ ControlledDynamicWebAppCluster web = addChild(EntitySpec.create(ControlledDynamicWebAppCluster.class)
+ .displayName("WebApp cluster")
+ .configure("controller", nginxController)
+ .configure("initialSize", 1)
+ .configure("memberSpec", jbossSpec));
+
+ web.getCluster().addEnricher(Enrichers.builder()
+ .aggregating(sinusoidalLoad)
+ .publishing(averageLoad)
+ .fromMembers()
+ .computingAverage()
+ .build());
+ web.getCluster().addPolicy(AutoScalerPolicy.builder()
+ .metric(averageLoad)
+ .sizeRange(1, 3)
+ .metricRange(0.3, 0.7)
+ .build());
+ }
+
+ public static void main(String[] argv) {
+ List<String> args = Lists.newArrayList(argv);
+ String port = CommandLineUtil.getCommandLineOption(args, "--port", "8081+");
+ String location = CommandLineUtil.getCommandLineOption(args, "--location", "localhost");
+
+ BrooklynLauncher launcher = BrooklynLauncher.newInstance()
+ .application(EntitySpec.create(StartableApplication.class, WebClusterApp.class).displayName("Brooklyn WebApp Cluster example"))
+ .webconsolePort(port)
+ .location(location)
+ .start();
+
+ Entities.dumpInfo(launcher.getApplications());
+ }
+}
[02/12] incubator-brooklyn git commit: brooklyn-qa: add org.apache
package prefix
Posted by al...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/bd44bb8f/usage/qa/src/main/java/org/apache/brooklyn/qa/load/SimulatedMySqlNodeImpl.java
----------------------------------------------------------------------
diff --git a/usage/qa/src/main/java/org/apache/brooklyn/qa/load/SimulatedMySqlNodeImpl.java b/usage/qa/src/main/java/org/apache/brooklyn/qa/load/SimulatedMySqlNodeImpl.java
new file mode 100644
index 0000000..8a24f73
--- /dev/null
+++ b/usage/qa/src/main/java/org/apache/brooklyn/qa/load/SimulatedMySqlNodeImpl.java
@@ -0,0 +1,183 @@
+/*
+ * 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.qa.load;
+
+import static java.lang.String.format;
+
+import java.util.concurrent.Callable;
+
+import brooklyn.config.ConfigKey;
+import brooklyn.entity.basic.AbstractSoftwareProcessSshDriver;
+import brooklyn.entity.database.mysql.MySqlNode;
+import brooklyn.entity.database.mysql.MySqlNodeImpl;
+import brooklyn.entity.database.mysql.MySqlSshDriver;
+import brooklyn.entity.software.SshEffectorTasks;
+import brooklyn.event.feed.function.FunctionFeed;
+import brooklyn.event.feed.function.FunctionPollConfig;
+import brooklyn.location.basic.SshMachineLocation;
+import brooklyn.util.collections.MutableMap;
+import brooklyn.util.task.DynamicTasks;
+import brooklyn.util.task.system.ProcessTaskWrapper;
+import brooklyn.util.time.CountdownTimer;
+import brooklyn.util.time.Duration;
+
+/**
+ * @see SimulatedJBoss7ServerImpl for description of purpose and configuration options.
+ */
+public class SimulatedMySqlNodeImpl extends MySqlNodeImpl {
+
+ public static final ConfigKey<Boolean> SIMULATE_ENTITY = SimulatedTheeTierApp.SIMULATE_ENTITY;
+ public static final ConfigKey<Boolean> SIMULATE_EXTERNAL_MONITORING = SimulatedTheeTierApp.SIMULATE_EXTERNAL_MONITORING;
+ public static final ConfigKey<Boolean> SKIP_SSH_ON_START = SimulatedTheeTierApp.SKIP_SSH_ON_START;
+
+ private FunctionFeed feed;
+
+ @Override
+ public Class<?> getDriverInterface() {
+ return SimulatedMySqlSshDriver.class;
+ }
+
+ @Override
+ protected void connectSensors() {
+ boolean simulateExternalMonitoring = getConfig(SIMULATE_EXTERNAL_MONITORING);
+ if (simulateExternalMonitoring) {
+ setAttribute(DATASTORE_URL, String.format("mysql://%s:%s/", getAttribute(HOSTNAME), getAttribute(MYSQL_PORT)));
+
+ feed = FunctionFeed.builder()
+ .entity(this)
+ .period(Duration.FIVE_SECONDS)
+ .poll(new FunctionPollConfig<Boolean, Boolean>(SERVICE_UP)
+ .callable(new Callable<Boolean>() {
+ private int counter = 0;
+ public Boolean call() {
+ setAttribute(QUERIES_PER_SECOND_FROM_MYSQL, (double)(counter++ % 100));
+ return true;
+ }})
+ .setOnFailureOrException(false))
+ .build();
+ } else {
+ super.connectSensors();
+ }
+ }
+
+ public static class SimulatedMySqlSshDriver extends MySqlSshDriver {
+
+ private int counter = 0;
+
+ public SimulatedMySqlSshDriver(SimulatedMySqlNodeImpl entity, SshMachineLocation machine) {
+ super(entity, machine);
+ }
+
+ // simulate metrics, for if using ssh polling
+ @Override
+ public String getStatusCmd() {
+ if (entity.getConfig(SIMULATE_ENTITY)) {
+ return "echo Uptime: 2427 Threads: 1 Questions: 581 Slow queries: 0 Opens: 53 Flush tables: 1 Open tables: 35 Queries per second avg: "+(counter++ % 100);
+ } else {
+ return super.getStatusCmd();
+ }
+ }
+
+ @Override
+ public void install() {
+ if (entity.getConfig(SKIP_SSH_ON_START)) {
+ // no-op
+ } else {
+ super.install();
+ }
+ }
+
+ // Not applying creation-script etc, as that requires launching msyqld (so would not scale for single-machine testing)
+ // This is a copy of super.customize, but with the mysqladmin-exec disabled
+ @Override
+ public void customize() {
+ if (!entity.getConfig(SIMULATE_ENTITY)) {
+ super.customize();
+ return;
+ } else if (entity.getConfig(SKIP_SSH_ON_START)) {
+ // no-op
+ } else {
+ copyDatabaseConfigScript();
+
+ newScript(CUSTOMIZING)
+ .updateTaskAndFailOnNonZeroResultCode()
+ .body.append(
+ "chmod 600 "+getConfigFile(),
+ getBaseDir()+"/scripts/mysql_install_db "+
+ "--basedir="+getBaseDir()+" --datadir="+getDataDir()+" "+
+ "--defaults-file="+getConfigFile())
+ .execute();
+
+ // launch, then we will configure it
+ launch();
+
+ CountdownTimer timer = Duration.seconds(20).countdownTimer();
+ boolean hasCreationScript = copyDatabaseCreationScript();
+ timer.waitForExpiryUnchecked();
+
+ // DELIBERATELY SKIPPED FOR SCALABILITY TESTING ON SINGLE MACHINE
+ DynamicTasks.queue(
+ SshEffectorTasks.ssh(
+ "cd "+getRunDir(),
+ "echo skipping exec of "+getBaseDir()+"/bin/mysqladmin --defaults-file="+getConfigFile()+" --password= password "+getPassword()
+ ).summary("setting password"));
+
+ if (hasCreationScript)
+ executeScriptFromInstalledFileAsync("creation-script.sql");
+
+ // not sure necessary to stop then subsequently launch, but seems safest
+ // (if skipping, use a flag in launch to indicate we've just launched it)
+ stop();
+ }
+ }
+
+ @Override
+ public void launch() {
+ if (!entity.getConfig(SIMULATE_ENTITY)) {
+ super.launch();
+ return;
+ }
+
+ entity.setAttribute(MySqlNode.PID_FILE, getRunDir() + "/" + AbstractSoftwareProcessSshDriver.PID_FILENAME);
+
+ if (entity.getConfig(SKIP_SSH_ON_START)) {
+ // minimal ssh, so that isRunning will subsequently work
+ newScript(MutableMap.of("usePidFile", true), LAUNCHING)
+ .body.append(
+ format("nohup sleep 100000 > %s 2>&1 < /dev/null &", getLogFile()))
+ .execute();
+ } else {
+ newScript(MutableMap.of("usePidFile", true), LAUNCHING)
+ .updateTaskAndFailOnNonZeroResultCode()
+ .body.append(format("echo skipping normal exec of nohup %s/bin/mysqld --defaults-file=%s --user=`whoami` > %s 2>&1 < /dev/null &", getBaseDir(), getConfigFile(), getLogFile()))
+ .body.append(format("nohup sleep 100000 > %s 2>&1 < /dev/null &", getLogFile()))
+ .execute();
+ }
+ }
+
+ @Override
+ public ProcessTaskWrapper<Integer> executeScriptFromInstalledFileAsync(String filenameAlreadyInstalledAtServer) {
+ return DynamicTasks.queue(
+ SshEffectorTasks.ssh(
+ "cd "+getRunDir(),
+ "echo skipping exec of "+getBaseDir()+"/bin/mysql --defaults-file="+getConfigFile()+" < "+filenameAlreadyInstalledAtServer)
+ .summary("executing datastore script "+filenameAlreadyInstalledAtServer));
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/bd44bb8f/usage/qa/src/main/java/org/apache/brooklyn/qa/load/SimulatedNginxControllerImpl.java
----------------------------------------------------------------------
diff --git a/usage/qa/src/main/java/org/apache/brooklyn/qa/load/SimulatedNginxControllerImpl.java b/usage/qa/src/main/java/org/apache/brooklyn/qa/load/SimulatedNginxControllerImpl.java
new file mode 100644
index 0000000..8813a4f
--- /dev/null
+++ b/usage/qa/src/main/java/org/apache/brooklyn/qa/load/SimulatedNginxControllerImpl.java
@@ -0,0 +1,196 @@
+/*
+ * 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.qa.load;
+
+import static java.lang.String.format;
+
+import java.net.URI;
+import java.util.Collection;
+import java.util.concurrent.Callable;
+
+import brooklyn.config.ConfigKey;
+import brooklyn.entity.Group;
+import brooklyn.entity.proxy.nginx.NginxControllerImpl;
+import brooklyn.entity.proxy.nginx.NginxSshDriver;
+import brooklyn.entity.proxy.nginx.UrlMapping;
+import brooklyn.event.SensorEvent;
+import brooklyn.event.SensorEventListener;
+import brooklyn.event.feed.ConfigToAttributes;
+import brooklyn.event.feed.function.FunctionFeed;
+import brooklyn.event.feed.function.FunctionPollConfig;
+import brooklyn.event.feed.http.HttpFeed;
+import brooklyn.event.feed.http.HttpPollConfig;
+import brooklyn.location.basic.SshMachineLocation;
+import brooklyn.policy.PolicySpec;
+import brooklyn.util.collections.MutableMap;
+import brooklyn.util.net.Networking;
+
+import com.google.common.base.Functions;
+
+/**
+ * @see SimulatedJBoss7ServerImpl for description of purpose and configuration options.
+ */
+public class SimulatedNginxControllerImpl extends NginxControllerImpl {
+
+ public static final ConfigKey<Boolean> SIMULATE_ENTITY = SimulatedTheeTierApp.SIMULATE_ENTITY;
+ public static final ConfigKey<Boolean> SIMULATE_EXTERNAL_MONITORING = SimulatedTheeTierApp.SIMULATE_EXTERNAL_MONITORING;
+ public static final ConfigKey<Boolean> SKIP_SSH_ON_START = SimulatedTheeTierApp.SKIP_SSH_ON_START;
+
+ private HttpFeed httpFeed;
+ private FunctionFeed functionFeed;
+
+ @Override
+ public Class<?> getDriverInterface() {
+ return SimulatedNginxSshDriver.class;
+ }
+
+ @Override
+ public void connectSensors() {
+ boolean simulateEntity = getConfig(SIMULATE_ENTITY);
+ boolean simulateExternalMonitoring = getConfig(SIMULATE_EXTERNAL_MONITORING);
+
+ if (!simulateEntity && !simulateExternalMonitoring) {
+ super.connectSensors();
+ return;
+ }
+
+ // From AbstractController.connectSensors
+ if (getUrl()==null) {
+ setAttribute(MAIN_URI, URI.create(inferUrl()));
+ setAttribute(ROOT_URL, inferUrl());
+ }
+ addServerPoolMemberTrackingPolicy();
+
+ // From NginxController.connectSensors
+ ConfigToAttributes.apply(this);
+
+ if (!simulateExternalMonitoring) {
+ // if simulating entity, then simulate work of periodic HTTP request; TODO but not parsing JSON response
+ String uriToPoll = (simulateEntity) ? "http://localhost:8081" : getAttribute(MAIN_URI).toString();
+
+ httpFeed = HttpFeed.builder()
+ .entity(this)
+ .period(getConfig(HTTP_POLL_PERIOD))
+ .baseUri(uriToPoll)
+ .poll(new HttpPollConfig<Boolean>(SERVICE_UP)
+ .onSuccess(Functions.constant(true))
+ .onFailureOrException(Functions.constant(true)))
+ .build();
+ }
+
+ functionFeed = FunctionFeed.builder()
+ .entity(this)
+ .period(getConfig(HTTP_POLL_PERIOD))
+ .poll(new FunctionPollConfig<Boolean,Boolean>(SERVICE_UP)
+ .callable(new Callable<Boolean>() {
+ public Boolean call() {
+ return true;
+ }}))
+ .build();
+
+ // Can guarantee that parent/managementContext has been set
+ Group urlMappings = getConfig(URL_MAPPINGS);
+ if (urlMappings != null) {
+ // Listen to the targets of each url-mapping changing
+ subscribeToMembers(urlMappings, UrlMapping.TARGET_ADDRESSES, new SensorEventListener<Collection<String>>() {
+ @Override public void onEvent(SensorEvent<Collection<String>> event) {
+ updateNeeded();
+ }
+ });
+
+ // Listen to url-mappings being added and removed
+ urlMappingsMemberTrackerPolicy = addPolicy(PolicySpec.create(UrlMappingsMemberTrackerPolicy.class)
+ .configure("group", urlMappings));
+ }
+ }
+
+ @Override
+ protected void disconnectSensors() {
+ super.disconnectSensors();
+ if (httpFeed != null) httpFeed.stop();
+ if (functionFeed != null) functionFeed.stop();
+ }
+
+ public static class SimulatedNginxSshDriver extends NginxSshDriver {
+ public SimulatedNginxSshDriver(SimulatedNginxControllerImpl entity, SshMachineLocation machine) {
+ super(entity, machine);
+ }
+
+ @Override
+ public void install() {
+ if (entity.getConfig(SKIP_SSH_ON_START)) {
+ // no-op
+ } else {
+ super.install();
+ }
+ }
+
+ @Override
+ public void customize() {
+ if (entity.getConfig(SKIP_SSH_ON_START)) {
+ // no-op
+ } else {
+ super.customize();
+ }
+ }
+
+ @Override
+ public void launch() {
+ if (!entity.getConfig(SIMULATE_ENTITY)) {
+ super.launch();
+ return;
+ }
+
+ Networking.checkPortsValid(MutableMap.of("httpPort", getPort()));
+
+ if (entity.getConfig(SKIP_SSH_ON_START)) {
+ // minimal ssh, so that isRunning will subsequently work
+ newScript(MutableMap.of("usePidFile", getPidFile()), LAUNCHING)
+ .body.append(
+ format("mkdir -p %s/logs", getRunDir()),
+ format("nohup sleep 100000 > %s 2>&1 < /dev/null &", getLogFileLocation()))
+ .execute();
+ } else {
+ newScript(MutableMap.of("usePidFile", false), LAUNCHING)
+ .body.append(
+ format("cd %s", getRunDir()),
+ "echo skipping exec of requireExecutable ./sbin/nginx",
+ sudoBashCIfPrivilegedPort(getPort(), format(
+ "echo skipping exec of nohup ./sbin/nginx -p %s/ -c conf/server.conf > %s 2>&1 &", getRunDir(), getLogFileLocation())),
+ format("nohup sleep 100000 > %s 2>&1 < /dev/null &", getLogFileLocation()),
+ format("echo $! > "+getPidFile()),
+ format("for i in {1..10}\n" +
+ "do\n" +
+ " test -f %1$s && ps -p `cat %1$s` && exit\n" +
+ " sleep 1\n" +
+ "done\n" +
+ "echo \"No explicit error launching nginx but couldn't find process by pid; continuing but may subsequently fail\"\n" +
+ "cat %2$s | tee /dev/stderr",
+ getPidFile(), getLogFileLocation()))
+ .execute();
+ }
+ }
+
+ // Use pid file, because just simulating the run of nginx
+ @Override
+ public void stop() {
+ newScript(MutableMap.of("usePidFile", getPidFile()), STOPPING).execute();
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/bd44bb8f/usage/qa/src/main/java/org/apache/brooklyn/qa/load/SimulatedTheeTierApp.java
----------------------------------------------------------------------
diff --git a/usage/qa/src/main/java/org/apache/brooklyn/qa/load/SimulatedTheeTierApp.java b/usage/qa/src/main/java/org/apache/brooklyn/qa/load/SimulatedTheeTierApp.java
new file mode 100644
index 0000000..273d130
--- /dev/null
+++ b/usage/qa/src/main/java/org/apache/brooklyn/qa/load/SimulatedTheeTierApp.java
@@ -0,0 +1,140 @@
+/*
+ * 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.qa.load;
+
+import static brooklyn.event.basic.DependentConfiguration.attributeWhenReady;
+import static brooklyn.event.basic.DependentConfiguration.formatString;
+
+import java.util.Collection;
+import java.util.List;
+
+import brooklyn.config.ConfigKey;
+import brooklyn.enricher.Enrichers;
+import brooklyn.enricher.HttpLatencyDetector;
+import brooklyn.entity.basic.AbstractApplication;
+import brooklyn.entity.basic.Attributes;
+import brooklyn.entity.basic.ConfigKeys;
+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.trait.Startable;
+import brooklyn.entity.webapp.ControlledDynamicWebAppCluster;
+import brooklyn.entity.webapp.DynamicWebAppCluster;
+import brooklyn.entity.webapp.JavaWebAppService;
+import brooklyn.entity.webapp.WebAppService;
+import brooklyn.entity.webapp.WebAppServiceConstants;
+import brooklyn.entity.webapp.jboss.JBoss7Server;
+import brooklyn.launcher.BrooklynLauncher;
+import brooklyn.location.basic.PortRanges;
+import brooklyn.policy.autoscaling.AutoScalerPolicy;
+import brooklyn.util.CommandLineUtil;
+import brooklyn.util.collections.MutableSet;
+
+import com.google.common.base.Function;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Lists;
+
+/**
+ * A 3-tier app where all components are just "simulated" - they don't actually run
+ * real app-servers or databases, instead just executing a "sleep" command to simulate
+ * the running process.
+ *
+ * This is useful for load testing, where we want to test the performance of Brooklyn
+ * rather than the ability to host many running app-servers.
+ *
+ * The app is based on WebClusterDatabaseExampleApp
+ *
+ * @see SimulatedJBoss7ServerImpl for description of purpose and configuration options.
+ */
+public class SimulatedTheeTierApp extends AbstractApplication {
+
+ public static final ConfigKey<Boolean> SIMULATE_ENTITY = ConfigKeys.newBooleanConfigKey("simulateEntity", "", true);
+
+ public static final ConfigKey<Boolean> SIMULATE_EXTERNAL_MONITORING = ConfigKeys.newBooleanConfigKey("simulateExternalMonitoring", "", true);
+
+ public static final ConfigKey<Boolean> SKIP_SSH_ON_START = ConfigKeys.newBooleanConfigKey("skipSshOnStart", "", false);
+
+ public static final String WAR_PATH = "classpath://hello-world.war";
+ public static final String DB_TABLE = "visitors";
+ public static final String DB_USERNAME = "brooklyn";
+ public static final String DB_PASSWORD = "br00k11n";
+ public static final boolean USE_HTTPS = false;
+
+ @Override
+ public void init() {
+ MySqlNode mysql = addChild(
+ EntitySpec.create(MySqlNode.class)
+ .impl(SimulatedMySqlNodeImpl.class));
+
+ ControlledDynamicWebAppCluster web = addChild(
+ EntitySpec.create(ControlledDynamicWebAppCluster.class)
+ .configure(ControlledDynamicWebAppCluster.MEMBER_SPEC, EntitySpec.create(JBoss7Server.class).impl(SimulatedJBoss7ServerImpl.class))
+ .configure(ControlledDynamicWebAppCluster.CONTROLLER_SPEC, EntitySpec.create(NginxController.class).impl(SimulatedNginxControllerImpl.class))
+ .configure(WebAppService.HTTP_PORT, PortRanges.fromString("8080+"))
+ .configure(JavaWebAppService.ROOT_WAR, WAR_PATH)
+ .configure(JavaEntityMethods.javaSysProp("brooklyn.example.db.url"),
+ formatString("jdbc:%s%s?user=%s\\&password=%s",
+ attributeWhenReady(mysql, MySqlNode.DATASTORE_URL), DB_TABLE, DB_USERNAME, DB_PASSWORD))
+ .configure(DynamicCluster.INITIAL_SIZE, 2)
+ .configure(WebAppService.ENABLED_PROTOCOLS, ImmutableSet.of(USE_HTTPS ? "https" : "http")) );
+
+ web.getCluster().addPolicy(AutoScalerPolicy.builder().
+ metric(DynamicWebAppCluster.REQUESTS_PER_SECOND_IN_WINDOW_PER_NODE).
+ metricRange(10, 100).
+ sizeRange(2, 5).
+ build());
+
+ addEnricher(Enrichers.builder()
+ .propagating(Attributes.MAIN_URI, WebAppServiceConstants.ROOT_URL,
+ DynamicWebAppCluster.REQUESTS_PER_SECOND_IN_WINDOW,
+ HttpLatencyDetector.REQUEST_LATENCY_IN_SECONDS_IN_WINDOW)
+ .from(web)
+ .build());
+
+ addEnricher(Enrichers.builder()
+ .aggregating(Startable.SERVICE_UP)
+ .publishing(Startable.SERVICE_UP)
+ .fromHardcodedProducers(ImmutableList.of(web, mysql))
+ .computing(new Function<Collection<Boolean>, Boolean>() {
+ @Override public Boolean apply(Collection<Boolean> input) {
+ return input != null && input.size() == 2 && MutableSet.copyOf(input).equals(ImmutableSet.of(true));
+ }})
+ .build());
+ }
+
+ public static void main(String[] argv) {
+ List<String> args = Lists.newArrayList(argv);
+ String port = CommandLineUtil.getCommandLineOption(args, "--port", "8081+");
+ String location = CommandLineUtil.getCommandLineOption(args, "--location", "localhost");
+
+ BrooklynLauncher launcher = BrooklynLauncher.newInstance()
+ .application(EntitySpec.create(StartableApplication.class, SimulatedTheeTierApp.class)
+ .displayName("Brooklyn WebApp Cluster with Database example"))
+ .webconsolePort(port)
+ .location(location)
+ .start();
+
+ Entities.dumpInfo(launcher.getApplications());
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/bd44bb8f/usage/qa/src/main/java/org/apache/brooklyn/qa/longevity/Monitor.java
----------------------------------------------------------------------
diff --git a/usage/qa/src/main/java/org/apache/brooklyn/qa/longevity/Monitor.java b/usage/qa/src/main/java/org/apache/brooklyn/qa/longevity/Monitor.java
new file mode 100644
index 0000000..7a3ea42
--- /dev/null
+++ b/usage/qa/src/main/java/org/apache/brooklyn/qa/longevity/Monitor.java
@@ -0,0 +1,261 @@
+/*
+ * 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.qa.longevity;
+
+import static org.apache.brooklyn.qa.longevity.StatusRecorder.Factory.chain;
+import static org.apache.brooklyn.qa.longevity.StatusRecorder.Factory.noop;
+import static org.apache.brooklyn.qa.longevity.StatusRecorder.Factory.toFile;
+import static org.apache.brooklyn.qa.longevity.StatusRecorder.Factory.toLog;
+import static java.util.concurrent.TimeUnit.SECONDS;
+
+import java.io.File;
+import java.io.IOException;
+import java.net.URL;
+import java.util.Collections;
+import java.util.List;
+import java.util.Set;
+import java.util.concurrent.Executors;
+import java.util.concurrent.ScheduledExecutorService;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicReference;
+
+import joptsimple.OptionParser;
+import joptsimple.OptionSet;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import brooklyn.util.collections.TimeWindowedList;
+import brooklyn.util.collections.TimestampedValue;
+import brooklyn.util.time.Duration;
+
+import com.google.common.base.Charsets;
+import com.google.common.base.Throwables;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Lists;
+import com.google.common.collect.Range;
+import com.google.common.io.Files;
+
+public class Monitor {
+
+ private static final Logger LOG = LoggerFactory.getLogger(Monitor.class);
+
+ private static final int checkPeriodMs = 1000;
+
+ private static final OptionParser parser = new OptionParser() {
+ {
+ acceptsAll(ImmutableList.of("help", "?", "h"), "show help");
+ accepts("webUrl", "Web-app url")
+ .withRequiredArg().ofType(URL.class);
+ accepts("brooklynPid", "Brooklyn pid")
+ .withRequiredArg().ofType(Integer.class);
+ accepts("logFile", "Brooklyn log file")
+ .withRequiredArg().ofType(File.class);
+ accepts("logGrep", "Grep in log file (defaults to 'SEVERE|ERROR|WARN|Exception|Error'")
+ .withRequiredArg().ofType(String.class);
+ accepts("logGrepExclusionsFile", "File of expressions to be ignored in log file")
+ .withRequiredArg().ofType(File.class);
+ accepts("webProcesses", "Name (for `ps ax | grep` of web-processes")
+ .withRequiredArg().ofType(String.class);
+ accepts("numWebProcesses", "Number of web-processes expected (e.g. 1 or 1-3)")
+ .withRequiredArg().ofType(String.class);
+ accepts("webProcessesCyclingPeriod", "The period (in seconds) for cycling through the range of numWebProcesses")
+ .withRequiredArg().ofType(Integer.class);
+ accepts("outFile", "File to write monitor status info")
+ .withRequiredArg().ofType(File.class);
+ accepts("abortOnError", "Exit the JVM on error, with exit code 1")
+ .withRequiredArg().ofType(Boolean.class);
+ }
+ };
+
+ public static void main(String[] argv) throws InterruptedException, IOException {
+ OptionSet options = parse(argv);
+
+ if (options == null || options.has("help")) {
+ parser.printHelpOn(System.out);
+ System.exit(0);
+ }
+
+ MonitorPrefs prefs = new MonitorPrefs();
+ prefs.webUrl = options.hasArgument("webUrl") ? (URL) options.valueOf("webUrl") : null;
+ prefs.brooklynPid = options.hasArgument("brooklynPid") ? (Integer) options.valueOf("brooklynPid") : -1;
+ prefs.logFile = options.hasArgument("logFile") ? (File) options.valueOf("logFile") : null;
+ prefs.logGrep = options.hasArgument("logGrep") ? (String) options.valueOf("logGrep") : "SEVERE|ERROR|WARN|Exception|Error";
+ prefs.logGrepExclusionsFile = options.hasArgument("logGrepExclusionsFile") ? (File) options.valueOf("logGrepExclusionsFile") : null;
+ prefs.webProcessesRegex = options.hasArgument("webProcesses") ? (String) options.valueOf("webProcesses") : null;
+ prefs.numWebProcesses = options.hasArgument("numWebProcesses") ? parseRange((String) options.valueOf("numWebProcesses")) : null;
+ prefs.webProcessesCyclingPeriod = options.hasArgument("webProcessesCyclingPeriod") ? (Integer) options.valueOf("webProcessesCyclingPeriod") : -1;
+ prefs.outFile = options.hasArgument("outFile") ? (File) options.valueOf("outFile") : null;
+ prefs.abortOnError = options.hasArgument("abortOnError") ? (Boolean) options.valueOf("abortOnError") : false;
+ Monitor main = new Monitor(prefs, MonitorListener.NOOP);
+ main.start();
+ }
+
+ private static Range<Integer> parseRange(String range) {
+ if (range.contains("-")) {
+ String[] parts = range.split("-");
+ return Range.closed(Integer.parseInt(parts[0]), Integer.parseInt(parts[1]));
+ } else {
+ return Range.singleton(Integer.parseInt(range));
+ }
+ }
+
+ private static OptionSet parse(String...argv) {
+ try {
+ return parser.parse(argv);
+ } catch (Exception e) {
+ System.out.println("Error in parsing options: " + e.getMessage());
+ return null;
+ }
+ }
+
+ private final MonitorPrefs prefs;
+ private final StatusRecorder recorder;
+ private final MonitorListener listener;
+
+ public Monitor(MonitorPrefs prefs, MonitorListener listener) {
+ this.prefs = prefs;
+ this.listener = listener;
+ this.recorder = chain(toLog(LOG), (prefs.outFile != null ? toFile(prefs.outFile) : noop()));
+ }
+
+ private void start() throws IOException {
+ LOG.info("Monitoring: "+prefs);
+ ScheduledExecutorService executor = Executors.newSingleThreadScheduledExecutor();
+
+ final AtomicReference<List<String>> previousLogLines = new AtomicReference<List<String>>(Collections.<String>emptyList());
+ final TimeWindowedList<Integer> numWebProcessesHistory = new TimeWindowedList<Integer>(
+ ImmutableMap.of("timePeriod", Duration.seconds(prefs.webProcessesCyclingPeriod), "minExpiredVals", 1));
+ final Set<String> logGrepExclusions = ImmutableSet.copyOf(Files.readLines(prefs.logGrepExclusionsFile, Charsets.UTF_8));
+
+ executor.scheduleAtFixedRate(new Runnable() {
+ @Override public void run() {
+ StatusRecorder.Record record = new StatusRecorder.Record();
+ StringBuilder failureMsg = new StringBuilder();
+ try {
+ if (prefs.brooklynPid > 0) {
+ boolean pidRunning = MonitorUtils.isPidRunning(prefs.brooklynPid, "java");
+ MonitorUtils.MemoryUsage memoryUsage = MonitorUtils.getMemoryUsage(prefs.brooklynPid, ".*brooklyn.*", 1000);
+ record.put("pidRunning", pidRunning);
+ record.put("totalMemoryBytes", memoryUsage.getTotalMemoryBytes());
+ record.put("totalMemoryInstances", memoryUsage.getTotalInstances());
+ record.put("instanceCounts", memoryUsage.getInstanceCounts());
+
+ if (!pidRunning) {
+ failureMsg.append("pid "+prefs.brooklynPid+" is not running"+"\n");
+ }
+ }
+ if (prefs.webUrl != null) {
+ boolean webUrlUp = MonitorUtils.isUrlUp(prefs.webUrl);
+ record.put("webUrlUp", webUrlUp);
+
+ if (!webUrlUp) {
+ failureMsg.append("web URL "+prefs.webUrl+" is not available"+"\n");
+ }
+ }
+ if (prefs.logFile != null) {
+ List<String> logLines = MonitorUtils.searchLog(prefs.logFile, prefs.logGrep, logGrepExclusions);
+ List<String> newLogLines = getAdditions(previousLogLines.get(), logLines);
+ previousLogLines.set(logLines);
+ record.put("logLines", newLogLines);
+
+ if (newLogLines.size() > 0) {
+ failureMsg.append("Log contains warnings/errors: "+newLogLines+"\n");
+ }
+ }
+ if (prefs.webProcessesRegex != null) {
+ List<Integer> pids = MonitorUtils.getRunningPids(prefs.webProcessesRegex, "--webProcesses");
+ pids.remove((Object)MonitorUtils.findOwnPid());
+
+ record.put("webPids", pids);
+ record.put("numWebPids", pids.size());
+ numWebProcessesHistory.add(pids.size());
+
+ if (prefs.numWebProcesses != null) {
+ boolean numWebPidsInRange = prefs.numWebProcesses.apply(pids.size());
+ record.put("numWebPidsInRange", numWebPidsInRange);
+
+ if (!numWebPidsInRange) {
+ failureMsg.append("num web processes out-of-range: pids="+pids+"; size="+pids.size()+"; expected="+prefs.numWebProcesses);
+ }
+
+ if (prefs.webProcessesCyclingPeriod > 0) {
+ List<TimestampedValue<Integer>> values = numWebProcessesHistory.getValues();
+ long valuesTimeRange = (values.get(values.size()-1).getTimestamp() - values.get(0).getTimestamp());
+ if (values.size() > 0 && valuesTimeRange > SECONDS.toMillis(prefs.webProcessesCyclingPeriod)) {
+ int min = -1;
+ int max = -1;
+ for (TimestampedValue<Integer> val : values) {
+ min = (min < 0) ? val.getValue() : Math.min(val.getValue(), min);
+ max = Math.max(val.getValue(), max);
+ }
+ record.put("minWebSizeInPeriod", min);
+ record.put("maxWebSizeInPeriod", max);
+
+ if (min > prefs.numWebProcesses.lowerEndpoint() || max < prefs.numWebProcesses.upperEndpoint()) {
+ failureMsg.append("num web processes not increasing/decreasing correctly: " +
+ "pids="+pids+"; size="+pids.size()+"; cyclePeriod="+prefs.webProcessesCyclingPeriod+
+ "; expectedRange="+prefs.numWebProcesses+"; min="+min+"; max="+max+"; history="+values);
+ }
+ } else {
+ int numVals = values.size();
+ long startTime = (numVals > 0) ? values.get(0).getTimestamp() : 0;
+ long endTime = (numVals > 0) ? values.get(values.size()-1).getTimestamp() : 0;
+ LOG.info("Insufficient vals in time-window to determine cycling behaviour over period ("+prefs.webProcessesCyclingPeriod+"secs): "+
+ "numVals="+numVals+"; startTime="+startTime+"; endTime="+endTime+"; periodCovered="+(endTime-startTime)/1000);
+ }
+ }
+ }
+ }
+
+ } catch (Throwable t) {
+ LOG.error("Error during periodic checks", t);
+ throw Throwables.propagate(t);
+ }
+
+ try {
+ recorder.record(record);
+ listener.onRecord(record);
+
+ if (failureMsg.length() > 0) {
+ listener.onFailure(record, failureMsg.toString());
+
+ if (prefs.abortOnError) {
+ LOG.error("Aborting on error: "+failureMsg);
+ System.exit(1);
+ }
+ }
+
+ } catch (Throwable t) {
+ LOG.warn("Error recording monitor info ("+record+")", t);
+ throw Throwables.propagate(t);
+ }
+ }
+ }, 0, checkPeriodMs, TimeUnit.MILLISECONDS);
+ }
+
+ // TODO What is the guava equivalent? Don't want Set.difference, because duplicates/ordered.
+ private static List<String> getAdditions(List<String> prev, List<String> next) {
+ List<String> result = Lists.newArrayList(next);
+ result.removeAll(prev);
+ return result;
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/bd44bb8f/usage/qa/src/main/java/org/apache/brooklyn/qa/longevity/MonitorListener.java
----------------------------------------------------------------------
diff --git a/usage/qa/src/main/java/org/apache/brooklyn/qa/longevity/MonitorListener.java b/usage/qa/src/main/java/org/apache/brooklyn/qa/longevity/MonitorListener.java
new file mode 100644
index 0000000..11fdd3f
--- /dev/null
+++ b/usage/qa/src/main/java/org/apache/brooklyn/qa/longevity/MonitorListener.java
@@ -0,0 +1,35 @@
+/*
+ * 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.qa.longevity;
+
+import org.apache.brooklyn.qa.longevity.StatusRecorder.Record;
+
+public interface MonitorListener {
+
+ public static final MonitorListener NOOP = new MonitorListener() {
+ @Override public void onRecord(Record record) {
+ }
+ @Override public void onFailure(Record record, String msg) {
+ }
+ };
+
+ public void onRecord(Record record);
+
+ public void onFailure(Record record, String msg);
+}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/bd44bb8f/usage/qa/src/main/java/org/apache/brooklyn/qa/longevity/MonitorPrefs.java
----------------------------------------------------------------------
diff --git a/usage/qa/src/main/java/org/apache/brooklyn/qa/longevity/MonitorPrefs.java b/usage/qa/src/main/java/org/apache/brooklyn/qa/longevity/MonitorPrefs.java
new file mode 100644
index 0000000..4d74045
--- /dev/null
+++ b/usage/qa/src/main/java/org/apache/brooklyn/qa/longevity/MonitorPrefs.java
@@ -0,0 +1,54 @@
+/*
+ * 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.qa.longevity;
+
+import java.io.File;
+import java.net.URL;
+
+import com.google.common.base.Objects;
+import com.google.common.collect.Range;
+
+public class MonitorPrefs {
+
+ public URL webUrl;
+ public int brooklynPid;
+ public File logFile;
+ public String logGrep;
+ public File logGrepExclusionsFile;
+ public String webProcessesRegex;
+ public Range<Integer> numWebProcesses;
+ public int webProcessesCyclingPeriod;
+ public File outFile;
+ public boolean abortOnError;
+
+ @Override
+ public String toString() {
+ return Objects.toStringHelper(this)
+ .add("webUrl", webUrl)
+ .add("brooklynPid", brooklynPid)
+ .add("logFile", logFile)
+ .add("logGrep", logGrep)
+ .add("logGrepExclusionsFile", logGrepExclusionsFile)
+ .add("outFile", outFile)
+ .add("webProcessesRegex", webProcessesRegex)
+ .add("numWebProcesses", numWebProcesses)
+ .add("webProcessesCyclingPeriod", webProcessesCyclingPeriod)
+ .toString();
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/bd44bb8f/usage/qa/src/main/java/org/apache/brooklyn/qa/longevity/MonitorUtils.java
----------------------------------------------------------------------
diff --git a/usage/qa/src/main/java/org/apache/brooklyn/qa/longevity/MonitorUtils.java b/usage/qa/src/main/java/org/apache/brooklyn/qa/longevity/MonitorUtils.java
new file mode 100644
index 0000000..54acb3b
--- /dev/null
+++ b/usage/qa/src/main/java/org/apache/brooklyn/qa/longevity/MonitorUtils.java
@@ -0,0 +1,329 @@
+/*
+ * 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.qa.longevity;
+
+import static com.google.common.base.Strings.isNullOrEmpty;
+
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URI;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.LinkedHashSet;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.regex.Pattern;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import brooklyn.util.http.HttpTool;
+import brooklyn.util.http.HttpToolResponse;
+import brooklyn.util.stream.StreamGobbler;
+
+import com.google.common.base.Objects;
+import com.google.common.base.Throwables;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.Maps;
+import com.google.common.io.ByteStreams;
+
+public class MonitorUtils {
+
+ private static final Logger LOG = LoggerFactory.getLogger(MonitorUtils.class);
+
+ private static volatile int ownPid = -1;
+
+ /**
+ * Confirm can read from URL.
+ *
+ * @param url
+ */
+ public static boolean isUrlUp(URL url) {
+ try {
+ HttpToolResponse result = HttpTool.httpGet(
+ HttpTool.httpClientBuilder().trustAll().build(),
+ URI.create(url.toString()),
+ ImmutableMap.<String,String>of());
+ int statuscode = result.getResponseCode();
+
+ if (statuscode != 200) {
+ LOG.info("Error reading URL {}: {}, {}", new Object[]{url, statuscode, result.getReasonPhrase()});
+ return false;
+ } else {
+ return true;
+ }
+ } catch (Exception e) {
+ LOG.info("Error reading URL {}: {}", url, e);
+ return false;
+ }
+ }
+
+ public static boolean isPidRunning(int pid) {
+ return isPidRunning(pid, null);
+ }
+
+ /**
+ * Confirm the given pid is running, and that the the process matches the given regex.
+ *
+ * @param pid
+ * @param regex
+ */
+ public static boolean isPidRunning(int pid, String regex) {
+ Process process = exec("ps -p " + pid);
+ String out = waitFor(process);
+ if (process.exitValue() > 0) {
+ String err = toString(process.getErrorStream());
+ LOG.info(String.format("pid %s not running: %s", pid, err));
+ return false;
+ }
+
+ if (regex != null) {
+ String regex2 = "^\\s*" + pid + ".*" + regex;
+ boolean found = false;
+ for (String line : out.split("\n")) {
+ if (hasAtLeastOneMatch(line, regex2)) {
+ found = true;
+ break;
+ }
+ }
+
+ if (!found) {
+ String txt = toString(process.getInputStream());
+ LOG.info("process did not match regular expression: "+txt);
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ private static boolean hasAtLeastOneMatch(String line, String regex) {
+ return Pattern.matches(".*"+regex+".*", line);
+ }
+
+ private static String toString(InputStream in){
+ try {
+ byte[] bytes = ByteStreams.toByteArray(in);
+ return new String(bytes);
+ } catch (IOException e) {
+ throw Throwables.propagate(e);
+ }
+
+ }
+
+ public static List<Integer> getRunningPids(String regex) {
+ return getRunningPids(regex, null);
+ }
+
+ /**
+ * Confirm the given pid is running, and that the the process matches the given regex.
+ *
+ * @param regex
+ * @param excludingRegex
+ */
+ public static List<Integer> getRunningPids(String regex, String excludingRegex) {
+ Process process = exec("ps ax");
+ String out = waitFor(process);
+
+ List<Integer> result = new LinkedList<Integer>();
+ for (String line : out.split("\n")) {
+ if (excludingRegex != null && hasAtLeastOneMatch(line, excludingRegex)) {
+ continue;
+ }
+ if (hasAtLeastOneMatch(line, regex)) {
+ String[] linesplit = line.trim().split("\\s+");
+ result.add(Integer.parseInt(linesplit[0]));
+ }
+ }
+ return result;
+ }
+
+ public static MemoryUsage getMemoryUsage(int pid){
+ return getMemoryUsage(pid, null,0);
+ }
+
+ /**
+ * @param pid
+ */
+ public static MemoryUsage getMemoryUsage(int pid, String clazzRegexOfInterest, int minInstancesOfInterest) {
+ Process process = exec(String.format("jmap -histo %s", pid));
+ String out = waitFor(process);
+
+ Map<String, Integer> instanceCounts = Maps.newLinkedHashMap();
+ long totalInstances=0;
+ long totalMemoryBytes=0;
+
+ for (String line : out.split("\n")) {
+ if (clazzRegexOfInterest!=null && hasAtLeastOneMatch(line, clazzRegexOfInterest)) {
+ // Format is:
+ // num #instances #bytes class name
+ // 1: 43506 8047096 example.MyClazz
+
+ String[] parts = line.trim().split("\\s+");
+ String clazz = parts[3];
+ int instanceCount = Integer.parseInt(parts[1]);
+ if (instanceCount >= minInstancesOfInterest) {
+ instanceCounts.put(clazz, instanceCount);
+ }
+ }
+ if (hasAtLeastOneMatch(line, "^Total.*")) {
+ String[] parts = line.split("\\s+");
+ totalInstances = Long.parseLong(parts[1]);
+ totalMemoryBytes = Long.parseLong(parts[2]);
+ }
+ }
+
+ return new MemoryUsage(totalInstances, totalMemoryBytes, instanceCounts);
+ }
+
+ public static class MemoryUsage {
+ final long totalInstances;
+ final long totalMemoryBytes;
+ final Map<String, Integer> instanceCounts;
+
+ MemoryUsage(long totalInstances, long totalMemoryBytes, Map<String, Integer> instanceCounts) {
+ this.totalInstances = totalInstances;
+ this.totalMemoryBytes = totalMemoryBytes;
+ this.instanceCounts = instanceCounts;
+ }
+
+ public String toString() {
+ return Objects.toStringHelper(this)
+ .add("totalInstances", totalInstances)
+ .add("totalMemoryBytes", totalMemoryBytes)
+ .add("instanceCounts", instanceCounts)
+ .toString();
+ }
+
+ public long getTotalInstances() {
+ return totalInstances;
+ }
+
+ public long getTotalMemoryBytes() {
+ return totalMemoryBytes;
+ }
+
+ public Map<String, Integer> getInstanceCounts() {
+ return instanceCounts;
+ }
+ }
+
+ public static List<String> searchLog(File file, String grepOfInterest) {
+ return searchLog(file, grepOfInterest, new LinkedHashSet<String>());
+ }
+
+ /**
+ * Find lines in the given file that match given given regex.
+ *
+ * @param file
+ * @param grepOfInterest
+ */
+ public static List<String> searchLog(File file, String grepOfInterest, Set<String> grepExclusions) {
+ Process process = exec(String.format("grep -E %s %s", grepOfInterest, file.getAbsoluteFile()));
+ String out = waitFor(process);
+
+ // TODO Annoying that String.split() returns size 1 when empty string; lookup javadoc when back online...
+ if (out.length() == 0) return Collections.<String>emptyList();
+
+ List<String> result = new ArrayList<String>();
+ for (String line : out.trim().split("\n")) {
+ boolean excluded = false;
+ for (String exclusion : grepExclusions) {
+ if (!isNullOrEmpty(exclusion) && hasAtLeastOneMatch(line, exclusion)) {
+ excluded = true;
+ }
+ }
+ if (!excluded) {
+ result.add(line);
+ }
+ }
+ return result;
+ }
+
+ public static Process exec(String cmd) {
+ LOG.info("executing cmd: " + cmd);
+
+ try {
+ return Runtime.getRuntime().exec(cmd);
+ } catch (IOException e) {
+ throw Throwables.propagate(e);
+ }
+ }
+
+ public static class ProcessHasStderr extends IllegalStateException {
+ private static final long serialVersionUID = -937871002993888405L;
+
+ byte[] stderrBytes;
+ public ProcessHasStderr(byte[] stderrBytes) {
+ this("Process printed to stderr: " + new String(stderrBytes), stderrBytes);
+ }
+ public ProcessHasStderr(String message, byte[] stderrBytes) {
+ super(message);
+ this.stderrBytes = stderrBytes;
+ }
+ }
+
+ /**
+ * Waits for the given process to complete, consuming its stdout and returning it as a string.
+ * If there is any output on stderr an exception will be thrown.
+ */
+ public static String waitFor(Process process) {
+ ByteArrayOutputStream bytesOut = new ByteArrayOutputStream();
+ @SuppressWarnings("resource") //Closeable doesn't seem appropriate for StreamGobbler since it isn't expected to be called every time
+ StreamGobbler gobblerOut = new StreamGobbler(process.getInputStream(), bytesOut, null);
+ gobblerOut.start();
+
+ ByteArrayOutputStream bytesErr = new ByteArrayOutputStream();
+ @SuppressWarnings("resource")
+ StreamGobbler gobblerErr = new StreamGobbler(process.getErrorStream(), bytesErr, null);
+ gobblerErr.start();
+
+ try {
+ process.waitFor();
+ gobblerOut.blockUntilFinished();
+ gobblerErr.blockUntilFinished();
+
+ if (bytesErr.size() > 0) {
+ throw new ProcessHasStderr(bytesErr.toByteArray());
+ }
+
+ return new String(bytesOut.toByteArray());
+ } catch (Exception e) {
+ throw Throwables.propagate(e);
+ } finally {
+ if (gobblerOut.isAlive()) gobblerOut.interrupt();
+ if (gobblerErr.isAlive()) gobblerErr.interrupt();
+ }
+ }
+
+ public static int findOwnPid() throws IOException {
+ if (ownPid >= 0) return ownPid;
+
+ String[] cmd = new String[]{"bash", "-c", "echo $PPID"};
+ Process process = Runtime.getRuntime().exec(cmd);
+ String out = MonitorUtils.waitFor(process);
+ ownPid = Integer.parseInt(out.trim());
+ return ownPid;
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/bd44bb8f/usage/qa/src/main/java/org/apache/brooklyn/qa/longevity/StatusRecorder.java
----------------------------------------------------------------------
diff --git a/usage/qa/src/main/java/org/apache/brooklyn/qa/longevity/StatusRecorder.java b/usage/qa/src/main/java/org/apache/brooklyn/qa/longevity/StatusRecorder.java
new file mode 100644
index 0000000..210e0a2
--- /dev/null
+++ b/usage/qa/src/main/java/org/apache/brooklyn/qa/longevity/StatusRecorder.java
@@ -0,0 +1,130 @@
+/*
+ * 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.qa.longevity;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.Map;
+
+import org.slf4j.Logger;
+
+import com.google.common.base.Charsets;
+import com.google.common.collect.Maps;
+import com.google.common.io.Files;
+
+public interface StatusRecorder {
+
+ public void record(Record record) throws IOException;
+
+ public static class Factory {
+ public static final StatusRecorder NOOP = new StatusRecorder() {
+ @Override public void record(Record record) {}
+ };
+
+ public static StatusRecorder noop() {
+ return NOOP;
+ }
+ public static StatusRecorder toFile(File outFile) {
+ return new FileBasedStatusRecorder(outFile);
+ }
+ public static StatusRecorder toSysout() {
+ return new SysoutBasedStatusRecorder();
+ }
+ public static StatusRecorder toLog(Logger log) {
+ return new LogBasedStatusRecorder(log);
+ }
+ public static StatusRecorder chain(StatusRecorder...recorders) {
+ return new ChainingStatusRecorder(recorders);
+ }
+ }
+
+ public static class Record {
+ private final Map<String,Object> fields = Maps.newLinkedHashMap();
+
+ public void putAll(Map<String,?> entries) {
+ fields.putAll(entries);
+ }
+
+ public void putAll(String keyPrefix, Map<String,?> entries) {
+ for (Map.Entry<String,?> entry : entries.entrySet()) {
+ fields.put(keyPrefix+entry.getKey(), entry.getValue());
+ }
+ }
+
+ public void put(String key, Object val) {
+ fields.put(key, val);
+ }
+
+ @Override
+ public String toString() {
+ return fields.toString();
+ }
+ }
+
+ public static class FileBasedStatusRecorder implements StatusRecorder {
+ private final File outFile;
+
+ public FileBasedStatusRecorder(File outFile) {
+ this.outFile = outFile;
+ }
+
+ @Override
+ public void record(Record record) throws IOException {
+ Files.append(record.fields.toString()+"\n", outFile, Charsets.UTF_8);
+ }
+ }
+
+ public static class SysoutBasedStatusRecorder implements StatusRecorder {
+ public SysoutBasedStatusRecorder() {
+ }
+
+ @Override
+ public void record(Record record) {
+ System.out.println(record.fields);
+ }
+ }
+
+ public static class LogBasedStatusRecorder implements StatusRecorder {
+ private final Logger log;
+
+ public LogBasedStatusRecorder(Logger log) {
+ this.log = log;
+ }
+
+ @Override
+ public void record(Record record) {
+ log.info("{}", record.fields);
+ }
+ }
+
+ public static class ChainingStatusRecorder implements StatusRecorder {
+ private final StatusRecorder[] recorders;
+
+ public ChainingStatusRecorder(StatusRecorder... recorders) {
+ this.recorders = recorders;
+ }
+
+ @Override
+ public void record(Record record) throws IOException {
+ for (StatusRecorder recorder : recorders) {
+ recorder.record(record);
+ }
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/bd44bb8f/usage/qa/src/test/java/brooklyn/qa/load/LoadTest.java
----------------------------------------------------------------------
diff --git a/usage/qa/src/test/java/brooklyn/qa/load/LoadTest.java b/usage/qa/src/test/java/brooklyn/qa/load/LoadTest.java
deleted file mode 100644
index 16a0195..0000000
--- a/usage/qa/src/test/java/brooklyn/qa/load/LoadTest.java
+++ /dev/null
@@ -1,243 +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.qa.load;
-
-import static org.testng.Assert.assertEquals;
-
-import java.io.File;
-import java.util.Collections;
-import java.util.List;
-import java.util.concurrent.Callable;
-import java.util.concurrent.Executors;
-import java.util.concurrent.Future;
-import java.util.concurrent.TimeUnit;
-
-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.Entities;
-import brooklyn.entity.basic.StartableApplication;
-import brooklyn.entity.proxying.EntitySpec;
-import brooklyn.entity.rebind.persister.PersistMode;
-import brooklyn.entity.trait.Startable;
-import brooklyn.launcher.BrooklynLauncher;
-import brooklyn.location.Location;
-import brooklyn.management.ManagementContext;
-import brooklyn.management.ha.HighAvailabilityMode;
-import brooklyn.management.internal.LocalManagementContext;
-import brooklyn.test.PerformanceTestUtils;
-import brooklyn.util.os.Os;
-import brooklyn.util.time.Duration;
-
-import com.google.common.base.Stopwatch;
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.Lists;
-import com.google.common.io.Files;
-import com.google.common.util.concurrent.Futures;
-import com.google.common.util.concurrent.ListenableFuture;
-import com.google.common.util.concurrent.ListeningExecutorService;
-import com.google.common.util.concurrent.MoreExecutors;
-
-/**
- * Customers ask about the scalability of Brooklyn. These load tests investigate how many
- * concurrent apps can be deployed and managed by a single Brooklyn management node.
- *
- * The apps are "simulated" in that they don't create the underlying resources
- * (we are not checking if the test machine can run 100s of app-servers simultaneously!)
- * The install/customize/launch will instead execute ssh commands of comparable length,
- * but that just echo rather than execute the actual commands.
- *
- * "SIMULATE_EXTERNAL_MONITORING" means that we do not poll the entities directly (over ssh, http or
- * whatever). Instead we simulate the metrics being injected directly to be set on the entity (e.g.
- * having been collected from a Graphite server).
- *
- * "SKIP_SSH_ON_START" means don't do the normal install+customize+launch ssh commands. Instead, just
- * startup the entities so we can monitor their resource usage.
- */
-public class LoadTest {
-
- // TODO Could/should issue provisioning request through REST api, rather than programmatically;
- // and poll to detect completion.
-
- /*
- * Useful commands when investigating:
- * LOG_FILE=usage/qa/brooklyn-camp-tests.log
- * grep -E "OutOfMemoryError|[P|p]rovisioning time|sleeping before|CPU fraction|LoadTest using" $LOG_FILE | less
- * grep -E "OutOfMemoryError|[P|p]rovisioning time" $LOG_FILE; grep "CPU fraction" $LOG_FILE | tail -1; grep "LoadTest using" $LOG_FILE | tail -1
- * grep -E "OutOfMemoryError|LoadTest using" $LOG_FILE
- */
- private static final Logger LOG = LoggerFactory.getLogger(LoadTest.class);
-
- private File persistenceDir;
- private BrooklynLauncher launcher;
- private String webServerUrl;
- private ManagementContext managementContext;
- private ListeningExecutorService executor;
- private Future<?> cpuFuture;
-
- private Location localhost;
-
- List<Duration> provisioningTimes;
-
-
- @BeforeMethod(alwaysRun=true)
- public void setUp() throws Exception {
- // Create management node
- persistenceDir = Files.createTempDir();
- launcher = BrooklynLauncher.newInstance()
- .persistMode(PersistMode.CLEAN)
- .highAvailabilityMode(HighAvailabilityMode.MASTER)
- .persistenceDir(persistenceDir)
- .start();
- webServerUrl = launcher.getServerDetails().getWebServerUrl();
- managementContext = launcher.getServerDetails().getManagementContext();
-
- localhost = managementContext.getLocationRegistry().resolve("localhost");
-
- provisioningTimes = Collections.synchronizedList(Lists.<Duration>newArrayList());
-
- // Create executors
- executor = MoreExecutors.listeningDecorator(Executors.newCachedThreadPool());
-
- // Monitor utilisation (memory/CPU) while tests run
- executor.submit(new Callable<Void>() {
- public Void call() {
- try {
- while (true) {
- managementContext.getExecutionManager(); // force GC to be instantiated
- String usage = ((LocalManagementContext)managementContext).getGarbageCollector().getUsageString();
- LOG.info("LoadTest using "+usage);
- Thread.sleep(1000);
- }
- } catch (InterruptedException e) {
- Thread.currentThread().interrupt(); // exit gracefully
- } catch (Exception e) {
- LOG.error("Error getting usage info", e);
- }
- return null;
- }});
-
- cpuFuture = PerformanceTestUtils.sampleProcessCpuTime(Duration.ONE_SECOND, "during testProvisionAppsConcurrently");
-
- }
-
- @AfterMethod(alwaysRun=true)
- public void tearDown() throws Exception {
- if (cpuFuture != null) cpuFuture.cancel(true);
- if (executor != null) executor.shutdownNow();
- if (launcher != null) launcher.terminate();
- if (persistenceDir != null) Os.deleteRecursively(persistenceDir);
- }
-
- /**
- * Creates multiple apps simultaneously.
- *
- * Long-term target is 50 concurrent provisioning requests (which may be issued while there are
- * many existing applications under management). Until we reach that point, we can partition the
- * load across multiple (separate) brooklyn management nodes.
- * TODO TBD: is that 50 VMs worth, or 50 apps with 4 VMs in each?
- *
- * TODO Does not measure the cost of jclouds for creating all the VMs/containers.
- */
- @Test(groups="Acceptance")
- public void testLocalhostProvisioningAppsConcurrently() throws Exception {
- final int NUM_CONCURRENT_APPS_PROVISIONING = 20;
-
- List<ListenableFuture<StartableApplication>> futures = Lists.newArrayList();
- for (int i = 0; i < NUM_CONCURRENT_APPS_PROVISIONING; i++) {
- ListenableFuture<StartableApplication> future = executor.submit(newProvisionAppTask(managementContext,
- EntitySpec.create(StartableApplication.class, SimulatedTheeTierApp.class)
- .configure(SimulatedTheeTierApp.SIMULATE_EXTERNAL_MONITORING, true)
- .displayName("Simulated app "+i)));
- futures.add(future);
- }
-
- List<StartableApplication> apps = Futures.allAsList(futures).get();
-
- for (StartableApplication app : apps) {
- assertEquals(app.getAttribute(Startable.SERVICE_UP), (Boolean)true);
- }
- }
-
- /**
- * Creates many apps, to monitor resource usage etc.
- *
- * "SIMULATE_EXTERNAL_MONITORING" means that we do not poll the entities directly (over ssh, http or
- * whatever). Instead we simulate the metrics being injected directly to be set on the entity (e.g.
- * having been collected from a Graphite server).
- *
- * Long-term target is 2500 VMs under management.
- * Until we reach that point, we can partition the load across multiple (separate) brooklyn management nodes.
- */
- @Test(groups="Acceptance")
- public void testLocalhostManyApps() throws Exception {
- final int NUM_APPS = 630; // target is 2500 VMs; each blueprint has 4 (rounding up)
- final int NUM_APPS_PER_BATCH = 10;
- final int SLEEP_BETWEEN_BATCHES = 10*1000;
- final boolean SKIP_SSH_ON_START = true; // getting ssh errors otherwise!
-
- int counter = 0;
-
- for (int i = 0; i < NUM_APPS / NUM_APPS_PER_BATCH; i++) {
- List<ListenableFuture<StartableApplication>> futures = Lists.newArrayList();
- for (int j = 0; j < NUM_APPS_PER_BATCH; j++) {
- ListenableFuture<StartableApplication> future = executor.submit(newProvisionAppTask(
- managementContext,
- EntitySpec.create(StartableApplication.class, SimulatedTheeTierApp.class)
- .configure(SimulatedTheeTierApp.SIMULATE_EXTERNAL_MONITORING, true)
- .configure(SimulatedTheeTierApp.SKIP_SSH_ON_START, SKIP_SSH_ON_START)
- .displayName("Simulated app "+(++counter))));
- futures.add(future);
- }
-
- List<StartableApplication> apps = Futures.allAsList(futures).get();
-
- for (StartableApplication app : apps) {
- assertEquals(app.getAttribute(Startable.SERVICE_UP), (Boolean)true);
- }
-
- synchronized (provisioningTimes) {
- LOG.info("cycle="+i+"; numApps="+counter+": provisioning times: "+provisioningTimes);
- provisioningTimes.clear();
- }
-
- LOG.info("cycle="+i+"; numApps="+counter+": sleeping before next batch of apps");
- Thread.sleep(SLEEP_BETWEEN_BATCHES);
- }
- }
-
- protected <T extends StartableApplication> Callable<T> newProvisionAppTask(final ManagementContext managementContext, final EntitySpec<T> entitySpec) {
- return new Callable<T>() {
- public T call() {
- Stopwatch stopwatch = Stopwatch.createStarted();
- T app = managementContext.getEntityManager().createEntity(entitySpec);
- Entities.startManagement(app, managementContext);
- app.start(ImmutableList.of(localhost));
- Duration duration = Duration.of(stopwatch.elapsed(TimeUnit.MILLISECONDS), TimeUnit.MILLISECONDS);
- LOG.info("Provisioning time: "+duration);
- provisioningTimes.add(duration);
-
- return app;
- }
- };
- }
-}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/bd44bb8f/usage/qa/src/test/java/brooklyn/qa/longevity/MonitorUtilsTest.java
----------------------------------------------------------------------
diff --git a/usage/qa/src/test/java/brooklyn/qa/longevity/MonitorUtilsTest.java b/usage/qa/src/test/java/brooklyn/qa/longevity/MonitorUtilsTest.java
deleted file mode 100644
index 2f1e854..0000000
--- a/usage/qa/src/test/java/brooklyn/qa/longevity/MonitorUtilsTest.java
+++ /dev/null
@@ -1,165 +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.qa.longevity;
-
-import static org.testng.Assert.assertEquals;
-import static org.testng.Assert.assertFalse;
-import static org.testng.Assert.assertTrue;
-import static org.testng.Assert.fail;
-
-import java.io.File;
-import java.io.IOException;
-import java.net.URL;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.List;
-
-import org.testng.annotations.Test;
-
-import brooklyn.qa.longevity.MonitorUtils.ProcessHasStderr;
-import brooklyn.util.os.Os;
-import brooklyn.util.text.Strings;
-
-import com.google.common.base.Charsets;
-import com.google.common.collect.ImmutableMap;
-import com.google.common.io.Files;
-
-public class MonitorUtilsTest {
-
- @Test(enabled=false, timeOut=1000) // Demonstrates that process.waitFor() hangs for big output streams
- public void testExecuteAndWaitFor() throws Exception {
- Process process = createDumpingProcess(false);
- process.waitFor();
- fail("Should block while waiting to consume process output");
- }
-
- @Test(enabled=false, timeOut=1000) // Demonstrates that process.waitFor() hangs for big err streams
- public void testExecuteAndWaitForErr() throws Exception {
- Process process = createDumpingProcess(true);
- process.waitFor();
- fail("Should block while waiting to consume process output");
- }
-
- @Test(timeOut=1000)
- public void testExecuteAndWaitForConsumingOutputStream() throws Exception {
- Process process = createDumpingProcess(false);
- String out = MonitorUtils.waitFor(process);
- assertTrue(out.length() > 100000, "out.size="+out.length());
- }
-
- @Test(timeOut=1000, expectedExceptions=IllegalStateException.class)
- public void testExecuteAndWaitForConsumingErrorStream() throws Exception {
- Process process = createDumpingProcess(true);
- MonitorUtils.waitFor(process);
- }
-
- private Process createDumpingProcess(boolean writeToErr) throws IOException {
- String errSuffix = writeToErr ? " >&2" : "";
- //Windows limits the length of the arguments so echo multiple times instead
- String bigstr = Strings.repeat("a", 8000);
- String bigcmd = Strings.repeat(getSilentPrefix() + "echo " + bigstr + errSuffix + Os.LINE_SEPARATOR, 15);
- File file = Os.newTempFile("test-consume", ".bat");
- file.setExecutable(true);
- Files.write(bigcmd, file, Charsets.UTF_8);
- Process process = MonitorUtils.exec(file.getAbsolutePath());
- return process;
- }
-
- @Test(groups="UNIX")
- public void testFindOwnPid() throws Exception {
- int ownpid = MonitorUtils.findOwnPid();
- assertTrue(ownpid > 0, "ownpid=$ownpid");
- assertTrue(MonitorUtils.isPidRunning(ownpid, "java"),"java is not running");
- }
-
- @Test(groups="UNIX")
- public void testIsPidRunning() throws Exception {
- int usedPid = MonitorUtils.findOwnPid();
-
- //the child process will terminate freeing it PID
- String[] cmd = new String[]{"bash", "-c", "echo $$"};
- Process process = Runtime.getRuntime().exec(cmd);
- String out = MonitorUtils.waitFor(process);
- int unusedPid = Integer.parseInt(out.trim());
-
- assertTrue(MonitorUtils.isPidRunning(usedPid));
- assertFalse(MonitorUtils.isPidRunning(unusedPid));
-
- try {
- assertFalse(MonitorUtils.isPidRunning(1234567)); // too large
- } catch (ProcessHasStderr e) {
- // expected on osx
- }
- }
-
- @Test(groups="UNIX")
- public void testGetRunningPids() throws Exception {
- int ownpid = MonitorUtils.findOwnPid();
-
- List<Integer> javapids = MonitorUtils.getRunningPids("java");
-
- assertTrue(javapids.contains(ownpid), "javapids="+javapids+"; ownpid="+ownpid);
- }
-
- @Test
- public void testIsUrlUp() throws Exception {
- assertFalse(MonitorUtils.isUrlUp(new URL("http://localhost/thispathdoesnotexist")));
- }
-
- @Test(groups="UNIX")
- public void testSearchLog() throws Exception {
- String fileContents = "line1\nline2\nline3\n";
- File file = File.createTempFile("monitorUtilsTest.testSearchLog", ".txt");
- Files.write(fileContents, file, Charsets.UTF_8);
-
- try {
- assertEquals(MonitorUtils.searchLog(file, "line1"), Arrays.asList("line1"));
- assertEquals(MonitorUtils.searchLog(file, "line1|line2"), Arrays.asList("line1", "line2"));
- assertEquals(MonitorUtils.searchLog(file, "textnotthere"), Collections.emptyList());
- assertEquals(MonitorUtils.searchLog(file, "line"), Arrays.asList("line1", "line2", "line3"));
- } finally {
- file.delete();
- }
- }
-
- @Test(groups="Integration")
- public void testMemoryUsage() throws Exception {
- int ownpid = MonitorUtils.findOwnPid();
-
- MonitorUtils.MemoryUsage memUsage = MonitorUtils.getMemoryUsage(ownpid);
- assertTrue(memUsage.totalInstances > 0, memUsage.toString());
- assertTrue(memUsage.totalMemoryBytes > 0, memUsage.toString());
- assertEquals(memUsage.getInstanceCounts(), Collections.emptyMap());
-
- MonitorUtils.MemoryUsage memUsage2 = MonitorUtils.getMemoryUsage(ownpid, MonitorUtilsTest.class.getCanonicalName(),0);
- assertEquals(memUsage2.getInstanceCounts(), ImmutableMap.of(MonitorUtilsTest.class.getCanonicalName(), 1));
-
- MonitorUtils.MemoryUsage memUsage3 = MonitorUtils.getMemoryUsage(ownpid, MonitorUtilsTest.class.getCanonicalName(), 2);
- assertEquals(memUsage3.getInstanceCounts(), Collections.emptyMap());
- }
-
- private String getSilentPrefix() {
- if (Os.isMicrosoftWindows()) {
- return "@";
- } else {
- return "";
- }
- }
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/bd44bb8f/usage/qa/src/test/java/brooklyn/qa/longevity/webcluster/SinusoidalLoadGenerator.java
----------------------------------------------------------------------
diff --git a/usage/qa/src/test/java/brooklyn/qa/longevity/webcluster/SinusoidalLoadGenerator.java b/usage/qa/src/test/java/brooklyn/qa/longevity/webcluster/SinusoidalLoadGenerator.java
deleted file mode 100644
index 392b976..0000000
--- a/usage/qa/src/test/java/brooklyn/qa/longevity/webcluster/SinusoidalLoadGenerator.java
+++ /dev/null
@@ -1,90 +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.qa.longevity.webcluster;
-
-import java.util.concurrent.Executors;
-import java.util.concurrent.ScheduledExecutorService;
-import java.util.concurrent.TimeUnit;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import brooklyn.config.ConfigKey;
-import brooklyn.enricher.basic.AbstractEnricher;
-import brooklyn.entity.basic.ConfigKeys;
-import brooklyn.entity.basic.EntityLocal;
-import brooklyn.event.AttributeSensor;
-
-import com.google.common.base.Throwables;
-import com.google.common.reflect.TypeToken;
-
-/**
- * Periodically publishes values in the range of 0 to #amplitude.
- * The value varies sinusoidally over time.
- */
-public class SinusoidalLoadGenerator extends AbstractEnricher {
-
- private static final Logger LOG = LoggerFactory.getLogger(SinusoidalLoadGenerator.class);
-
- public static final ConfigKey<AttributeSensor<Double>> TARGET = ConfigKeys.newConfigKey(new TypeToken<AttributeSensor<Double>>() {}, "target");
-
- public static final ConfigKey<Long> PUBLISH_PERIOD_MS = ConfigKeys.newLongConfigKey("publishPeriodMs");
-
- public static final ConfigKey<Long> SIN_PERIOD_MS = ConfigKeys.newLongConfigKey("sinPeriodMs");
-
- public static final ConfigKey<Double> SIN_AMPLITUDE = ConfigKeys.newDoubleConfigKey("sinAmplitude");
-
- private final ScheduledExecutorService executor;
-
- public SinusoidalLoadGenerator() {
- this.executor = Executors.newSingleThreadScheduledExecutor();
- }
-
- public SinusoidalLoadGenerator(AttributeSensor<Double> target, long publishPeriodMs, long sinPeriodMs, double sinAmplitude) {
- config().set(TARGET, target);
- config().set(PUBLISH_PERIOD_MS, publishPeriodMs);
- config().set(SIN_PERIOD_MS, sinPeriodMs);
- config().set(SIN_AMPLITUDE, sinAmplitude);
- this.executor = Executors.newSingleThreadScheduledExecutor();
- }
-
- @Override
- public void setEntity(final EntityLocal entity) {
- super.setEntity(entity);
-
- executor.scheduleAtFixedRate(new Runnable() {
- @Override public void run() {
- try {
- long time = System.currentTimeMillis();
- double val = getRequiredConfig(SIN_AMPLITUDE) * (1 + Math.sin( (1.0*time) / getRequiredConfig(SIN_PERIOD_MS) * Math.PI * 2 - Math.PI/2 )) / 2;
- entity.setAttribute(getRequiredConfig(TARGET), val);
- } catch (Throwable t) {
- LOG.warn("Error generating sinusoidal-load metric", t);
- throw Throwables.propagate(t);
- }
- }
-
- }, 0, getRequiredConfig(PUBLISH_PERIOD_MS), TimeUnit.MILLISECONDS);
- }
-
- @Override
- public void destroy() {
- executor.shutdownNow();
- }
-}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/bd44bb8f/usage/qa/src/test/java/brooklyn/qa/longevity/webcluster/WebClusterApp.java
----------------------------------------------------------------------
diff --git a/usage/qa/src/test/java/brooklyn/qa/longevity/webcluster/WebClusterApp.java b/usage/qa/src/test/java/brooklyn/qa/longevity/webcluster/WebClusterApp.java
deleted file mode 100644
index a223861..0000000
--- a/usage/qa/src/test/java/brooklyn/qa/longevity/webcluster/WebClusterApp.java
+++ /dev/null
@@ -1,101 +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.qa.longevity.webcluster;
-
-import java.util.List;
-
-import brooklyn.config.BrooklynProperties;
-import brooklyn.enricher.Enrichers;
-import brooklyn.entity.basic.AbstractApplication;
-import brooklyn.entity.basic.Entities;
-import brooklyn.entity.basic.StartableApplication;
-import brooklyn.entity.proxy.nginx.NginxController;
-import brooklyn.entity.proxying.EntitySpec;
-import brooklyn.entity.webapp.ControlledDynamicWebAppCluster;
-import brooklyn.entity.webapp.jboss.JBoss7Server;
-import brooklyn.event.AttributeSensor;
-import brooklyn.event.basic.Sensors;
-import brooklyn.launcher.BrooklynLauncher;
-import brooklyn.policy.EnricherSpec;
-import brooklyn.policy.autoscaling.AutoScalerPolicy;
-import brooklyn.util.CommandLineUtil;
-
-import com.google.common.collect.Lists;
-
-public class WebClusterApp extends AbstractApplication {
-
- static BrooklynProperties config = BrooklynProperties.Factory.newDefault();
-
- public static final String WAR_PATH = "classpath://hello-world.war";
-
- private static final long loadCyclePeriodMs = 2 * 60 * 1000L;
-
- @Override
- public void initApp() {
- final AttributeSensor<Double> sinusoidalLoad =
- Sensors.newDoubleSensor("brooklyn.qa.sinusoidalLoad", "Sinusoidal server load");
- AttributeSensor<Double> averageLoad =
- Sensors.newDoubleSensor("brooklyn.qa.averageLoad", "Average load in cluster");
-
- NginxController nginxController = addChild(EntitySpec.create(NginxController.class)
- // .configure("domain", "webclusterexample.brooklyn.local")
- .configure("port", "8000+"));
-
- EntitySpec<JBoss7Server> jbossSpec = EntitySpec.create(JBoss7Server.class)
- .configure("httpPort", "8080+")
- .configure("war", WAR_PATH)
- .enricher(EnricherSpec.create(SinusoidalLoadGenerator.class)
- .configure(SinusoidalLoadGenerator.TARGET, sinusoidalLoad)
- .configure(SinusoidalLoadGenerator.PUBLISH_PERIOD_MS, 500L)
- .configure(SinusoidalLoadGenerator.SIN_PERIOD_MS, loadCyclePeriodMs)
- .configure(SinusoidalLoadGenerator.SIN_AMPLITUDE, 1d));
-
- ControlledDynamicWebAppCluster web = addChild(EntitySpec.create(ControlledDynamicWebAppCluster.class)
- .displayName("WebApp cluster")
- .configure("controller", nginxController)
- .configure("initialSize", 1)
- .configure("memberSpec", jbossSpec));
-
- web.getCluster().addEnricher(Enrichers.builder()
- .aggregating(sinusoidalLoad)
- .publishing(averageLoad)
- .fromMembers()
- .computingAverage()
- .build());
- web.getCluster().addPolicy(AutoScalerPolicy.builder()
- .metric(averageLoad)
- .sizeRange(1, 3)
- .metricRange(0.3, 0.7)
- .build());
- }
-
- public static void main(String[] argv) {
- List<String> args = Lists.newArrayList(argv);
- String port = CommandLineUtil.getCommandLineOption(args, "--port", "8081+");
- String location = CommandLineUtil.getCommandLineOption(args, "--location", "localhost");
-
- BrooklynLauncher launcher = BrooklynLauncher.newInstance()
- .application(EntitySpec.create(StartableApplication.class, WebClusterApp.class).displayName("Brooklyn WebApp Cluster example"))
- .webconsolePort(port)
- .location(location)
- .start();
-
- Entities.dumpInfo(launcher.getApplications());
- }
-}
[10/12] incubator-brooklyn git commit:
brooklyn-example-simple-nosql-cluster: add org.apache package prefix
Posted by al...@apache.org.
brooklyn-example-simple-nosql-cluster: add org.apache package prefix
Project: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/commit/44d2dc11
Tree: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/tree/44d2dc11
Diff: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/diff/44d2dc11
Branch: refs/heads/master
Commit: 44d2dc1163db52a35e1125654f1137f106c196dc
Parents: 0cdb2ed
Author: Ciprian Ciubotariu <ch...@gmx.net>
Authored: Wed Jul 15 11:06:56 2015 +0300
Committer: Ciprian Ciubotariu <ch...@gmx.net>
Committed: Wed Jul 15 18:47:01 2015 +0300
----------------------------------------------------------------------
.../brooklyn/demo/CumulusRDFApplication.java | 240 -------------------
.../demo/HighAvailabilityCassandraCluster.java | 89 -------
.../java/brooklyn/demo/ResilientMongoDbApp.java | 106 --------
.../java/brooklyn/demo/RiakClusterExample.java | 76 ------
.../brooklyn/demo/SimpleCassandraCluster.java | 58 -----
.../brooklyn/demo/SimpleCouchDBCluster.java | 36 ---
.../brooklyn/demo/SimpleMongoDBReplicaSet.java | 39 ---
.../java/brooklyn/demo/SimpleRedisCluster.java | 35 ---
.../main/java/brooklyn/demo/StormSampleApp.java | 70 ------
.../brooklyn/demo/WideAreaCassandraCluster.java | 86 -------
.../brooklyn/demo/CumulusRDFApplication.java | 240 +++++++++++++++++++
.../demo/HighAvailabilityCassandraCluster.java | 89 +++++++
.../brooklyn/demo/ResilientMongoDbApp.java | 106 ++++++++
.../brooklyn/demo/RiakClusterExample.java | 76 ++++++
.../brooklyn/demo/SimpleCassandraCluster.java | 58 +++++
.../brooklyn/demo/SimpleCouchDBCluster.java | 36 +++
.../brooklyn/demo/SimpleMongoDBReplicaSet.java | 39 +++
.../brooklyn/demo/SimpleRedisCluster.java | 35 +++
.../apache/brooklyn/demo/StormSampleApp.java | 70 ++++++
.../brooklyn/demo/WideAreaCassandraCluster.java | 86 +++++++
.../brooklyn/demo/ha-cassandra-cluster.yaml | 45 ----
.../brooklyn/demo/simple-cassandra-cluster.yaml | 28 ---
.../demo/wide-area-cassandra-cluster.yaml | 41 ----
.../brooklyn/demo/ha-cassandra-cluster.yaml | 45 ++++
.../brooklyn/demo/simple-cassandra-cluster.yaml | 28 +++
.../demo/wide-area-cassandra-cluster.yaml | 41 ++++
26 files changed, 949 insertions(+), 949 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/44d2dc11/examples/simple-nosql-cluster/src/main/java/brooklyn/demo/CumulusRDFApplication.java
----------------------------------------------------------------------
diff --git a/examples/simple-nosql-cluster/src/main/java/brooklyn/demo/CumulusRDFApplication.java b/examples/simple-nosql-cluster/src/main/java/brooklyn/demo/CumulusRDFApplication.java
deleted file mode 100644
index 3379bd4..0000000
--- a/examples/simple-nosql-cluster/src/main/java/brooklyn/demo/CumulusRDFApplication.java
+++ /dev/null
@@ -1,240 +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.demo;
-
-import java.util.Collection;
-import java.util.List;
-import java.util.Map;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import brooklyn.catalog.Catalog;
-import brooklyn.catalog.CatalogConfig;
-import brooklyn.config.ConfigKey;
-import brooklyn.entity.Effector;
-import brooklyn.entity.Entity;
-import brooklyn.entity.basic.AbstractApplication;
-import brooklyn.entity.basic.ConfigKeys;
-import brooklyn.entity.basic.Entities;
-import brooklyn.entity.basic.EntityInternal;
-import brooklyn.entity.basic.Lifecycle;
-import brooklyn.entity.basic.ServiceStateLogic;
-import brooklyn.entity.basic.StartableApplication;
-import brooklyn.entity.effector.EffectorBody;
-import brooklyn.entity.effector.Effectors;
-import brooklyn.entity.java.UsesJava;
-import brooklyn.entity.java.UsesJmx;
-import brooklyn.entity.nosql.cassandra.CassandraDatacenter;
-import brooklyn.entity.nosql.cassandra.CassandraFabric;
-import brooklyn.entity.nosql.cassandra.CassandraNode;
-import brooklyn.entity.proxying.EntitySpec;
-import brooklyn.entity.software.SshEffectorTasks;
-import brooklyn.entity.trait.Startable;
-import brooklyn.entity.webapp.JavaWebAppService;
-import brooklyn.entity.webapp.tomcat.TomcatServer;
-import brooklyn.event.SensorEvent;
-import brooklyn.event.SensorEventListener;
-import brooklyn.event.basic.DependentConfiguration;
-import brooklyn.launcher.BrooklynLauncher;
-import brooklyn.location.Location;
-import brooklyn.location.basic.PortRanges;
-import brooklyn.policy.EnricherSpec;
-import brooklyn.policy.PolicySpec;
-import brooklyn.policy.ha.ServiceFailureDetector;
-import brooklyn.policy.ha.ServiceReplacer;
-import brooklyn.policy.ha.ServiceRestarter;
-import brooklyn.util.CommandLineUtil;
-import brooklyn.util.ResourceUtils;
-import brooklyn.util.collections.MutableList;
-import brooklyn.util.collections.MutableMap;
-import brooklyn.util.config.ConfigBag;
-import brooklyn.util.exceptions.Exceptions;
-import brooklyn.util.task.DynamicTasks;
-import brooklyn.util.text.StringEscapes.JavaStringEscapes;
-import brooklyn.util.text.Strings;
-import brooklyn.util.text.TemplateProcessor;
-
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.Iterables;
-import com.google.common.collect.Lists;
-import com.google.common.net.HostAndPort;
-
-/** CumulusRDF application with Cassandra cluster. */
-@Catalog(name="Cumulus RDF Application", description="CumulusRDF Application on a Tomcat server using a multi-region Cassandra fabric")
-public class CumulusRDFApplication extends AbstractApplication {
-
- private static final Logger log = LoggerFactory.getLogger(CumulusRDFApplication.class);
-
- @CatalogConfig(label="Cumulus Configuration File (URL)", priority=1)
- public static final ConfigKey<String> CUMULUS_RDF_CONFIG_URL = ConfigKeys.newConfigKey(
- "cumulus.config.url", "URL for the YAML configuration file for CumulusRDF", "classpath://cumulus.yaml");
-
- @CatalogConfig(label="Cassandra Thrift Port", priority=1)
- public static final ConfigKey<Integer> CASSANDRA_THRIFT_PORT = ConfigKeys.newConfigKey(
- "cumulus.cassandra.port", "Port to contact the Cassandra cluster on", 9160);
-
- @CatalogConfig(label="Cassandra Cluster Size", priority=1)
- public static final ConfigKey<Integer> CASSANDRA_CLUSTER_SIZE = ConfigKeys.newConfigKey(
- "cumulus.cassandra.cluster.size", "Initial size of the Cassandra cluster", 2);
-
- @CatalogConfig(label="Multi-region Fabric", priority=1)
- public static final ConfigKey<Boolean> MULTI_REGION_FABRIC = ConfigKeys.newConfigKey(
- "cumulus.cassandra.fabric", "Deploy a multi-region Cassandra fabric", false);
-
- // TODO Fails when given two locations
- // public static final String DEFAULT_LOCATIONS = "[ jclouds:aws-ec2:us-east-1,jclouds:rackspace-cloudservers-uk ]";
- public static final String DEFAULT_LOCATIONS = "jclouds:aws-ec2:us-east-1";
-
- private Effector<Void> cumulusConfig = Effectors.effector(Void.class, "cumulusConfig")
- .description("Configure the CumulusRDF web application")
- .buildAbstract();
-
- private Entity cassandra;
- private TomcatServer webapp;
- private HostAndPort endpoint;
- private final Object endpointMutex = new Object();
-
- /**
- * Create the application entities:
- * <ul>
- * <li>A {@link CassandraFabric} of {@link CassandraDatacenter}s containing {@link CassandraNode}s
- * <li>A {@link TomcatServer}
- * </ul>
- */
- @Override
- public void initApp() {
- // Cassandra cluster
- EntitySpec<CassandraDatacenter> clusterSpec = EntitySpec.create(CassandraDatacenter.class)
- .configure(CassandraDatacenter.MEMBER_SPEC, EntitySpec.create(CassandraNode.class)
- //FIXME can probably use JMXMP_AND_RMI now, to deploy to GCE and elsewhere
- .configure(UsesJmx.JMX_AGENT_MODE, UsesJmx.JmxAgentModes.JMX_RMI_CUSTOM_AGENT)
- .configure(UsesJmx.JMX_PORT, PortRanges.fromString("11099+"))
- .configure(UsesJmx.RMI_REGISTRY_PORT, PortRanges.fromString("9001+"))
- .configure(CassandraNode.THRIFT_PORT, PortRanges.fromInteger(getConfig(CASSANDRA_THRIFT_PORT)))
- .enricher(EnricherSpec.create(ServiceFailureDetector.class))
- .policy(PolicySpec.create(ServiceRestarter.class)
- .configure(ServiceRestarter.FAILURE_SENSOR_TO_MONITOR, ServiceFailureDetector.ENTITY_FAILED)))
- .policy(PolicySpec.create(ServiceReplacer.class)
- .configure(ServiceReplacer.FAILURE_SENSOR_TO_MONITOR, ServiceRestarter.ENTITY_RESTART_FAILED));
-
- if (getConfig(MULTI_REGION_FABRIC)) {
- cassandra = addChild(EntitySpec.create(CassandraFabric.class)
- .configure(CassandraDatacenter.CLUSTER_NAME, "Brooklyn")
- .configure(CassandraDatacenter.INITIAL_SIZE, getConfig(CASSANDRA_CLUSTER_SIZE)) // per location
- .configure(CassandraDatacenter.ENDPOINT_SNITCH_NAME, "brooklyn.entity.nosql.cassandra.customsnitch.MultiCloudSnitch")
- .configure(CassandraNode.CUSTOM_SNITCH_JAR_URL, "classpath://brooklyn/entity/nosql/cassandra/cassandra-multicloud-snitch.jar")
- .configure(CassandraFabric.MEMBER_SPEC, clusterSpec));
- } else {
- cassandra = addChild(EntitySpec.create(clusterSpec)
- .configure(CassandraDatacenter.CLUSTER_NAME, "Brooklyn")
- .configure(CassandraDatacenter.INITIAL_SIZE, getConfig(CASSANDRA_CLUSTER_SIZE)));
- }
-
- // Tomcat web-app server
- webapp = addChild(EntitySpec.create(TomcatServer.class)
- .configure(UsesJmx.JMX_AGENT_MODE, UsesJmx.JmxAgentModes.JMX_RMI_CUSTOM_AGENT)
- .configure(UsesJmx.JMX_PORT, PortRanges.fromString("11099+"))
- .configure(UsesJmx.RMI_REGISTRY_PORT, PortRanges.fromString("9001+"))
- .configure(JavaWebAppService.ROOT_WAR, "https://cumulusrdf.googlecode.com/svn/wiki/downloads/cumulusrdf-1.0.1.war")
- .configure(UsesJava.JAVA_SYSPROPS, MutableMap.of("cumulusrdf.config-file", "/tmp/cumulus.yaml")));
-
- // Add an effector to tomcat to reconfigure with a new YAML config file
- ((EntityInternal) webapp).getMutableEntityType().addEffector(cumulusConfig, new EffectorBody<Void>() {
- @Override
- public Void call(ConfigBag parameters) {
- // Process the YAML template given in the application config
- String url = Entities.getRequiredUrlConfig(CumulusRDFApplication.this, CUMULUS_RDF_CONFIG_URL);
- Map<String, Object> config;
- synchronized (endpointMutex) {
- config = MutableMap.<String, Object>of("cassandraHostname", endpoint.getHostText(), "cassandraThriftPort", endpoint.getPort());
- }
- String contents = TemplateProcessor.processTemplateContents(ResourceUtils.create(CumulusRDFApplication.this).getResourceAsString(url), config);
- // Copy the file contents to the remote machine
- return DynamicTasks.queue(SshEffectorTasks.put("/tmp/cumulus.yaml").contents(contents)).get();
- }
- });
-
- // Listen for HOSTNAME changes from the Cassandra fabric to show at least one node is available
- subscribe(cassandra, CassandraDatacenter.HOSTNAME, new SensorEventListener<String>() {
- @Override
- public void onEvent(SensorEvent<String> event) {
- if (Strings.isNonBlank(event.getValue())) {
- synchronized (endpointMutex) {
- String hostname = Entities.submit(CumulusRDFApplication.this, DependentConfiguration.attributeWhenReady(cassandra, CassandraDatacenter.HOSTNAME)).getUnchecked();
- Integer thriftPort = Entities.submit(CumulusRDFApplication.this, DependentConfiguration.attributeWhenReady(cassandra, CassandraDatacenter.THRIFT_PORT)).getUnchecked();
- HostAndPort current = HostAndPort.fromParts(hostname, thriftPort);
-
- // Check if the cluster access point has changed
- if (!current.equals(endpoint)) {
- log.info("Setting cluster endpoint to {}", current.toString());
- endpoint = current;
-
- // Reconfigure the CumulusRDF application and restart tomcat if necessary
- webapp.invoke(cumulusConfig, MutableMap.<String, Object>of());
- if (webapp.getAttribute(Startable.SERVICE_UP)) {
- webapp.restart();
- }
- }
- }
- }
- }
- });
- }
-
- /**
- * Controls the startup locations for the webapp and the cassandra fabric.
- *
- * @see AbstractApplication#start(Collection)
- */
- @Override
- public void start(Collection<? extends Location> locations) {
- addLocations(locations);
-
- // The web application only needs to run in one location, use the first
- // TODO use a multi-region web cluster
- Collection<? extends Location> first = MutableList.copyOf(Iterables.limit(locations, 1));
-
- ServiceStateLogic.setExpectedState(this, Lifecycle.STARTING);
- try {
- Entities.invokeEffector(this, cassandra, Startable.START, MutableMap.of("locations", locations)).getUnchecked();
- Entities.invokeEffector(this, webapp, Startable.START, MutableMap.of("locations", first)).getUnchecked();
- } catch (Exception e) {
- throw Exceptions.propagate(e);
- } finally {
- ServiceStateLogic.setExpectedState(this, Lifecycle.RUNNING);
- }
- log.info("Started CumulusRDF in " + locations);
- }
-
-
- public static void main(String[] argv) {
- List<String> args = Lists.newArrayList(argv);
- String port = CommandLineUtil.getCommandLineOption(args, "--port", "8081+");
- String locations = CommandLineUtil.getCommandLineOption(args, "--locations", DEFAULT_LOCATIONS);
-
- BrooklynLauncher launcher = BrooklynLauncher.newInstance()
- .application(EntitySpec.create(StartableApplication.class, CumulusRDFApplication.class).displayName("CumulusRDF application using Cassandra"))
- .webconsolePort(port)
- .locations(Strings.isBlank(locations) ? ImmutableList.<String>of() : JavaStringEscapes.unwrapJsonishListIfPossible(locations))
- .start();
-
- Entities.dumpInfo(launcher.getApplications());
- }
-}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/44d2dc11/examples/simple-nosql-cluster/src/main/java/brooklyn/demo/HighAvailabilityCassandraCluster.java
----------------------------------------------------------------------
diff --git a/examples/simple-nosql-cluster/src/main/java/brooklyn/demo/HighAvailabilityCassandraCluster.java b/examples/simple-nosql-cluster/src/main/java/brooklyn/demo/HighAvailabilityCassandraCluster.java
deleted file mode 100644
index a105783..0000000
--- a/examples/simple-nosql-cluster/src/main/java/brooklyn/demo/HighAvailabilityCassandraCluster.java
+++ /dev/null
@@ -1,89 +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.demo;
-
-import java.util.List;
-
-import brooklyn.catalog.Catalog;
-import brooklyn.catalog.CatalogConfig;
-import brooklyn.config.ConfigKey;
-import brooklyn.entity.basic.AbstractApplication;
-import brooklyn.entity.basic.ConfigKeys;
-import brooklyn.entity.basic.Entities;
-import brooklyn.entity.basic.StartableApplication;
-import brooklyn.entity.nosql.cassandra.CassandraDatacenter;
-import brooklyn.entity.nosql.cassandra.CassandraNode;
-import brooklyn.entity.proxying.EntitySpec;
-import brooklyn.launcher.BrooklynLauncher;
-import brooklyn.policy.EnricherSpec;
-import brooklyn.policy.PolicySpec;
-import brooklyn.policy.ha.ServiceFailureDetector;
-import brooklyn.policy.ha.ServiceReplacer;
-import brooklyn.policy.ha.ServiceRestarter;
-import brooklyn.util.CommandLineUtil;
-
-import com.google.common.collect.Lists;
-
-@Catalog(name="HA Cassandra Cluster Application", description="Deploy a Cassandra cluster with a High Availability architecture.")
-public class HighAvailabilityCassandraCluster extends AbstractApplication {
-
- public static final String DEFAULT_LOCATION_SPEC = "aws-ec2:us-east-1";
-
- @CatalogConfig(label="Number of Availability Zones", priority=1)
- public static final ConfigKey<Integer> NUM_AVAILABILITY_ZONES = ConfigKeys.newConfigKey(
- "cassandra.cluster.numAvailabilityZones", "Number of availability zones to spread the cluster across", 3);
-
- @CatalogConfig(label="Initial Cluster Size", priority=2)
- public static final ConfigKey<Integer> CASSANDRA_CLUSTER_SIZE = ConfigKeys.newConfigKey(
- "cassandra.cluster.initialSize", "Initial size of the Cassandra cluster", 6);
-
-
- @Override
- public void initApp() {
- addChild(EntitySpec.create(CassandraDatacenter.class)
- .configure(CassandraDatacenter.CLUSTER_NAME, "Brooklyn")
- .configure(CassandraDatacenter.INITIAL_SIZE, getConfig(CASSANDRA_CLUSTER_SIZE))
- .configure(CassandraDatacenter.ENABLE_AVAILABILITY_ZONES, true)
- .configure(CassandraDatacenter.NUM_AVAILABILITY_ZONES, getConfig(NUM_AVAILABILITY_ZONES))
- //See https://github.com/brooklyncentral/brooklyn/issues/973
- //.configure(CassandraCluster.AVAILABILITY_ZONE_NAMES, ImmutableList.of("us-east-1b", "us-east-1c", "us-east-1e"))
- .configure(CassandraDatacenter.ENDPOINT_SNITCH_NAME, "GossipingPropertyFileSnitch")
- .configure(CassandraDatacenter.MEMBER_SPEC, EntitySpec.create(CassandraNode.class)
- .enricher(EnricherSpec.create(ServiceFailureDetector.class))
- .policy(PolicySpec.create(ServiceRestarter.class)
- .configure(ServiceRestarter.FAILURE_SENSOR_TO_MONITOR, ServiceFailureDetector.ENTITY_FAILED)))
- .policy(PolicySpec.create(ServiceReplacer.class)
- .configure(ServiceReplacer.FAILURE_SENSOR_TO_MONITOR, ServiceRestarter.ENTITY_RESTART_FAILED)));
- }
-
- public static void main(String[] argv) {
- List<String> args = Lists.newArrayList(argv);
- String port = CommandLineUtil.getCommandLineOption(args, "--port", "8081+");
- String location = CommandLineUtil.getCommandLineOption(args, "--location", DEFAULT_LOCATION_SPEC);
-
- BrooklynLauncher launcher = BrooklynLauncher.newInstance()
- .application(EntitySpec.create(StartableApplication.class, HighAvailabilityCassandraCluster.class)
- .displayName("Cassandra"))
- .webconsolePort(port)
- .location(location)
- .start();
-
- Entities.dumpInfo(launcher.getApplications());
- }
-}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/44d2dc11/examples/simple-nosql-cluster/src/main/java/brooklyn/demo/ResilientMongoDbApp.java
----------------------------------------------------------------------
diff --git a/examples/simple-nosql-cluster/src/main/java/brooklyn/demo/ResilientMongoDbApp.java b/examples/simple-nosql-cluster/src/main/java/brooklyn/demo/ResilientMongoDbApp.java
deleted file mode 100644
index 4acbbea..0000000
--- a/examples/simple-nosql-cluster/src/main/java/brooklyn/demo/ResilientMongoDbApp.java
+++ /dev/null
@@ -1,106 +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.demo;
-
-import java.util.List;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import brooklyn.catalog.Catalog;
-import brooklyn.enricher.Enrichers;
-import brooklyn.entity.Entity;
-import brooklyn.entity.basic.AbstractApplication;
-import brooklyn.entity.basic.Entities;
-import brooklyn.entity.basic.SoftwareProcess;
-import brooklyn.entity.basic.StartableApplication;
-import brooklyn.entity.group.DynamicCluster;
-import brooklyn.entity.nosql.mongodb.MongoDBReplicaSet;
-import brooklyn.entity.nosql.mongodb.MongoDBServer;
-import brooklyn.entity.proxying.EntitySpec;
-import brooklyn.event.SensorEvent;
-import brooklyn.event.SensorEventListener;
-import brooklyn.launcher.BrooklynLauncher;
-import brooklyn.policy.ha.ServiceFailureDetector;
-import brooklyn.policy.ha.ServiceReplacer;
-import brooklyn.policy.ha.ServiceRestarter;
-import brooklyn.util.CommandLineUtil;
-
-import com.google.common.collect.Lists;
-
-/**
- * Sample showing a MongoDB replica set with resilience policies attached at nodes and the cluster.
- **/
-@Catalog(name="Resilient MongoDB")
-public class ResilientMongoDbApp extends AbstractApplication implements StartableApplication {
-
- public static final Logger LOG = LoggerFactory.getLogger(ResilientMongoDbApp.class);
-
- public static final String DEFAULT_LOCATION = "named:gce-europe-west1";
-
- @Override
- public void initApp() {
- MongoDBReplicaSet rs = addChild(
- EntitySpec.create(MongoDBReplicaSet.class)
- .configure(MongoDBReplicaSet.INITIAL_SIZE, 3));
-
- initResilience(rs);
-
- addEnricher(Enrichers.builder()
- .propagating(MongoDBReplicaSet.REPLICA_SET_ENDPOINTS, MongoDBServer.REPLICA_SET_PRIMARY_ENDPOINT)
- .from(rs)
- .build());
- }
-
- /** this attaches a policy at each MongoDB node listening for ENTITY_FAILED,
- * attempting to _restart_ the process, and
- * failing that attempting to _replace_ the entity (e.g. a new VM), and
- * failing that setting the cluster "on-fire" */
- protected void initResilience(MongoDBReplicaSet rs) {
- subscribe(rs, DynamicCluster.MEMBER_ADDED, new SensorEventListener<Entity>() {
- @Override
- public void onEvent(SensorEvent<Entity> addition) {
- initSoftwareProcess((SoftwareProcess)addition.getValue());
- }
- });
- rs.addPolicy(new ServiceReplacer(ServiceRestarter.ENTITY_RESTART_FAILED));
- }
-
- /** invoked whenever a new MongoDB server is added (the server may not be started yet) */
- protected void initSoftwareProcess(SoftwareProcess p) {
- p.addEnricher(new ServiceFailureDetector());
- p.addPolicy(new ServiceRestarter(ServiceFailureDetector.ENTITY_FAILED));
- }
-
- public static void main(String[] argv) {
- List<String> args = Lists.newArrayList(argv);
- String port = CommandLineUtil.getCommandLineOption(args, "--port", "8081+");
- String location = CommandLineUtil.getCommandLineOption(args, "--location", DEFAULT_LOCATION);
-
- BrooklynLauncher launcher = BrooklynLauncher.newInstance()
- .application(EntitySpec.create(StartableApplication.class, ResilientMongoDbApp.class)
- .displayName("Resilient MongoDB"))
- .webconsolePort(port)
- .location(location)
- .start();
-
- Entities.dumpInfo(launcher.getApplications());
- }
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/44d2dc11/examples/simple-nosql-cluster/src/main/java/brooklyn/demo/RiakClusterExample.java
----------------------------------------------------------------------
diff --git a/examples/simple-nosql-cluster/src/main/java/brooklyn/demo/RiakClusterExample.java b/examples/simple-nosql-cluster/src/main/java/brooklyn/demo/RiakClusterExample.java
deleted file mode 100644
index 58b6f60..0000000
--- a/examples/simple-nosql-cluster/src/main/java/brooklyn/demo/RiakClusterExample.java
+++ /dev/null
@@ -1,76 +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.demo;
-
-import java.util.List;
-
-import brooklyn.catalog.Catalog;
-import brooklyn.catalog.CatalogConfig;
-import brooklyn.config.ConfigKey;
-import brooklyn.entity.basic.AbstractApplication;
-import brooklyn.entity.basic.ConfigKeys;
-import brooklyn.entity.basic.Entities;
-import brooklyn.entity.basic.StartableApplication;
-import brooklyn.entity.nosql.riak.RiakCluster;
-import brooklyn.entity.nosql.riak.RiakNode;
-import brooklyn.entity.proxying.EntitySpec;
-import brooklyn.launcher.BrooklynLauncher;
-import brooklyn.policy.EnricherSpec;
-import brooklyn.policy.PolicySpec;
-import brooklyn.policy.ha.ServiceFailureDetector;
-import brooklyn.policy.ha.ServiceRestarter;
-import brooklyn.util.CommandLineUtil;
-
-import com.google.common.base.Preconditions;
-import com.google.common.collect.Lists;
-
-@Catalog(name = "Riak Cluster Application", description = "Riak ring deployment blueprint")
-public class RiakClusterExample extends AbstractApplication {
-
- public static final String DEFAULT_LOCATION_SPEC = "aws-ec2:us-east-1";
-
- @CatalogConfig(label = "Riak Ring Size")
- public static final ConfigKey<Integer> RIAK_RING_SIZE = ConfigKeys.newConfigKey(
- "riak.ring.size", "Initial size of the Riak Ring", 4);
-
- public static void main(String[] argv) {
- List<String> args = Lists.newArrayList(argv);
- String port = CommandLineUtil.getCommandLineOption(args, "--port", "8081+");
- String location = CommandLineUtil.getCommandLineOption(args, "--location", DEFAULT_LOCATION_SPEC);
- Preconditions.checkArgument(args.isEmpty(), "Unsupported args: " + args);
-
- BrooklynLauncher launcher = BrooklynLauncher.newInstance()
- .application(EntitySpec.create(StartableApplication.class, RiakClusterExample.class))
- .webconsolePort(port)
- .location(location)
- .start();
-
- Entities.dumpInfo(launcher.getApplications());
- }
-
- public void initApp() {
- addChild(EntitySpec.create(RiakCluster.class)
- .configure(RiakCluster.INITIAL_SIZE, getConfig(RIAK_RING_SIZE))
- .configure(RiakCluster.MEMBER_SPEC, EntitySpec.create(RiakNode.class)
- .enricher(EnricherSpec.create(ServiceFailureDetector.class))
- .policy(PolicySpec.create(ServiceRestarter.class)
- .configure(ServiceRestarter.FAILURE_SENSOR_TO_MONITOR, ServiceFailureDetector.ENTITY_FAILED))));
- }
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/44d2dc11/examples/simple-nosql-cluster/src/main/java/brooklyn/demo/SimpleCassandraCluster.java
----------------------------------------------------------------------
diff --git a/examples/simple-nosql-cluster/src/main/java/brooklyn/demo/SimpleCassandraCluster.java b/examples/simple-nosql-cluster/src/main/java/brooklyn/demo/SimpleCassandraCluster.java
deleted file mode 100644
index 94f792c..0000000
--- a/examples/simple-nosql-cluster/src/main/java/brooklyn/demo/SimpleCassandraCluster.java
+++ /dev/null
@@ -1,58 +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.demo;
-
-import java.util.List;
-
-import brooklyn.entity.basic.AbstractApplication;
-import brooklyn.entity.basic.Entities;
-import brooklyn.entity.basic.StartableApplication;
-import brooklyn.entity.nosql.cassandra.CassandraDatacenter;
-import brooklyn.entity.proxying.EntitySpec;
-import brooklyn.launcher.BrooklynLauncher;
-import brooklyn.util.CommandLineUtil;
-
-import com.google.common.collect.Lists;
-
-public class SimpleCassandraCluster extends AbstractApplication {
-
- private static final String DEFAULT_LOCATION = "localhost";
-
- @Override
- public void initApp() {
- addChild(EntitySpec.create(CassandraDatacenter.class)
- .configure(CassandraDatacenter.INITIAL_SIZE, 1)
- .configure(CassandraDatacenter.CLUSTER_NAME, "Brooklyn"));
- }
-
- public static void main(String[] argv) {
- List<String> args = Lists.newArrayList(argv);
- String port = CommandLineUtil.getCommandLineOption(args, "--port", "8081+");
- String location = CommandLineUtil.getCommandLineOption(args, "--location", DEFAULT_LOCATION);
-
- BrooklynLauncher launcher = BrooklynLauncher.newInstance()
- .application(EntitySpec.create(StartableApplication.class, SimpleCassandraCluster.class)
- .displayName("Cassandra"))
- .webconsolePort(port)
- .location(location)
- .start();
-
- Entities.dumpInfo(launcher.getApplications());
- }
-}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/44d2dc11/examples/simple-nosql-cluster/src/main/java/brooklyn/demo/SimpleCouchDBCluster.java
----------------------------------------------------------------------
diff --git a/examples/simple-nosql-cluster/src/main/java/brooklyn/demo/SimpleCouchDBCluster.java b/examples/simple-nosql-cluster/src/main/java/brooklyn/demo/SimpleCouchDBCluster.java
deleted file mode 100644
index 6f249e2..0000000
--- a/examples/simple-nosql-cluster/src/main/java/brooklyn/demo/SimpleCouchDBCluster.java
+++ /dev/null
@@ -1,36 +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.demo;
-
-import brooklyn.entity.basic.ApplicationBuilder;
-import brooklyn.entity.nosql.couchdb.CouchDBCluster;
-import brooklyn.entity.proxying.EntitySpec;
-
-/** CouchDB cluster. */
-public class SimpleCouchDBCluster extends ApplicationBuilder {
-
- /** Create entities. */
- protected void doBuild() {
- addChild(EntitySpec.create(CouchDBCluster.class)
- .configure("initialSize", "2")
- .configure("clusterName", "Brooklyn")
- .configure("httpPort", "8000+"));
- }
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/44d2dc11/examples/simple-nosql-cluster/src/main/java/brooklyn/demo/SimpleMongoDBReplicaSet.java
----------------------------------------------------------------------
diff --git a/examples/simple-nosql-cluster/src/main/java/brooklyn/demo/SimpleMongoDBReplicaSet.java b/examples/simple-nosql-cluster/src/main/java/brooklyn/demo/SimpleMongoDBReplicaSet.java
deleted file mode 100644
index 5597590..0000000
--- a/examples/simple-nosql-cluster/src/main/java/brooklyn/demo/SimpleMongoDBReplicaSet.java
+++ /dev/null
@@ -1,39 +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.demo;
-
-import brooklyn.entity.basic.ApplicationBuilder;
-import brooklyn.entity.nosql.mongodb.MongoDBReplicaSet;
-import brooklyn.entity.nosql.mongodb.MongoDBServer;
-import brooklyn.entity.proxying.EntitySpec;
-
-public class SimpleMongoDBReplicaSet extends ApplicationBuilder {
-
- protected void doBuild() {
- addChild(EntitySpec.create(MongoDBReplicaSet.class)
- .configure("name", "Simple MongoDB replica set")
- .configure("initialSize", 3)
- .configure("replicaSetName", "simple-replica-set")
- .configure("memberSpec", EntitySpec.create(MongoDBServer.class)
- .configure("mongodbConfTemplateUrl", "classpath:///mongodb.conf")
- .configure("enableRestInterface", true)
- .configure("port", "27017+")));
- }
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/44d2dc11/examples/simple-nosql-cluster/src/main/java/brooklyn/demo/SimpleRedisCluster.java
----------------------------------------------------------------------
diff --git a/examples/simple-nosql-cluster/src/main/java/brooklyn/demo/SimpleRedisCluster.java b/examples/simple-nosql-cluster/src/main/java/brooklyn/demo/SimpleRedisCluster.java
deleted file mode 100644
index ed899b3..0000000
--- a/examples/simple-nosql-cluster/src/main/java/brooklyn/demo/SimpleRedisCluster.java
+++ /dev/null
@@ -1,35 +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.demo;
-
-import brooklyn.entity.basic.ApplicationBuilder;
-import brooklyn.entity.nosql.redis.RedisCluster;
-import brooklyn.entity.proxying.EntitySpec;
-
-/** Redis cluster. */
-public class SimpleRedisCluster extends ApplicationBuilder {
-
- /** Create entities. */
- protected void doBuild() {
- addChild(EntitySpec.create(RedisCluster.class)
- .configure("initialSize", "2")
- .configure("clusterName", "Brooklyn"));
- }
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/44d2dc11/examples/simple-nosql-cluster/src/main/java/brooklyn/demo/StormSampleApp.java
----------------------------------------------------------------------
diff --git a/examples/simple-nosql-cluster/src/main/java/brooklyn/demo/StormSampleApp.java b/examples/simple-nosql-cluster/src/main/java/brooklyn/demo/StormSampleApp.java
deleted file mode 100644
index 732ccd5..0000000
--- a/examples/simple-nosql-cluster/src/main/java/brooklyn/demo/StormSampleApp.java
+++ /dev/null
@@ -1,70 +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.demo;
-
-import java.util.List;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import brooklyn.catalog.Catalog;
-import brooklyn.entity.basic.AbstractApplication;
-import brooklyn.entity.basic.Entities;
-import brooklyn.entity.basic.StartableApplication;
-import brooklyn.entity.messaging.storm.StormDeployment;
-import brooklyn.entity.proxying.EntitySpec;
-import brooklyn.launcher.BrooklynLauncher;
-import brooklyn.util.CommandLineUtil;
-
-import com.google.common.collect.Lists;
-
-/**
- * Sample showing a storm analyticscluster
- **/
-@Catalog(name="Storm Sample App",
-description="Creates a Storm analytics cluster",
- iconUrl="classpath://brooklyn/demo/glossy-3d-blue-web-icon.png")
-public class StormSampleApp extends AbstractApplication implements StartableApplication {
-
- public static final Logger LOG = LoggerFactory.getLogger(StormSampleApp.class);
-
- public static final String DEFAULT_LOCATION = "named:gce-europe-west1";
-
- @Override
- public void initApp() {
- addChild(EntitySpec.create(StormDeployment.class)
- .configure(StormDeployment.SUPERVISORS_COUNT, 2)
- .configure(StormDeployment.ZOOKEEPERS_COUNT, 1));
- }
-
- public static void main(String[] argv) {
- List<String> args = Lists.newArrayList(argv);
- String port = CommandLineUtil.getCommandLineOption(args, "--port", "8081+");
- String location = CommandLineUtil.getCommandLineOption(args, "--location", DEFAULT_LOCATION);
-
- BrooklynLauncher launcher = BrooklynLauncher.newInstance()
- .application(EntitySpec.create(StartableApplication.class, StormSampleApp.class)
- .displayName("Storm App"))
- .webconsolePort(port)
- .location(location)
- .start();
-
- Entities.dumpInfo(launcher.getApplications());
- }
-}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/44d2dc11/examples/simple-nosql-cluster/src/main/java/brooklyn/demo/WideAreaCassandraCluster.java
----------------------------------------------------------------------
diff --git a/examples/simple-nosql-cluster/src/main/java/brooklyn/demo/WideAreaCassandraCluster.java b/examples/simple-nosql-cluster/src/main/java/brooklyn/demo/WideAreaCassandraCluster.java
deleted file mode 100644
index 7c441ee..0000000
--- a/examples/simple-nosql-cluster/src/main/java/brooklyn/demo/WideAreaCassandraCluster.java
+++ /dev/null
@@ -1,86 +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.demo;
-
-import java.util.Arrays;
-import java.util.List;
-
-import brooklyn.catalog.Catalog;
-import brooklyn.catalog.CatalogConfig;
-import brooklyn.config.ConfigKey;
-import brooklyn.entity.basic.AbstractApplication;
-import brooklyn.entity.basic.ConfigKeys;
-import brooklyn.entity.basic.Entities;
-import brooklyn.entity.basic.StartableApplication;
-import brooklyn.entity.nosql.cassandra.CassandraDatacenter;
-import brooklyn.entity.nosql.cassandra.CassandraFabric;
-import brooklyn.entity.nosql.cassandra.CassandraNode;
-import brooklyn.entity.proxying.EntitySpec;
-import brooklyn.launcher.BrooklynLauncher;
-import brooklyn.policy.EnricherSpec;
-import brooklyn.policy.PolicySpec;
-import brooklyn.policy.ha.ServiceFailureDetector;
-import brooklyn.policy.ha.ServiceReplacer;
-import brooklyn.policy.ha.ServiceRestarter;
-import brooklyn.util.CommandLineUtil;
-
-import com.google.common.collect.Lists;
-
-@Catalog(name="Wide Area Cassandra Cluster Application", description="Deploy a Cassandra cluster across multiple geographies.")
-public class WideAreaCassandraCluster extends AbstractApplication {
-
- public static final String DEFAULT_LOCATION_SPEC = "aws-ec2:us-east-1,rackspace-cloudservers-uk";
-
- @CatalogConfig(label="Initial Cluster Size (per location)", priority=2)
- public static final ConfigKey<Integer> CASSANDRA_CLUSTER_SIZE = ConfigKeys.newConfigKey(
- "cassandra.cluster.initialSize", "Initial size of the Cassandra clusterss", 2);
-
-
-
- @Override
- public void initApp() {
- addChild(EntitySpec.create(CassandraFabric.class)
- .configure(CassandraDatacenter.CLUSTER_NAME, "Brooklyn")
- .configure(CassandraDatacenter.INITIAL_SIZE, getConfig(CASSANDRA_CLUSTER_SIZE)) // per location
- .configure(CassandraDatacenter.ENDPOINT_SNITCH_NAME, "brooklyn.entity.nosql.cassandra.customsnitch.MultiCloudSnitch")
- .configure(CassandraNode.CUSTOM_SNITCH_JAR_URL, "classpath://brooklyn/entity/nosql/cassandra/cassandra-multicloud-snitch.jar")
- .configure(CassandraFabric.MEMBER_SPEC, EntitySpec.create(CassandraDatacenter.class)
- .configure(CassandraDatacenter.MEMBER_SPEC, EntitySpec.create(CassandraNode.class)
- .enricher(EnricherSpec.create(ServiceFailureDetector.class))
- .policy(PolicySpec.create(ServiceRestarter.class)
- .configure(ServiceRestarter.FAILURE_SENSOR_TO_MONITOR, ServiceFailureDetector.ENTITY_FAILED)))
- .policy(PolicySpec.create(ServiceReplacer.class)
- .configure(ServiceReplacer.FAILURE_SENSOR_TO_MONITOR, ServiceRestarter.ENTITY_RESTART_FAILED))));
- }
-
- public static void main(String[] argv) {
- List<String> args = Lists.newArrayList(argv);
- String port = CommandLineUtil.getCommandLineOption(args, "--port", "8081+");
- String locations = CommandLineUtil.getCommandLineOption(args, "--location", DEFAULT_LOCATION_SPEC);
-
- BrooklynLauncher launcher = BrooklynLauncher.newInstance()
- .application(EntitySpec.create(StartableApplication.class, WideAreaCassandraCluster.class)
- .displayName("Cassandra"))
- .webconsolePort(port)
- .locations(Arrays.asList(locations))
- .start();
-
- Entities.dumpInfo(launcher.getApplications());
- }
-}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/44d2dc11/examples/simple-nosql-cluster/src/main/java/org/apache/brooklyn/demo/CumulusRDFApplication.java
----------------------------------------------------------------------
diff --git a/examples/simple-nosql-cluster/src/main/java/org/apache/brooklyn/demo/CumulusRDFApplication.java b/examples/simple-nosql-cluster/src/main/java/org/apache/brooklyn/demo/CumulusRDFApplication.java
new file mode 100644
index 0000000..f2ec860
--- /dev/null
+++ b/examples/simple-nosql-cluster/src/main/java/org/apache/brooklyn/demo/CumulusRDFApplication.java
@@ -0,0 +1,240 @@
+/*
+ * 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 java.util.Collection;
+import java.util.List;
+import java.util.Map;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import brooklyn.catalog.Catalog;
+import brooklyn.catalog.CatalogConfig;
+import brooklyn.config.ConfigKey;
+import brooklyn.entity.Effector;
+import brooklyn.entity.Entity;
+import brooklyn.entity.basic.AbstractApplication;
+import brooklyn.entity.basic.ConfigKeys;
+import brooklyn.entity.basic.Entities;
+import brooklyn.entity.basic.EntityInternal;
+import brooklyn.entity.basic.Lifecycle;
+import brooklyn.entity.basic.ServiceStateLogic;
+import brooklyn.entity.basic.StartableApplication;
+import brooklyn.entity.effector.EffectorBody;
+import brooklyn.entity.effector.Effectors;
+import brooklyn.entity.java.UsesJava;
+import brooklyn.entity.java.UsesJmx;
+import brooklyn.entity.nosql.cassandra.CassandraDatacenter;
+import brooklyn.entity.nosql.cassandra.CassandraFabric;
+import brooklyn.entity.nosql.cassandra.CassandraNode;
+import brooklyn.entity.proxying.EntitySpec;
+import brooklyn.entity.software.SshEffectorTasks;
+import brooklyn.entity.trait.Startable;
+import brooklyn.entity.webapp.JavaWebAppService;
+import brooklyn.entity.webapp.tomcat.TomcatServer;
+import brooklyn.event.SensorEvent;
+import brooklyn.event.SensorEventListener;
+import brooklyn.event.basic.DependentConfiguration;
+import brooklyn.launcher.BrooklynLauncher;
+import brooklyn.location.Location;
+import brooklyn.location.basic.PortRanges;
+import brooklyn.policy.EnricherSpec;
+import brooklyn.policy.PolicySpec;
+import brooklyn.policy.ha.ServiceFailureDetector;
+import brooklyn.policy.ha.ServiceReplacer;
+import brooklyn.policy.ha.ServiceRestarter;
+import brooklyn.util.CommandLineUtil;
+import brooklyn.util.ResourceUtils;
+import brooklyn.util.collections.MutableList;
+import brooklyn.util.collections.MutableMap;
+import brooklyn.util.config.ConfigBag;
+import brooklyn.util.exceptions.Exceptions;
+import brooklyn.util.task.DynamicTasks;
+import brooklyn.util.text.StringEscapes.JavaStringEscapes;
+import brooklyn.util.text.Strings;
+import brooklyn.util.text.TemplateProcessor;
+
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.Iterables;
+import com.google.common.collect.Lists;
+import com.google.common.net.HostAndPort;
+
+/** CumulusRDF application with Cassandra cluster. */
+@Catalog(name="Cumulus RDF Application", description="CumulusRDF Application on a Tomcat server using a multi-region Cassandra fabric")
+public class CumulusRDFApplication extends AbstractApplication {
+
+ private static final Logger log = LoggerFactory.getLogger(CumulusRDFApplication.class);
+
+ @CatalogConfig(label="Cumulus Configuration File (URL)", priority=1)
+ public static final ConfigKey<String> CUMULUS_RDF_CONFIG_URL = ConfigKeys.newConfigKey(
+ "cumulus.config.url", "URL for the YAML configuration file for CumulusRDF", "classpath://cumulus.yaml");
+
+ @CatalogConfig(label="Cassandra Thrift Port", priority=1)
+ public static final ConfigKey<Integer> CASSANDRA_THRIFT_PORT = ConfigKeys.newConfigKey(
+ "cumulus.cassandra.port", "Port to contact the Cassandra cluster on", 9160);
+
+ @CatalogConfig(label="Cassandra Cluster Size", priority=1)
+ public static final ConfigKey<Integer> CASSANDRA_CLUSTER_SIZE = ConfigKeys.newConfigKey(
+ "cumulus.cassandra.cluster.size", "Initial size of the Cassandra cluster", 2);
+
+ @CatalogConfig(label="Multi-region Fabric", priority=1)
+ public static final ConfigKey<Boolean> MULTI_REGION_FABRIC = ConfigKeys.newConfigKey(
+ "cumulus.cassandra.fabric", "Deploy a multi-region Cassandra fabric", false);
+
+ // TODO Fails when given two locations
+ // public static final String DEFAULT_LOCATIONS = "[ jclouds:aws-ec2:us-east-1,jclouds:rackspace-cloudservers-uk ]";
+ public static final String DEFAULT_LOCATIONS = "jclouds:aws-ec2:us-east-1";
+
+ private Effector<Void> cumulusConfig = Effectors.effector(Void.class, "cumulusConfig")
+ .description("Configure the CumulusRDF web application")
+ .buildAbstract();
+
+ private Entity cassandra;
+ private TomcatServer webapp;
+ private HostAndPort endpoint;
+ private final Object endpointMutex = new Object();
+
+ /**
+ * Create the application entities:
+ * <ul>
+ * <li>A {@link CassandraFabric} of {@link CassandraDatacenter}s containing {@link CassandraNode}s
+ * <li>A {@link TomcatServer}
+ * </ul>
+ */
+ @Override
+ public void initApp() {
+ // Cassandra cluster
+ EntitySpec<CassandraDatacenter> clusterSpec = EntitySpec.create(CassandraDatacenter.class)
+ .configure(CassandraDatacenter.MEMBER_SPEC, EntitySpec.create(CassandraNode.class)
+ //FIXME can probably use JMXMP_AND_RMI now, to deploy to GCE and elsewhere
+ .configure(UsesJmx.JMX_AGENT_MODE, UsesJmx.JmxAgentModes.JMX_RMI_CUSTOM_AGENT)
+ .configure(UsesJmx.JMX_PORT, PortRanges.fromString("11099+"))
+ .configure(UsesJmx.RMI_REGISTRY_PORT, PortRanges.fromString("9001+"))
+ .configure(CassandraNode.THRIFT_PORT, PortRanges.fromInteger(getConfig(CASSANDRA_THRIFT_PORT)))
+ .enricher(EnricherSpec.create(ServiceFailureDetector.class))
+ .policy(PolicySpec.create(ServiceRestarter.class)
+ .configure(ServiceRestarter.FAILURE_SENSOR_TO_MONITOR, ServiceFailureDetector.ENTITY_FAILED)))
+ .policy(PolicySpec.create(ServiceReplacer.class)
+ .configure(ServiceReplacer.FAILURE_SENSOR_TO_MONITOR, ServiceRestarter.ENTITY_RESTART_FAILED));
+
+ if (getConfig(MULTI_REGION_FABRIC)) {
+ cassandra = addChild(EntitySpec.create(CassandraFabric.class)
+ .configure(CassandraDatacenter.CLUSTER_NAME, "Brooklyn")
+ .configure(CassandraDatacenter.INITIAL_SIZE, getConfig(CASSANDRA_CLUSTER_SIZE)) // per location
+ .configure(CassandraDatacenter.ENDPOINT_SNITCH_NAME, "brooklyn.entity.nosql.cassandra.customsnitch.MultiCloudSnitch")
+ .configure(CassandraNode.CUSTOM_SNITCH_JAR_URL, "classpath://brooklyn/entity/nosql/cassandra/cassandra-multicloud-snitch.jar")
+ .configure(CassandraFabric.MEMBER_SPEC, clusterSpec));
+ } else {
+ cassandra = addChild(EntitySpec.create(clusterSpec)
+ .configure(CassandraDatacenter.CLUSTER_NAME, "Brooklyn")
+ .configure(CassandraDatacenter.INITIAL_SIZE, getConfig(CASSANDRA_CLUSTER_SIZE)));
+ }
+
+ // Tomcat web-app server
+ webapp = addChild(EntitySpec.create(TomcatServer.class)
+ .configure(UsesJmx.JMX_AGENT_MODE, UsesJmx.JmxAgentModes.JMX_RMI_CUSTOM_AGENT)
+ .configure(UsesJmx.JMX_PORT, PortRanges.fromString("11099+"))
+ .configure(UsesJmx.RMI_REGISTRY_PORT, PortRanges.fromString("9001+"))
+ .configure(JavaWebAppService.ROOT_WAR, "https://cumulusrdf.googlecode.com/svn/wiki/downloads/cumulusrdf-1.0.1.war")
+ .configure(UsesJava.JAVA_SYSPROPS, MutableMap.of("cumulusrdf.config-file", "/tmp/cumulus.yaml")));
+
+ // Add an effector to tomcat to reconfigure with a new YAML config file
+ ((EntityInternal) webapp).getMutableEntityType().addEffector(cumulusConfig, new EffectorBody<Void>() {
+ @Override
+ public Void call(ConfigBag parameters) {
+ // Process the YAML template given in the application config
+ String url = Entities.getRequiredUrlConfig(CumulusRDFApplication.this, CUMULUS_RDF_CONFIG_URL);
+ Map<String, Object> config;
+ synchronized (endpointMutex) {
+ config = MutableMap.<String, Object>of("cassandraHostname", endpoint.getHostText(), "cassandraThriftPort", endpoint.getPort());
+ }
+ String contents = TemplateProcessor.processTemplateContents(ResourceUtils.create(CumulusRDFApplication.this).getResourceAsString(url), config);
+ // Copy the file contents to the remote machine
+ return DynamicTasks.queue(SshEffectorTasks.put("/tmp/cumulus.yaml").contents(contents)).get();
+ }
+ });
+
+ // Listen for HOSTNAME changes from the Cassandra fabric to show at least one node is available
+ subscribe(cassandra, CassandraDatacenter.HOSTNAME, new SensorEventListener<String>() {
+ @Override
+ public void onEvent(SensorEvent<String> event) {
+ if (Strings.isNonBlank(event.getValue())) {
+ synchronized (endpointMutex) {
+ String hostname = Entities.submit(CumulusRDFApplication.this, DependentConfiguration.attributeWhenReady(cassandra, CassandraDatacenter.HOSTNAME)).getUnchecked();
+ Integer thriftPort = Entities.submit(CumulusRDFApplication.this, DependentConfiguration.attributeWhenReady(cassandra, CassandraDatacenter.THRIFT_PORT)).getUnchecked();
+ HostAndPort current = HostAndPort.fromParts(hostname, thriftPort);
+
+ // Check if the cluster access point has changed
+ if (!current.equals(endpoint)) {
+ log.info("Setting cluster endpoint to {}", current.toString());
+ endpoint = current;
+
+ // Reconfigure the CumulusRDF application and restart tomcat if necessary
+ webapp.invoke(cumulusConfig, MutableMap.<String, Object>of());
+ if (webapp.getAttribute(Startable.SERVICE_UP)) {
+ webapp.restart();
+ }
+ }
+ }
+ }
+ }
+ });
+ }
+
+ /**
+ * Controls the startup locations for the webapp and the cassandra fabric.
+ *
+ * @see AbstractApplication#start(Collection)
+ */
+ @Override
+ public void start(Collection<? extends Location> locations) {
+ addLocations(locations);
+
+ // The web application only needs to run in one location, use the first
+ // TODO use a multi-region web cluster
+ Collection<? extends Location> first = MutableList.copyOf(Iterables.limit(locations, 1));
+
+ ServiceStateLogic.setExpectedState(this, Lifecycle.STARTING);
+ try {
+ Entities.invokeEffector(this, cassandra, Startable.START, MutableMap.of("locations", locations)).getUnchecked();
+ Entities.invokeEffector(this, webapp, Startable.START, MutableMap.of("locations", first)).getUnchecked();
+ } catch (Exception e) {
+ throw Exceptions.propagate(e);
+ } finally {
+ ServiceStateLogic.setExpectedState(this, Lifecycle.RUNNING);
+ }
+ log.info("Started CumulusRDF in " + locations);
+ }
+
+
+ public static void main(String[] argv) {
+ List<String> args = Lists.newArrayList(argv);
+ String port = CommandLineUtil.getCommandLineOption(args, "--port", "8081+");
+ String locations = CommandLineUtil.getCommandLineOption(args, "--locations", DEFAULT_LOCATIONS);
+
+ BrooklynLauncher launcher = BrooklynLauncher.newInstance()
+ .application(EntitySpec.create(StartableApplication.class, CumulusRDFApplication.class).displayName("CumulusRDF application using Cassandra"))
+ .webconsolePort(port)
+ .locations(Strings.isBlank(locations) ? ImmutableList.<String>of() : JavaStringEscapes.unwrapJsonishListIfPossible(locations))
+ .start();
+
+ Entities.dumpInfo(launcher.getApplications());
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/44d2dc11/examples/simple-nosql-cluster/src/main/java/org/apache/brooklyn/demo/HighAvailabilityCassandraCluster.java
----------------------------------------------------------------------
diff --git a/examples/simple-nosql-cluster/src/main/java/org/apache/brooklyn/demo/HighAvailabilityCassandraCluster.java b/examples/simple-nosql-cluster/src/main/java/org/apache/brooklyn/demo/HighAvailabilityCassandraCluster.java
new file mode 100644
index 0000000..b6800f1
--- /dev/null
+++ b/examples/simple-nosql-cluster/src/main/java/org/apache/brooklyn/demo/HighAvailabilityCassandraCluster.java
@@ -0,0 +1,89 @@
+/*
+ * 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 java.util.List;
+
+import brooklyn.catalog.Catalog;
+import brooklyn.catalog.CatalogConfig;
+import brooklyn.config.ConfigKey;
+import brooklyn.entity.basic.AbstractApplication;
+import brooklyn.entity.basic.ConfigKeys;
+import brooklyn.entity.basic.Entities;
+import brooklyn.entity.basic.StartableApplication;
+import brooklyn.entity.nosql.cassandra.CassandraDatacenter;
+import brooklyn.entity.nosql.cassandra.CassandraNode;
+import brooklyn.entity.proxying.EntitySpec;
+import brooklyn.launcher.BrooklynLauncher;
+import brooklyn.policy.EnricherSpec;
+import brooklyn.policy.PolicySpec;
+import brooklyn.policy.ha.ServiceFailureDetector;
+import brooklyn.policy.ha.ServiceReplacer;
+import brooklyn.policy.ha.ServiceRestarter;
+import brooklyn.util.CommandLineUtil;
+
+import com.google.common.collect.Lists;
+
+@Catalog(name="HA Cassandra Cluster Application", description="Deploy a Cassandra cluster with a High Availability architecture.")
+public class HighAvailabilityCassandraCluster extends AbstractApplication {
+
+ public static final String DEFAULT_LOCATION_SPEC = "aws-ec2:us-east-1";
+
+ @CatalogConfig(label="Number of Availability Zones", priority=1)
+ public static final ConfigKey<Integer> NUM_AVAILABILITY_ZONES = ConfigKeys.newConfigKey(
+ "cassandra.cluster.numAvailabilityZones", "Number of availability zones to spread the cluster across", 3);
+
+ @CatalogConfig(label="Initial Cluster Size", priority=2)
+ public static final ConfigKey<Integer> CASSANDRA_CLUSTER_SIZE = ConfigKeys.newConfigKey(
+ "cassandra.cluster.initialSize", "Initial size of the Cassandra cluster", 6);
+
+
+ @Override
+ public void initApp() {
+ addChild(EntitySpec.create(CassandraDatacenter.class)
+ .configure(CassandraDatacenter.CLUSTER_NAME, "Brooklyn")
+ .configure(CassandraDatacenter.INITIAL_SIZE, getConfig(CASSANDRA_CLUSTER_SIZE))
+ .configure(CassandraDatacenter.ENABLE_AVAILABILITY_ZONES, true)
+ .configure(CassandraDatacenter.NUM_AVAILABILITY_ZONES, getConfig(NUM_AVAILABILITY_ZONES))
+ //See https://github.com/brooklyncentral/brooklyn/issues/973
+ //.configure(CassandraCluster.AVAILABILITY_ZONE_NAMES, ImmutableList.of("us-east-1b", "us-east-1c", "us-east-1e"))
+ .configure(CassandraDatacenter.ENDPOINT_SNITCH_NAME, "GossipingPropertyFileSnitch")
+ .configure(CassandraDatacenter.MEMBER_SPEC, EntitySpec.create(CassandraNode.class)
+ .enricher(EnricherSpec.create(ServiceFailureDetector.class))
+ .policy(PolicySpec.create(ServiceRestarter.class)
+ .configure(ServiceRestarter.FAILURE_SENSOR_TO_MONITOR, ServiceFailureDetector.ENTITY_FAILED)))
+ .policy(PolicySpec.create(ServiceReplacer.class)
+ .configure(ServiceReplacer.FAILURE_SENSOR_TO_MONITOR, ServiceRestarter.ENTITY_RESTART_FAILED)));
+ }
+
+ public static void main(String[] argv) {
+ List<String> args = Lists.newArrayList(argv);
+ String port = CommandLineUtil.getCommandLineOption(args, "--port", "8081+");
+ String location = CommandLineUtil.getCommandLineOption(args, "--location", DEFAULT_LOCATION_SPEC);
+
+ BrooklynLauncher launcher = BrooklynLauncher.newInstance()
+ .application(EntitySpec.create(StartableApplication.class, HighAvailabilityCassandraCluster.class)
+ .displayName("Cassandra"))
+ .webconsolePort(port)
+ .location(location)
+ .start();
+
+ Entities.dumpInfo(launcher.getApplications());
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/44d2dc11/examples/simple-nosql-cluster/src/main/java/org/apache/brooklyn/demo/ResilientMongoDbApp.java
----------------------------------------------------------------------
diff --git a/examples/simple-nosql-cluster/src/main/java/org/apache/brooklyn/demo/ResilientMongoDbApp.java b/examples/simple-nosql-cluster/src/main/java/org/apache/brooklyn/demo/ResilientMongoDbApp.java
new file mode 100644
index 0000000..d98a11c
--- /dev/null
+++ b/examples/simple-nosql-cluster/src/main/java/org/apache/brooklyn/demo/ResilientMongoDbApp.java
@@ -0,0 +1,106 @@
+/*
+ * 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 java.util.List;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import brooklyn.catalog.Catalog;
+import brooklyn.enricher.Enrichers;
+import brooklyn.entity.Entity;
+import brooklyn.entity.basic.AbstractApplication;
+import brooklyn.entity.basic.Entities;
+import brooklyn.entity.basic.SoftwareProcess;
+import brooklyn.entity.basic.StartableApplication;
+import brooklyn.entity.group.DynamicCluster;
+import brooklyn.entity.nosql.mongodb.MongoDBReplicaSet;
+import brooklyn.entity.nosql.mongodb.MongoDBServer;
+import brooklyn.entity.proxying.EntitySpec;
+import brooklyn.event.SensorEvent;
+import brooklyn.event.SensorEventListener;
+import brooklyn.launcher.BrooklynLauncher;
+import brooklyn.policy.ha.ServiceFailureDetector;
+import brooklyn.policy.ha.ServiceReplacer;
+import brooklyn.policy.ha.ServiceRestarter;
+import brooklyn.util.CommandLineUtil;
+
+import com.google.common.collect.Lists;
+
+/**
+ * Sample showing a MongoDB replica set with resilience policies attached at nodes and the cluster.
+ **/
+@Catalog(name="Resilient MongoDB")
+public class ResilientMongoDbApp extends AbstractApplication implements StartableApplication {
+
+ public static final Logger LOG = LoggerFactory.getLogger(ResilientMongoDbApp.class);
+
+ public static final String DEFAULT_LOCATION = "named:gce-europe-west1";
+
+ @Override
+ public void initApp() {
+ MongoDBReplicaSet rs = addChild(
+ EntitySpec.create(MongoDBReplicaSet.class)
+ .configure(MongoDBReplicaSet.INITIAL_SIZE, 3));
+
+ initResilience(rs);
+
+ addEnricher(Enrichers.builder()
+ .propagating(MongoDBReplicaSet.REPLICA_SET_ENDPOINTS, MongoDBServer.REPLICA_SET_PRIMARY_ENDPOINT)
+ .from(rs)
+ .build());
+ }
+
+ /** this attaches a policy at each MongoDB node listening for ENTITY_FAILED,
+ * attempting to _restart_ the process, and
+ * failing that attempting to _replace_ the entity (e.g. a new VM), and
+ * failing that setting the cluster "on-fire" */
+ protected void initResilience(MongoDBReplicaSet rs) {
+ subscribe(rs, DynamicCluster.MEMBER_ADDED, new SensorEventListener<Entity>() {
+ @Override
+ public void onEvent(SensorEvent<Entity> addition) {
+ initSoftwareProcess((SoftwareProcess)addition.getValue());
+ }
+ });
+ rs.addPolicy(new ServiceReplacer(ServiceRestarter.ENTITY_RESTART_FAILED));
+ }
+
+ /** invoked whenever a new MongoDB server is added (the server may not be started yet) */
+ protected void initSoftwareProcess(SoftwareProcess p) {
+ p.addEnricher(new ServiceFailureDetector());
+ p.addPolicy(new ServiceRestarter(ServiceFailureDetector.ENTITY_FAILED));
+ }
+
+ public static void main(String[] argv) {
+ List<String> args = Lists.newArrayList(argv);
+ String port = CommandLineUtil.getCommandLineOption(args, "--port", "8081+");
+ String location = CommandLineUtil.getCommandLineOption(args, "--location", DEFAULT_LOCATION);
+
+ BrooklynLauncher launcher = BrooklynLauncher.newInstance()
+ .application(EntitySpec.create(StartableApplication.class, ResilientMongoDbApp.class)
+ .displayName("Resilient MongoDB"))
+ .webconsolePort(port)
+ .location(location)
+ .start();
+
+ Entities.dumpInfo(launcher.getApplications());
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/44d2dc11/examples/simple-nosql-cluster/src/main/java/org/apache/brooklyn/demo/RiakClusterExample.java
----------------------------------------------------------------------
diff --git a/examples/simple-nosql-cluster/src/main/java/org/apache/brooklyn/demo/RiakClusterExample.java b/examples/simple-nosql-cluster/src/main/java/org/apache/brooklyn/demo/RiakClusterExample.java
new file mode 100644
index 0000000..672aba3
--- /dev/null
+++ b/examples/simple-nosql-cluster/src/main/java/org/apache/brooklyn/demo/RiakClusterExample.java
@@ -0,0 +1,76 @@
+/*
+ * 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 java.util.List;
+
+import brooklyn.catalog.Catalog;
+import brooklyn.catalog.CatalogConfig;
+import brooklyn.config.ConfigKey;
+import brooklyn.entity.basic.AbstractApplication;
+import brooklyn.entity.basic.ConfigKeys;
+import brooklyn.entity.basic.Entities;
+import brooklyn.entity.basic.StartableApplication;
+import brooklyn.entity.nosql.riak.RiakCluster;
+import brooklyn.entity.nosql.riak.RiakNode;
+import brooklyn.entity.proxying.EntitySpec;
+import brooklyn.launcher.BrooklynLauncher;
+import brooklyn.policy.EnricherSpec;
+import brooklyn.policy.PolicySpec;
+import brooklyn.policy.ha.ServiceFailureDetector;
+import brooklyn.policy.ha.ServiceRestarter;
+import brooklyn.util.CommandLineUtil;
+
+import com.google.common.base.Preconditions;
+import com.google.common.collect.Lists;
+
+@Catalog(name = "Riak Cluster Application", description = "Riak ring deployment blueprint")
+public class RiakClusterExample extends AbstractApplication {
+
+ public static final String DEFAULT_LOCATION_SPEC = "aws-ec2:us-east-1";
+
+ @CatalogConfig(label = "Riak Ring Size")
+ public static final ConfigKey<Integer> RIAK_RING_SIZE = ConfigKeys.newConfigKey(
+ "riak.ring.size", "Initial size of the Riak Ring", 4);
+
+ public static void main(String[] argv) {
+ List<String> args = Lists.newArrayList(argv);
+ String port = CommandLineUtil.getCommandLineOption(args, "--port", "8081+");
+ String location = CommandLineUtil.getCommandLineOption(args, "--location", DEFAULT_LOCATION_SPEC);
+ Preconditions.checkArgument(args.isEmpty(), "Unsupported args: " + args);
+
+ BrooklynLauncher launcher = BrooklynLauncher.newInstance()
+ .application(EntitySpec.create(StartableApplication.class, RiakClusterExample.class))
+ .webconsolePort(port)
+ .location(location)
+ .start();
+
+ Entities.dumpInfo(launcher.getApplications());
+ }
+
+ public void initApp() {
+ addChild(EntitySpec.create(RiakCluster.class)
+ .configure(RiakCluster.INITIAL_SIZE, getConfig(RIAK_RING_SIZE))
+ .configure(RiakCluster.MEMBER_SPEC, EntitySpec.create(RiakNode.class)
+ .enricher(EnricherSpec.create(ServiceFailureDetector.class))
+ .policy(PolicySpec.create(ServiceRestarter.class)
+ .configure(ServiceRestarter.FAILURE_SENSOR_TO_MONITOR, ServiceFailureDetector.ENTITY_FAILED))));
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/44d2dc11/examples/simple-nosql-cluster/src/main/java/org/apache/brooklyn/demo/SimpleCassandraCluster.java
----------------------------------------------------------------------
diff --git a/examples/simple-nosql-cluster/src/main/java/org/apache/brooklyn/demo/SimpleCassandraCluster.java b/examples/simple-nosql-cluster/src/main/java/org/apache/brooklyn/demo/SimpleCassandraCluster.java
new file mode 100644
index 0000000..2ba6ba3
--- /dev/null
+++ b/examples/simple-nosql-cluster/src/main/java/org/apache/brooklyn/demo/SimpleCassandraCluster.java
@@ -0,0 +1,58 @@
+/*
+ * 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 java.util.List;
+
+import brooklyn.entity.basic.AbstractApplication;
+import brooklyn.entity.basic.Entities;
+import brooklyn.entity.basic.StartableApplication;
+import brooklyn.entity.nosql.cassandra.CassandraDatacenter;
+import brooklyn.entity.proxying.EntitySpec;
+import brooklyn.launcher.BrooklynLauncher;
+import brooklyn.util.CommandLineUtil;
+
+import com.google.common.collect.Lists;
+
+public class SimpleCassandraCluster extends AbstractApplication {
+
+ private static final String DEFAULT_LOCATION = "localhost";
+
+ @Override
+ public void initApp() {
+ addChild(EntitySpec.create(CassandraDatacenter.class)
+ .configure(CassandraDatacenter.INITIAL_SIZE, 1)
+ .configure(CassandraDatacenter.CLUSTER_NAME, "Brooklyn"));
+ }
+
+ public static void main(String[] argv) {
+ List<String> args = Lists.newArrayList(argv);
+ String port = CommandLineUtil.getCommandLineOption(args, "--port", "8081+");
+ String location = CommandLineUtil.getCommandLineOption(args, "--location", DEFAULT_LOCATION);
+
+ BrooklynLauncher launcher = BrooklynLauncher.newInstance()
+ .application(EntitySpec.create(StartableApplication.class, SimpleCassandraCluster.class)
+ .displayName("Cassandra"))
+ .webconsolePort(port)
+ .location(location)
+ .start();
+
+ Entities.dumpInfo(launcher.getApplications());
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/44d2dc11/examples/simple-nosql-cluster/src/main/java/org/apache/brooklyn/demo/SimpleCouchDBCluster.java
----------------------------------------------------------------------
diff --git a/examples/simple-nosql-cluster/src/main/java/org/apache/brooklyn/demo/SimpleCouchDBCluster.java b/examples/simple-nosql-cluster/src/main/java/org/apache/brooklyn/demo/SimpleCouchDBCluster.java
new file mode 100644
index 0000000..0919c24
--- /dev/null
+++ b/examples/simple-nosql-cluster/src/main/java/org/apache/brooklyn/demo/SimpleCouchDBCluster.java
@@ -0,0 +1,36 @@
+/*
+ * 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 brooklyn.entity.basic.ApplicationBuilder;
+import brooklyn.entity.nosql.couchdb.CouchDBCluster;
+import brooklyn.entity.proxying.EntitySpec;
+
+/** CouchDB cluster. */
+public class SimpleCouchDBCluster extends ApplicationBuilder {
+
+ /** Create entities. */
+ protected void doBuild() {
+ addChild(EntitySpec.create(CouchDBCluster.class)
+ .configure("initialSize", "2")
+ .configure("clusterName", "Brooklyn")
+ .configure("httpPort", "8000+"));
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/44d2dc11/examples/simple-nosql-cluster/src/main/java/org/apache/brooklyn/demo/SimpleMongoDBReplicaSet.java
----------------------------------------------------------------------
diff --git a/examples/simple-nosql-cluster/src/main/java/org/apache/brooklyn/demo/SimpleMongoDBReplicaSet.java b/examples/simple-nosql-cluster/src/main/java/org/apache/brooklyn/demo/SimpleMongoDBReplicaSet.java
new file mode 100644
index 0000000..249431c
--- /dev/null
+++ b/examples/simple-nosql-cluster/src/main/java/org/apache/brooklyn/demo/SimpleMongoDBReplicaSet.java
@@ -0,0 +1,39 @@
+/*
+ * 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 brooklyn.entity.basic.ApplicationBuilder;
+import brooklyn.entity.nosql.mongodb.MongoDBReplicaSet;
+import brooklyn.entity.nosql.mongodb.MongoDBServer;
+import brooklyn.entity.proxying.EntitySpec;
+
+public class SimpleMongoDBReplicaSet extends ApplicationBuilder {
+
+ protected void doBuild() {
+ addChild(EntitySpec.create(MongoDBReplicaSet.class)
+ .configure("name", "Simple MongoDB replica set")
+ .configure("initialSize", 3)
+ .configure("replicaSetName", "simple-replica-set")
+ .configure("memberSpec", EntitySpec.create(MongoDBServer.class)
+ .configure("mongodbConfTemplateUrl", "classpath:///mongodb.conf")
+ .configure("enableRestInterface", true)
+ .configure("port", "27017+")));
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/44d2dc11/examples/simple-nosql-cluster/src/main/java/org/apache/brooklyn/demo/SimpleRedisCluster.java
----------------------------------------------------------------------
diff --git a/examples/simple-nosql-cluster/src/main/java/org/apache/brooklyn/demo/SimpleRedisCluster.java b/examples/simple-nosql-cluster/src/main/java/org/apache/brooklyn/demo/SimpleRedisCluster.java
new file mode 100644
index 0000000..96268c3
--- /dev/null
+++ b/examples/simple-nosql-cluster/src/main/java/org/apache/brooklyn/demo/SimpleRedisCluster.java
@@ -0,0 +1,35 @@
+/*
+ * 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 brooklyn.entity.basic.ApplicationBuilder;
+import brooklyn.entity.nosql.redis.RedisCluster;
+import brooklyn.entity.proxying.EntitySpec;
+
+/** Redis cluster. */
+public class SimpleRedisCluster extends ApplicationBuilder {
+
+ /** Create entities. */
+ protected void doBuild() {
+ addChild(EntitySpec.create(RedisCluster.class)
+ .configure("initialSize", "2")
+ .configure("clusterName", "Brooklyn"));
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/44d2dc11/examples/simple-nosql-cluster/src/main/java/org/apache/brooklyn/demo/StormSampleApp.java
----------------------------------------------------------------------
diff --git a/examples/simple-nosql-cluster/src/main/java/org/apache/brooklyn/demo/StormSampleApp.java b/examples/simple-nosql-cluster/src/main/java/org/apache/brooklyn/demo/StormSampleApp.java
new file mode 100644
index 0000000..37d0ec4
--- /dev/null
+++ b/examples/simple-nosql-cluster/src/main/java/org/apache/brooklyn/demo/StormSampleApp.java
@@ -0,0 +1,70 @@
+/*
+ * 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 java.util.List;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import brooklyn.catalog.Catalog;
+import brooklyn.entity.basic.AbstractApplication;
+import brooklyn.entity.basic.Entities;
+import brooklyn.entity.basic.StartableApplication;
+import brooklyn.entity.messaging.storm.StormDeployment;
+import brooklyn.entity.proxying.EntitySpec;
+import brooklyn.launcher.BrooklynLauncher;
+import brooklyn.util.CommandLineUtil;
+
+import com.google.common.collect.Lists;
+
+/**
+ * Sample showing a storm analyticscluster
+ **/
+@Catalog(name="Storm Sample App",
+description="Creates a Storm analytics cluster",
+ iconUrl="classpath://brooklyn/demo/glossy-3d-blue-web-icon.png")
+public class StormSampleApp extends AbstractApplication implements StartableApplication {
+
+ public static final Logger LOG = LoggerFactory.getLogger(StormSampleApp.class);
+
+ public static final String DEFAULT_LOCATION = "named:gce-europe-west1";
+
+ @Override
+ public void initApp() {
+ addChild(EntitySpec.create(StormDeployment.class)
+ .configure(StormDeployment.SUPERVISORS_COUNT, 2)
+ .configure(StormDeployment.ZOOKEEPERS_COUNT, 1));
+ }
+
+ public static void main(String[] argv) {
+ List<String> args = Lists.newArrayList(argv);
+ String port = CommandLineUtil.getCommandLineOption(args, "--port", "8081+");
+ String location = CommandLineUtil.getCommandLineOption(args, "--location", DEFAULT_LOCATION);
+
+ BrooklynLauncher launcher = BrooklynLauncher.newInstance()
+ .application(EntitySpec.create(StartableApplication.class, StormSampleApp.class)
+ .displayName("Storm App"))
+ .webconsolePort(port)
+ .location(location)
+ .start();
+
+ Entities.dumpInfo(launcher.getApplications());
+ }
+}
[04/12] incubator-brooklyn git commit: Export org.apache.brooklyn.*
in OSGi bundles
Posted by al...@apache.org.
Export org.apache.brooklyn.* in OSGi bundles
In preparation for renaming the base package to org.apache.brooklyn.
Project: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/commit/0d7c48c2
Tree: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/tree/0d7c48c2
Diff: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/diff/0d7c48c2
Branch: refs/heads/master
Commit: 0d7c48c2d6346d2330d4ff3dd9c987cabd0cd657
Parents: 726bebc
Author: Ciprian Ciubotariu <ch...@gmx.net>
Authored: Tue Jul 14 18:32:40 2015 +0300
Committer: Ciprian Ciubotariu <ch...@gmx.net>
Committed: Wed Jul 15 16:56:03 2015 +0300
----------------------------------------------------------------------
parent/pom.xml | 2 +-
usage/downstream-parent/pom.xml | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/0d7c48c2/parent/pom.xml
----------------------------------------------------------------------
diff --git a/parent/pom.xml b/parent/pom.xml
index ee23f9d..c0080d3 100644
--- a/parent/pom.xml
+++ b/parent/pom.xml
@@ -1375,7 +1375,7 @@
In time we should minimize our export lists to
what is really needed.
-->
- <Export-Package>brooklyn.*</Export-Package>
+ <Export-Package>brooklyn.*,org.apache.brooklyn.*</Export-Package>
<Implementation-SHA-1>${buildNumber}</Implementation-SHA-1>
<Implementation-Branch>${scmBranch}</Implementation-Branch>
</instructions>
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/0d7c48c2/usage/downstream-parent/pom.xml
----------------------------------------------------------------------
diff --git a/usage/downstream-parent/pom.xml b/usage/downstream-parent/pom.xml
index 8d544fc..2dea7ce 100644
--- a/usage/downstream-parent/pom.xml
+++ b/usage/downstream-parent/pom.xml
@@ -454,7 +454,7 @@
In time we should minimize our export lists to
what is really needed.
-->
- <Export-Package>brooklyn.*</Export-Package>
+ <Export-Package>brooklyn.*,org.apache.brooklyn.*</Export-Package>
<!-- Brooklyn-Feature prefix triggers inclusion of the project's metadata in the server's features list. -->
<Brooklyn-Feature-Name>${project.name}</Brooklyn-Feature-Name>
</instructions>
[06/12] incubator-brooklyn git commit:
brooklyn-example-global-web-fabric: add org.apache package prefix
Posted by al...@apache.org.
brooklyn-example-global-web-fabric: add org.apache package prefix
Project: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/commit/59cc05d5
Tree: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/tree/59cc05d5
Diff: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/diff/59cc05d5
Branch: refs/heads/master
Commit: 59cc05d598bc803e0b922a09753b4a22bfad91bf
Parents: f2792fa
Author: Ciprian Ciubotariu <ch...@gmx.net>
Authored: Wed Jul 15 17:55:45 2015 +0300
Committer: Ciprian Ciubotariu <ch...@gmx.net>
Committed: Wed Jul 15 18:47:01 2015 +0300
----------------------------------------------------------------------
.../brooklyn/demo/GlobalWebFabricExample.java | 119 -------------------
.../src/main/java/brooklyn/demo/ReadMe.java | 28 -----
.../brooklyn/demo/GlobalWebFabricExample.java | 119 +++++++++++++++++++
.../java/org/apache/brooklyn/demo/ReadMe.java | 28 +++++
4 files changed, 147 insertions(+), 147 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/59cc05d5/examples/global-web-fabric/src/main/java/brooklyn/demo/GlobalWebFabricExample.java
----------------------------------------------------------------------
diff --git a/examples/global-web-fabric/src/main/java/brooklyn/demo/GlobalWebFabricExample.java b/examples/global-web-fabric/src/main/java/brooklyn/demo/GlobalWebFabricExample.java
deleted file mode 100644
index cf4fa24..0000000
--- a/examples/global-web-fabric/src/main/java/brooklyn/demo/GlobalWebFabricExample.java
+++ /dev/null
@@ -1,119 +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.demo;
-
-import static com.google.common.base.Preconditions.checkNotNull;
-
-import java.util.Arrays;
-import java.util.List;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import brooklyn.catalog.Catalog;
-import brooklyn.catalog.CatalogConfig;
-import brooklyn.config.ConfigKey;
-import brooklyn.config.StringConfigMap;
-import brooklyn.entity.basic.AbstractApplication;
-import brooklyn.entity.basic.ConfigKeys;
-import brooklyn.entity.basic.Entities;
-import brooklyn.entity.basic.StartableApplication;
-import brooklyn.entity.dns.geoscaling.GeoscalingDnsService;
-import brooklyn.entity.group.DynamicRegionsFabric;
-import brooklyn.entity.proxy.AbstractController;
-import brooklyn.entity.proxying.EntitySpec;
-import brooklyn.entity.webapp.ElasticJavaWebAppService;
-import brooklyn.entity.webapp.JavaWebAppService;
-import brooklyn.event.basic.PortAttributeSensorAndConfigKey;
-import brooklyn.launcher.BrooklynLauncher;
-import brooklyn.location.basic.PortRanges;
-import brooklyn.util.BrooklynMavenArtifacts;
-import brooklyn.util.CommandLineUtil;
-import brooklyn.util.ResourceUtils;
-
-import com.google.common.base.Joiner;
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.Lists;
-
-@Catalog(name="Global Web Fabric",
-description="Deploys a WAR to multiple clusters, showing how Brooklyn fabrics work",
-iconUrl="classpath://brooklyn/demo/glossy-3d-blue-web-icon.png")
-public class GlobalWebFabricExample extends AbstractApplication {
-
- public static final Logger log = LoggerFactory.getLogger(GlobalWebFabricExample.class);
-
- static final List<String> DEFAULT_LOCATIONS = ImmutableList.of(
- "aws-ec2:eu-west-1",
- "aws-ec2:ap-southeast-1",
- "aws-ec2:us-west-1" );
-
- public static final String DEFAULT_WAR_PATH = ResourceUtils.create(GlobalWebFabricExample.class)
- // take this war, from the classpath, or via maven if not on the classpath
- .firstAvailableUrl(
- "classpath://hello-world-webapp.war",
- BrooklynMavenArtifacts.localUrl("example", "brooklyn-example-hello-world-webapp", "war"))
- .or("classpath://hello-world-webapp.war");
-
- @CatalogConfig(label="WAR (URL)", priority=2)
- public static final ConfigKey<String> WAR_PATH = ConfigKeys.newConfigKey(
- "app.war", "URL to the application archive which should be deployed",
- DEFAULT_WAR_PATH);
-
- // load-balancer instances must run on some port to work with GeoDNS, port 80 to work without special, so make that default
- // (but included here in case it runs on a different port on all machines, or use a range to work with multiple localhosts)
- @CatalogConfig(label="Proxy server HTTP port")
- public static final PortAttributeSensorAndConfigKey PROXY_HTTP_PORT =
- new PortAttributeSensorAndConfigKey(AbstractController.PROXY_HTTP_PORT, PortRanges.fromInteger(80));
-
- @Override
- public void initApp() {
- StringConfigMap config = getManagementContext().getConfig();
-
- GeoscalingDnsService geoDns = addChild(EntitySpec.create(GeoscalingDnsService.class)
- .displayName("GeoScaling DNS")
- .configure("username", checkNotNull(config.getFirst("brooklyn.geoscaling.username"), "username"))
- .configure("password", checkNotNull(config.getFirst("brooklyn.geoscaling.password"), "password"))
- .configure("primaryDomainName", checkNotNull(config.getFirst("brooklyn.geoscaling.primaryDomain"), "primaryDomain"))
- .configure("smartSubdomainName", "brooklyn"));
-
- DynamicRegionsFabric webFabric = addChild(EntitySpec.create(DynamicRegionsFabric.class)
- .displayName("Web Fabric")
- .configure(DynamicRegionsFabric.FACTORY, new ElasticJavaWebAppService.Factory())
-
- //specify the WAR file to use
- .configure(JavaWebAppService.ROOT_WAR, Entities.getRequiredUrlConfig(this, WAR_PATH)) );
-
- //tell GeoDNS what to monitor
- geoDns.setTargetEntityProvider(webFabric);
- }
-
- public static void main(String[] argv) {
- List<String> args = Lists.newArrayList(argv);
- String port = CommandLineUtil.getCommandLineOption(args, "--port", "8081+");
- String locations = CommandLineUtil.getCommandLineOption(args, "--locations", Joiner.on(",").join(DEFAULT_LOCATIONS));
-
- BrooklynLauncher launcher = BrooklynLauncher.newInstance()
- .application(EntitySpec.create(StartableApplication.class, GlobalWebFabricExample.class).displayName("Brooklyn Global Web Fabric Example"))
- .webconsolePort(port)
- .locations(Arrays.asList(locations))
- .start();
-
- Entities.dumpInfo(launcher.getApplications());
- }
-}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/59cc05d5/examples/global-web-fabric/src/main/java/brooklyn/demo/ReadMe.java
----------------------------------------------------------------------
diff --git a/examples/global-web-fabric/src/main/java/brooklyn/demo/ReadMe.java b/examples/global-web-fabric/src/main/java/brooklyn/demo/ReadMe.java
deleted file mode 100644
index f5d6b74..0000000
--- a/examples/global-web-fabric/src/main/java/brooklyn/demo/ReadMe.java
+++ /dev/null
@@ -1,28 +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.demo;
-
-public class ReadMe {
-
-/* This class exists only so that javadoc is generated and artifacts can be staged at sonatype for deployment to maven central.
- * See: https://docs.sonatype.org/display/Repository/Sonatype+OSS+Maven+Repository+Usage+Guide
- *
- * (The actual examples are in other classes in this package / project.) */
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/59cc05d5/examples/global-web-fabric/src/main/java/org/apache/brooklyn/demo/GlobalWebFabricExample.java
----------------------------------------------------------------------
diff --git a/examples/global-web-fabric/src/main/java/org/apache/brooklyn/demo/GlobalWebFabricExample.java b/examples/global-web-fabric/src/main/java/org/apache/brooklyn/demo/GlobalWebFabricExample.java
new file mode 100644
index 0000000..9f7a83a
--- /dev/null
+++ b/examples/global-web-fabric/src/main/java/org/apache/brooklyn/demo/GlobalWebFabricExample.java
@@ -0,0 +1,119 @@
+/*
+ * 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 static com.google.common.base.Preconditions.checkNotNull;
+
+import java.util.Arrays;
+import java.util.List;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import brooklyn.catalog.Catalog;
+import brooklyn.catalog.CatalogConfig;
+import brooklyn.config.ConfigKey;
+import brooklyn.config.StringConfigMap;
+import brooklyn.entity.basic.AbstractApplication;
+import brooklyn.entity.basic.ConfigKeys;
+import brooklyn.entity.basic.Entities;
+import brooklyn.entity.basic.StartableApplication;
+import brooklyn.entity.dns.geoscaling.GeoscalingDnsService;
+import brooklyn.entity.group.DynamicRegionsFabric;
+import brooklyn.entity.proxy.AbstractController;
+import brooklyn.entity.proxying.EntitySpec;
+import brooklyn.entity.webapp.ElasticJavaWebAppService;
+import brooklyn.entity.webapp.JavaWebAppService;
+import brooklyn.event.basic.PortAttributeSensorAndConfigKey;
+import brooklyn.launcher.BrooklynLauncher;
+import brooklyn.location.basic.PortRanges;
+import brooklyn.util.BrooklynMavenArtifacts;
+import brooklyn.util.CommandLineUtil;
+import brooklyn.util.ResourceUtils;
+
+import com.google.common.base.Joiner;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.Lists;
+
+@Catalog(name="Global Web Fabric",
+description="Deploys a WAR to multiple clusters, showing how Brooklyn fabrics work",
+iconUrl="classpath://brooklyn/demo/glossy-3d-blue-web-icon.png")
+public class GlobalWebFabricExample extends AbstractApplication {
+
+ public static final Logger log = LoggerFactory.getLogger(GlobalWebFabricExample.class);
+
+ static final List<String> DEFAULT_LOCATIONS = ImmutableList.of(
+ "aws-ec2:eu-west-1",
+ "aws-ec2:ap-southeast-1",
+ "aws-ec2:us-west-1" );
+
+ public static final String DEFAULT_WAR_PATH = ResourceUtils.create(GlobalWebFabricExample.class)
+ // take this war, from the classpath, or via maven if not on the classpath
+ .firstAvailableUrl(
+ "classpath://hello-world-webapp.war",
+ BrooklynMavenArtifacts.localUrl("example", "brooklyn-example-hello-world-webapp", "war"))
+ .or("classpath://hello-world-webapp.war");
+
+ @CatalogConfig(label="WAR (URL)", priority=2)
+ public static final ConfigKey<String> WAR_PATH = ConfigKeys.newConfigKey(
+ "app.war", "URL to the application archive which should be deployed",
+ DEFAULT_WAR_PATH);
+
+ // load-balancer instances must run on some port to work with GeoDNS, port 80 to work without special, so make that default
+ // (but included here in case it runs on a different port on all machines, or use a range to work with multiple localhosts)
+ @CatalogConfig(label="Proxy server HTTP port")
+ public static final PortAttributeSensorAndConfigKey PROXY_HTTP_PORT =
+ new PortAttributeSensorAndConfigKey(AbstractController.PROXY_HTTP_PORT, PortRanges.fromInteger(80));
+
+ @Override
+ public void initApp() {
+ StringConfigMap config = getManagementContext().getConfig();
+
+ GeoscalingDnsService geoDns = addChild(EntitySpec.create(GeoscalingDnsService.class)
+ .displayName("GeoScaling DNS")
+ .configure("username", checkNotNull(config.getFirst("brooklyn.geoscaling.username"), "username"))
+ .configure("password", checkNotNull(config.getFirst("brooklyn.geoscaling.password"), "password"))
+ .configure("primaryDomainName", checkNotNull(config.getFirst("brooklyn.geoscaling.primaryDomain"), "primaryDomain"))
+ .configure("smartSubdomainName", "brooklyn"));
+
+ DynamicRegionsFabric webFabric = addChild(EntitySpec.create(DynamicRegionsFabric.class)
+ .displayName("Web Fabric")
+ .configure(DynamicRegionsFabric.FACTORY, new ElasticJavaWebAppService.Factory())
+
+ //specify the WAR file to use
+ .configure(JavaWebAppService.ROOT_WAR, Entities.getRequiredUrlConfig(this, WAR_PATH)) );
+
+ //tell GeoDNS what to monitor
+ geoDns.setTargetEntityProvider(webFabric);
+ }
+
+ public static void main(String[] argv) {
+ List<String> args = Lists.newArrayList(argv);
+ String port = CommandLineUtil.getCommandLineOption(args, "--port", "8081+");
+ String locations = CommandLineUtil.getCommandLineOption(args, "--locations", Joiner.on(",").join(DEFAULT_LOCATIONS));
+
+ BrooklynLauncher launcher = BrooklynLauncher.newInstance()
+ .application(EntitySpec.create(StartableApplication.class, GlobalWebFabricExample.class).displayName("Brooklyn Global Web Fabric Example"))
+ .webconsolePort(port)
+ .locations(Arrays.asList(locations))
+ .start();
+
+ Entities.dumpInfo(launcher.getApplications());
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/59cc05d5/examples/global-web-fabric/src/main/java/org/apache/brooklyn/demo/ReadMe.java
----------------------------------------------------------------------
diff --git a/examples/global-web-fabric/src/main/java/org/apache/brooklyn/demo/ReadMe.java b/examples/global-web-fabric/src/main/java/org/apache/brooklyn/demo/ReadMe.java
new file mode 100644
index 0000000..6858630
--- /dev/null
+++ b/examples/global-web-fabric/src/main/java/org/apache/brooklyn/demo/ReadMe.java
@@ -0,0 +1,28 @@
+/*
+ * 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;
+
+public class ReadMe {
+
+/* This class exists only so that javadoc is generated and artifacts can be staged at sonatype for deployment to maven central.
+ * See: https://docs.sonatype.org/display/Repository/Sonatype+OSS+Maven+Repository+Usage+Guide
+ *
+ * (The actual examples are in other classes in this package / project.) */
+
+}
[12/12] incubator-brooklyn git commit: This closes #748
Posted by al...@apache.org.
This closes #748
Project: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/commit/12625d82
Tree: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/tree/12625d82
Diff: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/diff/12625d82
Branch: refs/heads/master
Commit: 12625d82c09fae3334cbc5c4105031fb875d7760
Parents: 726bebc 9b8bde0
Author: Aled Sage <al...@gmail.com>
Authored: Thu Jul 16 00:09:28 2015 +0100
Committer: Aled Sage <al...@gmail.com>
Committed: Thu Jul 16 00:09:28 2015 +0100
----------------------------------------------------------------------
.../brooklyn/demo/GlobalWebFabricExample.java | 119 -------
.../src/main/java/brooklyn/demo/ReadMe.java | 28 --
.../brooklyn/demo/GlobalWebFabricExample.java | 119 +++++++
.../java/org/apache/brooklyn/demo/ReadMe.java | 28 ++
.../java/brooklyn/demo/KafkaClusterExample.java | 58 ----
.../src/main/java/brooklyn/demo/Publish.java | 71 ----
.../demo/StandaloneQpidBrokerExample.java | 73 ----
.../src/main/java/brooklyn/demo/Subscribe.java | 76 -----
.../brooklyn/demo/KafkaClusterExample.java | 58 ++++
.../java/org/apache/brooklyn/demo/Publish.java | 71 ++++
.../demo/StandaloneQpidBrokerExample.java | 73 ++++
.../org/apache/brooklyn/demo/Subscribe.java | 76 +++++
.../brooklyn/demo/CumulusRDFApplication.java | 240 --------------
.../demo/HighAvailabilityCassandraCluster.java | 89 -----
.../java/brooklyn/demo/ResilientMongoDbApp.java | 106 ------
.../java/brooklyn/demo/RiakClusterExample.java | 76 -----
.../brooklyn/demo/SimpleCassandraCluster.java | 58 ----
.../brooklyn/demo/SimpleCouchDBCluster.java | 36 --
.../brooklyn/demo/SimpleMongoDBReplicaSet.java | 39 ---
.../java/brooklyn/demo/SimpleRedisCluster.java | 35 --
.../main/java/brooklyn/demo/StormSampleApp.java | 70 ----
.../brooklyn/demo/WideAreaCassandraCluster.java | 86 -----
.../brooklyn/demo/CumulusRDFApplication.java | 240 ++++++++++++++
.../demo/HighAvailabilityCassandraCluster.java | 89 +++++
.../brooklyn/demo/ResilientMongoDbApp.java | 106 ++++++
.../brooklyn/demo/RiakClusterExample.java | 76 +++++
.../brooklyn/demo/SimpleCassandraCluster.java | 58 ++++
.../brooklyn/demo/SimpleCouchDBCluster.java | 36 ++
.../brooklyn/demo/SimpleMongoDBReplicaSet.java | 39 +++
.../brooklyn/demo/SimpleRedisCluster.java | 35 ++
.../apache/brooklyn/demo/StormSampleApp.java | 70 ++++
.../brooklyn/demo/WideAreaCassandraCluster.java | 86 +++++
.../brooklyn/demo/ha-cassandra-cluster.yaml | 45 ---
.../brooklyn/demo/simple-cassandra-cluster.yaml | 28 --
.../demo/wide-area-cassandra-cluster.yaml | 41 ---
.../brooklyn/demo/ha-cassandra-cluster.yaml | 45 +++
.../brooklyn/demo/simple-cassandra-cluster.yaml | 28 ++
.../demo/wide-area-cassandra-cluster.yaml | 41 +++
.../src/main/assembly/scripts/start.sh | 2 +-
.../brooklyn/demo/NodeJsTodoApplication.java | 59 ----
.../brooklyn/demo/SingleWebServerExample.java | 67 ----
.../demo/WebClusterDatabaseExample.java | 123 -------
.../demo/WebClusterDatabaseExampleApp.java | 175 ----------
.../demo/WebClusterDatabaseExampleGroovy.groovy | 93 ------
.../java/brooklyn/demo/WebClusterExample.java | 96 ------
.../brooklyn/demo/NodeJsTodoApplication.java | 59 ++++
.../brooklyn/demo/SingleWebServerExample.java | 67 ++++
.../demo/WebClusterDatabaseExample.java | 123 +++++++
.../demo/WebClusterDatabaseExampleApp.java | 175 ++++++++++
.../demo/WebClusterDatabaseExampleGroovy.groovy | 93 ++++++
.../apache/brooklyn/demo/WebClusterExample.java | 96 ++++++
.../brooklyn/demo/glossy-3d-blue-web-icon.png | Bin 46490 -> 0 bytes
.../brooklyn/demo/nodejs-riak-todo.yaml | 46 ---
.../resources/brooklyn/demo/nodejs-todo.yaml | 53 ---
.../src/main/resources/logback-custom.xml | 2 +-
.../brooklyn/demo/glossy-3d-blue-web-icon.png | Bin 0 -> 46490 bytes
.../apache/brooklyn/demo/nodejs-riak-todo.yaml | 46 +++
.../org/apache/brooklyn/demo/nodejs-todo.yaml | 53 +++
...lusterDatabaseExampleAppIntegrationTest.java | 205 ------------
...lusterDatabaseExampleAppIntegrationTest.java | 206 ++++++++++++
parent/pom.xml | 2 +-
usage/downstream-parent/pom.xml | 2 +-
.../qa/load/SimulatedJBoss7ServerImpl.java | 240 --------------
.../qa/load/SimulatedMySqlNodeImpl.java | 183 -----------
.../qa/load/SimulatedNginxControllerImpl.java | 196 -----------
.../brooklyn/qa/load/SimulatedTheeTierApp.java | 140 --------
.../java/brooklyn/qa/longevity/Monitor.java | 261 ---------------
.../brooklyn/qa/longevity/MonitorListener.java | 35 --
.../brooklyn/qa/longevity/MonitorPrefs.java | 54 ---
.../brooklyn/qa/longevity/MonitorUtils.java | 329 -------------------
.../brooklyn/qa/longevity/StatusRecorder.java | 130 --------
.../qa/load/SimulatedJBoss7ServerImpl.java | 240 ++++++++++++++
.../qa/load/SimulatedMySqlNodeImpl.java | 183 +++++++++++
.../qa/load/SimulatedNginxControllerImpl.java | 196 +++++++++++
.../brooklyn/qa/load/SimulatedTheeTierApp.java | 140 ++++++++
.../apache/brooklyn/qa/longevity/Monitor.java | 261 +++++++++++++++
.../brooklyn/qa/longevity/MonitorListener.java | 35 ++
.../brooklyn/qa/longevity/MonitorPrefs.java | 54 +++
.../brooklyn/qa/longevity/MonitorUtils.java | 329 +++++++++++++++++++
.../brooklyn/qa/longevity/StatusRecorder.java | 130 ++++++++
usage/qa/src/main/resources/hello-world.war | Bin 14693 -> 15066 bytes
.../test/java/brooklyn/qa/load/LoadTest.java | 243 --------------
.../brooklyn/qa/longevity/MonitorUtilsTest.java | 165 ----------
.../webcluster/SinusoidalLoadGenerator.java | 90 -----
.../qa/longevity/webcluster/WebClusterApp.java | 101 ------
.../org/apache/brooklyn/qa/load/LoadTest.java | 244 ++++++++++++++
.../brooklyn/qa/longevity/MonitorUtilsTest.java | 166 ++++++++++
.../webcluster/SinusoidalLoadGenerator.java | 90 +++++
.../qa/longevity/webcluster/WebClusterApp.java | 101 ++++++
89 files changed, 4465 insertions(+), 4462 deletions(-)
----------------------------------------------------------------------
[07/12] incubator-brooklyn git commit:
brooklyn-example-simple-web-cluster: add org.apache package prefix
Posted by al...@apache.org.
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();
+ }
+}
[11/12] incubator-brooklyn git commit:
brooklyn-example-simple-messaging-pubsub: add org.apache package prefix
Posted by al...@apache.org.
brooklyn-example-simple-messaging-pubsub: add org.apache package prefix
Project: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/commit/f2792fa1
Tree: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/tree/f2792fa1
Diff: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/diff/f2792fa1
Branch: refs/heads/master
Commit: f2792fa18a7bfb58f42938cde6f6bbaed49dacec
Parents: 44d2dc1
Author: Ciprian Ciubotariu <ch...@gmx.net>
Authored: Wed Jul 15 11:11:14 2015 +0300
Committer: Ciprian Ciubotariu <ch...@gmx.net>
Committed: Wed Jul 15 18:47:01 2015 +0300
----------------------------------------------------------------------
.../java/brooklyn/demo/KafkaClusterExample.java | 58 ---------------
.../src/main/java/brooklyn/demo/Publish.java | 71 ------------------
.../demo/StandaloneQpidBrokerExample.java | 73 -------------------
.../src/main/java/brooklyn/demo/Subscribe.java | 76 --------------------
.../brooklyn/demo/KafkaClusterExample.java | 58 +++++++++++++++
.../java/org/apache/brooklyn/demo/Publish.java | 71 ++++++++++++++++++
.../demo/StandaloneQpidBrokerExample.java | 73 +++++++++++++++++++
.../org/apache/brooklyn/demo/Subscribe.java | 76 ++++++++++++++++++++
8 files changed, 278 insertions(+), 278 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/f2792fa1/examples/simple-messaging-pubsub/src/main/java/brooklyn/demo/KafkaClusterExample.java
----------------------------------------------------------------------
diff --git a/examples/simple-messaging-pubsub/src/main/java/brooklyn/demo/KafkaClusterExample.java b/examples/simple-messaging-pubsub/src/main/java/brooklyn/demo/KafkaClusterExample.java
deleted file mode 100644
index ec921c9..0000000
--- a/examples/simple-messaging-pubsub/src/main/java/brooklyn/demo/KafkaClusterExample.java
+++ /dev/null
@@ -1,58 +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.demo;
-
-import java.util.List;
-
-import brooklyn.entity.basic.ApplicationBuilder;
-import brooklyn.entity.basic.Entities;
-import brooklyn.entity.messaging.kafka.KafkaCluster;
-import brooklyn.entity.proxying.EntitySpec;
-import brooklyn.launcher.BrooklynLauncher;
-import brooklyn.util.CommandLineUtil;
-
-import com.google.common.collect.Lists;
-
-/** Kafka Cluster Application */
-public class KafkaClusterExample extends ApplicationBuilder {
-
- public static final String DEFAULT_LOCATION = "localhost";
-
- /** Configure the application. */
- protected void doBuild() {
- addChild(EntitySpec.create(KafkaCluster.class)
- .configure("startTimeout", 300) // 5 minutes
- .configure("initialSize", 2));
- // TODO set application display name?
- }
-
- public static void main(String[] argv) {
- List<String> args = Lists.newArrayList(argv);
- String port = CommandLineUtil.getCommandLineOption(args, "--port", "8081+");
- String location = CommandLineUtil.getCommandLineOption(args, "--location", DEFAULT_LOCATION);
-
- BrooklynLauncher launcher = BrooklynLauncher.newInstance()
- .application(new KafkaClusterExample().appDisplayName("Kafka cluster application"))
- .webconsolePort(port)
- .location(location)
- .start();
-
- Entities.dumpInfo(launcher.getApplications());
- }
-}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/f2792fa1/examples/simple-messaging-pubsub/src/main/java/brooklyn/demo/Publish.java
----------------------------------------------------------------------
diff --git a/examples/simple-messaging-pubsub/src/main/java/brooklyn/demo/Publish.java b/examples/simple-messaging-pubsub/src/main/java/brooklyn/demo/Publish.java
deleted file mode 100644
index 22c0a60..0000000
--- a/examples/simple-messaging-pubsub/src/main/java/brooklyn/demo/Publish.java
+++ /dev/null
@@ -1,71 +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.demo;
-
-import javax.jms.Connection;
-import javax.jms.MessageProducer;
-import javax.jms.Queue;
-import javax.jms.Session;
-import javax.jms.TextMessage;
-
-import org.apache.qpid.client.AMQConnectionFactory;
-import org.apache.qpid.configuration.ClientProperties;
-
-import com.google.common.base.Preconditions;
-import com.google.common.base.Throwables;
-
-/** Publishes messages to a queue on a Qpid broker at a given URL. */
-public class Publish {
- public static final String QUEUE = "'amq.direct'/'testQueue'; { node: { type: queue } }";
-
- public static void main(String...argv) throws Exception {
- Preconditions.checkElementIndex(0, argv.length, "Must specify broker URL");
- String url = argv[0];
-
- // Set Qpid client properties
- System.setProperty(ClientProperties.AMQP_VERSION, "0-10");
- System.setProperty(ClientProperties.DEST_SYNTAX, "ADDR");
-
- // Connect to the broker
- AMQConnectionFactory factory = new AMQConnectionFactory(url);
- Connection connection = factory.createConnection();
- connection.start();
- Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
-
- try {
- // Create a producer for the queue
- Queue destination = session.createQueue(QUEUE);
- MessageProducer messageProducer = session.createProducer(destination);
-
- // Send 100 messages
- for (int n = 0; n < 100; n++) {
- String body = String.format("test message %03d", n+1);
- TextMessage message = session.createTextMessage(body);
- messageProducer.send(message);
- System.out.printf("Sent message %s\n", body);
- }
- } catch (Exception e) {
- System.err.printf("Error while sending - %s\n", e.getMessage());
- System.err.printf("Cause: %s\n", Throwables.getStackTraceAsString(e));
- } finally {
- session.close();
- connection.close();
- }
- }
-}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/f2792fa1/examples/simple-messaging-pubsub/src/main/java/brooklyn/demo/StandaloneQpidBrokerExample.java
----------------------------------------------------------------------
diff --git a/examples/simple-messaging-pubsub/src/main/java/brooklyn/demo/StandaloneQpidBrokerExample.java b/examples/simple-messaging-pubsub/src/main/java/brooklyn/demo/StandaloneQpidBrokerExample.java
deleted file mode 100644
index 89f7874..0000000
--- a/examples/simple-messaging-pubsub/src/main/java/brooklyn/demo/StandaloneQpidBrokerExample.java
+++ /dev/null
@@ -1,73 +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.demo;
-
-import java.util.List;
-
-import brooklyn.entity.basic.AbstractApplication;
-import brooklyn.entity.basic.Entities;
-import brooklyn.entity.basic.StartableApplication;
-import brooklyn.entity.messaging.amqp.AmqpServer;
-import brooklyn.entity.messaging.qpid.QpidBroker;
-import brooklyn.entity.proxying.EntitySpec;
-import brooklyn.launcher.BrooklynLauncher;
-import brooklyn.util.CommandLineUtil;
-
-import com.google.common.collect.ImmutableMap;
-import com.google.common.collect.Lists;
-
-/** Qpid Broker Application */
-public class StandaloneQpidBrokerExample extends AbstractApplication {
-
- public static final String CUSTOM_CONFIG_PATH = "classpath://custom-config.xml";
- public static final String PASSWD_PATH = "classpath://passwd";
- public static final String QPID_BDBSTORE_JAR_PATH = "classpath://qpid-bdbstore-0.20.jar";
- public static final String BDBSTORE_JAR_PATH = "classpath://je-5.0.34.jar";
-
- public static final String DEFAULT_LOCATION = "localhost";
-
- @Override
- public void initApp() {
- // Configure the Qpid broker entity
- QpidBroker broker = addChild(EntitySpec.create(QpidBroker.class)
- .configure("amqpPort", 5672)
- .configure("amqpVersion", AmqpServer.AMQP_0_10)
- .configure("runtimeFiles", ImmutableMap.builder()
- .put(CUSTOM_CONFIG_PATH, QpidBroker.CONFIG_XML)
- .put(PASSWD_PATH, QpidBroker.PASSWD)
- .put(QPID_BDBSTORE_JAR_PATH, "lib/opt/qpid-bdbstore-0.20.jar")
- .put(BDBSTORE_JAR_PATH, "lib/opt/je-5.0.34.jar")
- .build())
- .configure("queue", "testQueue"));
- }
-
- public static void main(String[] argv) {
- List<String> args = Lists.newArrayList(argv);
- String port = CommandLineUtil.getCommandLineOption(args, "--port", "8081+");
- String location = CommandLineUtil.getCommandLineOption(args, "--location", DEFAULT_LOCATION);
-
- BrooklynLauncher launcher = BrooklynLauncher.newInstance()
- .application(EntitySpec.create(StartableApplication.class, StandaloneQpidBrokerExample.class).displayName("Qpid app"))
- .webconsolePort(port)
- .location(location)
- .start();
-
- Entities.dumpInfo(launcher.getApplications());
- }
-}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/f2792fa1/examples/simple-messaging-pubsub/src/main/java/brooklyn/demo/Subscribe.java
----------------------------------------------------------------------
diff --git a/examples/simple-messaging-pubsub/src/main/java/brooklyn/demo/Subscribe.java b/examples/simple-messaging-pubsub/src/main/java/brooklyn/demo/Subscribe.java
deleted file mode 100644
index 7272887..0000000
--- a/examples/simple-messaging-pubsub/src/main/java/brooklyn/demo/Subscribe.java
+++ /dev/null
@@ -1,76 +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.demo;
-
-import javax.jms.Connection;
-import javax.jms.MessageConsumer;
-import javax.jms.Queue;
-import javax.jms.Session;
-import javax.jms.TextMessage;
-
-import org.apache.qpid.client.AMQConnectionFactory;
-import org.apache.qpid.configuration.ClientProperties;
-
-import com.google.common.base.Preconditions;
-import com.google.common.base.Throwables;
-
-/** Receives messages from a queue on a Qpid broker at a given URL. */
-public class Subscribe {
- public static final String QUEUE = "'amq.direct'/'testQueue'; { node: { type: queue } }";
- private static final long MESSAGE_TIMEOUT_MILLIS = 15000L;
- private static final int MESSAGE_COUNT = 100;
-
- public static void main(String...argv) throws Exception {
- Preconditions.checkElementIndex(0, argv.length, "Must specify broker URL");
- String url = argv[0];
-
- // Set Qpid client properties
- System.setProperty(ClientProperties.AMQP_VERSION, "0-10");
- System.setProperty(ClientProperties.DEST_SYNTAX, "ADDR");
-
- // Connect to the broker
- AMQConnectionFactory factory = new AMQConnectionFactory(url);
- Connection connection = factory.createConnection();
- connection.start();
- Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
-
- System.out.printf("Waiting up to %s milliseconds to receive %s messages\n", MESSAGE_TIMEOUT_MILLIS, MESSAGE_COUNT);
- try {
- // Create a producer for the queue
- Queue destination = session.createQueue(QUEUE);
- MessageConsumer messageConsumer = session.createConsumer(destination);
-
- // Try and receive 100 messages
- for (int n = 0; n < MESSAGE_COUNT; n++) {
- TextMessage msg = (TextMessage) messageConsumer.receive(MESSAGE_TIMEOUT_MILLIS);
- if (msg == null) {
- System.out.printf("No message received in %s milliseconds, exiting", MESSAGE_TIMEOUT_MILLIS);
- break;
- }
- System.out.printf("Got message %d: '%s'\n", n+1, msg.getText());
- }
- } catch (Exception e) {
- System.err.printf("Error while receiving - %s\n", e.getMessage());
- System.err.printf("Cause: %s\n", Throwables.getStackTraceAsString(e));
- } finally {
- session.close();
- connection.close();
- }
- }
-}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/f2792fa1/examples/simple-messaging-pubsub/src/main/java/org/apache/brooklyn/demo/KafkaClusterExample.java
----------------------------------------------------------------------
diff --git a/examples/simple-messaging-pubsub/src/main/java/org/apache/brooklyn/demo/KafkaClusterExample.java b/examples/simple-messaging-pubsub/src/main/java/org/apache/brooklyn/demo/KafkaClusterExample.java
new file mode 100644
index 0000000..f0d361e
--- /dev/null
+++ b/examples/simple-messaging-pubsub/src/main/java/org/apache/brooklyn/demo/KafkaClusterExample.java
@@ -0,0 +1,58 @@
+/*
+ * 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 java.util.List;
+
+import brooklyn.entity.basic.ApplicationBuilder;
+import brooklyn.entity.basic.Entities;
+import brooklyn.entity.messaging.kafka.KafkaCluster;
+import brooklyn.entity.proxying.EntitySpec;
+import brooklyn.launcher.BrooklynLauncher;
+import brooklyn.util.CommandLineUtil;
+
+import com.google.common.collect.Lists;
+
+/** Kafka Cluster Application */
+public class KafkaClusterExample extends ApplicationBuilder {
+
+ public static final String DEFAULT_LOCATION = "localhost";
+
+ /** Configure the application. */
+ protected void doBuild() {
+ addChild(EntitySpec.create(KafkaCluster.class)
+ .configure("startTimeout", 300) // 5 minutes
+ .configure("initialSize", 2));
+ // TODO set application display name?
+ }
+
+ public static void main(String[] argv) {
+ List<String> args = Lists.newArrayList(argv);
+ String port = CommandLineUtil.getCommandLineOption(args, "--port", "8081+");
+ String location = CommandLineUtil.getCommandLineOption(args, "--location", DEFAULT_LOCATION);
+
+ BrooklynLauncher launcher = BrooklynLauncher.newInstance()
+ .application(new KafkaClusterExample().appDisplayName("Kafka cluster application"))
+ .webconsolePort(port)
+ .location(location)
+ .start();
+
+ Entities.dumpInfo(launcher.getApplications());
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/f2792fa1/examples/simple-messaging-pubsub/src/main/java/org/apache/brooklyn/demo/Publish.java
----------------------------------------------------------------------
diff --git a/examples/simple-messaging-pubsub/src/main/java/org/apache/brooklyn/demo/Publish.java b/examples/simple-messaging-pubsub/src/main/java/org/apache/brooklyn/demo/Publish.java
new file mode 100644
index 0000000..8a68061
--- /dev/null
+++ b/examples/simple-messaging-pubsub/src/main/java/org/apache/brooklyn/demo/Publish.java
@@ -0,0 +1,71 @@
+/*
+ * 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 javax.jms.Connection;
+import javax.jms.MessageProducer;
+import javax.jms.Queue;
+import javax.jms.Session;
+import javax.jms.TextMessage;
+
+import org.apache.qpid.client.AMQConnectionFactory;
+import org.apache.qpid.configuration.ClientProperties;
+
+import com.google.common.base.Preconditions;
+import com.google.common.base.Throwables;
+
+/** Publishes messages to a queue on a Qpid broker at a given URL. */
+public class Publish {
+ public static final String QUEUE = "'amq.direct'/'testQueue'; { node: { type: queue } }";
+
+ public static void main(String...argv) throws Exception {
+ Preconditions.checkElementIndex(0, argv.length, "Must specify broker URL");
+ String url = argv[0];
+
+ // Set Qpid client properties
+ System.setProperty(ClientProperties.AMQP_VERSION, "0-10");
+ System.setProperty(ClientProperties.DEST_SYNTAX, "ADDR");
+
+ // Connect to the broker
+ AMQConnectionFactory factory = new AMQConnectionFactory(url);
+ Connection connection = factory.createConnection();
+ connection.start();
+ Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
+
+ try {
+ // Create a producer for the queue
+ Queue destination = session.createQueue(QUEUE);
+ MessageProducer messageProducer = session.createProducer(destination);
+
+ // Send 100 messages
+ for (int n = 0; n < 100; n++) {
+ String body = String.format("test message %03d", n+1);
+ TextMessage message = session.createTextMessage(body);
+ messageProducer.send(message);
+ System.out.printf("Sent message %s\n", body);
+ }
+ } catch (Exception e) {
+ System.err.printf("Error while sending - %s\n", e.getMessage());
+ System.err.printf("Cause: %s\n", Throwables.getStackTraceAsString(e));
+ } finally {
+ session.close();
+ connection.close();
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/f2792fa1/examples/simple-messaging-pubsub/src/main/java/org/apache/brooklyn/demo/StandaloneQpidBrokerExample.java
----------------------------------------------------------------------
diff --git a/examples/simple-messaging-pubsub/src/main/java/org/apache/brooklyn/demo/StandaloneQpidBrokerExample.java b/examples/simple-messaging-pubsub/src/main/java/org/apache/brooklyn/demo/StandaloneQpidBrokerExample.java
new file mode 100644
index 0000000..9df7005
--- /dev/null
+++ b/examples/simple-messaging-pubsub/src/main/java/org/apache/brooklyn/demo/StandaloneQpidBrokerExample.java
@@ -0,0 +1,73 @@
+/*
+ * 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 java.util.List;
+
+import brooklyn.entity.basic.AbstractApplication;
+import brooklyn.entity.basic.Entities;
+import brooklyn.entity.basic.StartableApplication;
+import brooklyn.entity.messaging.amqp.AmqpServer;
+import brooklyn.entity.messaging.qpid.QpidBroker;
+import brooklyn.entity.proxying.EntitySpec;
+import brooklyn.launcher.BrooklynLauncher;
+import brooklyn.util.CommandLineUtil;
+
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.Lists;
+
+/** Qpid Broker Application */
+public class StandaloneQpidBrokerExample extends AbstractApplication {
+
+ public static final String CUSTOM_CONFIG_PATH = "classpath://custom-config.xml";
+ public static final String PASSWD_PATH = "classpath://passwd";
+ public static final String QPID_BDBSTORE_JAR_PATH = "classpath://qpid-bdbstore-0.20.jar";
+ public static final String BDBSTORE_JAR_PATH = "classpath://je-5.0.34.jar";
+
+ public static final String DEFAULT_LOCATION = "localhost";
+
+ @Override
+ public void initApp() {
+ // Configure the Qpid broker entity
+ QpidBroker broker = addChild(EntitySpec.create(QpidBroker.class)
+ .configure("amqpPort", 5672)
+ .configure("amqpVersion", AmqpServer.AMQP_0_10)
+ .configure("runtimeFiles", ImmutableMap.builder()
+ .put(CUSTOM_CONFIG_PATH, QpidBroker.CONFIG_XML)
+ .put(PASSWD_PATH, QpidBroker.PASSWD)
+ .put(QPID_BDBSTORE_JAR_PATH, "lib/opt/qpid-bdbstore-0.20.jar")
+ .put(BDBSTORE_JAR_PATH, "lib/opt/je-5.0.34.jar")
+ .build())
+ .configure("queue", "testQueue"));
+ }
+
+ public static void main(String[] argv) {
+ List<String> args = Lists.newArrayList(argv);
+ String port = CommandLineUtil.getCommandLineOption(args, "--port", "8081+");
+ String location = CommandLineUtil.getCommandLineOption(args, "--location", DEFAULT_LOCATION);
+
+ BrooklynLauncher launcher = BrooklynLauncher.newInstance()
+ .application(EntitySpec.create(StartableApplication.class, StandaloneQpidBrokerExample.class).displayName("Qpid app"))
+ .webconsolePort(port)
+ .location(location)
+ .start();
+
+ Entities.dumpInfo(launcher.getApplications());
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/f2792fa1/examples/simple-messaging-pubsub/src/main/java/org/apache/brooklyn/demo/Subscribe.java
----------------------------------------------------------------------
diff --git a/examples/simple-messaging-pubsub/src/main/java/org/apache/brooklyn/demo/Subscribe.java b/examples/simple-messaging-pubsub/src/main/java/org/apache/brooklyn/demo/Subscribe.java
new file mode 100644
index 0000000..b7df104
--- /dev/null
+++ b/examples/simple-messaging-pubsub/src/main/java/org/apache/brooklyn/demo/Subscribe.java
@@ -0,0 +1,76 @@
+/*
+ * 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 javax.jms.Connection;
+import javax.jms.MessageConsumer;
+import javax.jms.Queue;
+import javax.jms.Session;
+import javax.jms.TextMessage;
+
+import org.apache.qpid.client.AMQConnectionFactory;
+import org.apache.qpid.configuration.ClientProperties;
+
+import com.google.common.base.Preconditions;
+import com.google.common.base.Throwables;
+
+/** Receives messages from a queue on a Qpid broker at a given URL. */
+public class Subscribe {
+ public static final String QUEUE = "'amq.direct'/'testQueue'; { node: { type: queue } }";
+ private static final long MESSAGE_TIMEOUT_MILLIS = 15000L;
+ private static final int MESSAGE_COUNT = 100;
+
+ public static void main(String...argv) throws Exception {
+ Preconditions.checkElementIndex(0, argv.length, "Must specify broker URL");
+ String url = argv[0];
+
+ // Set Qpid client properties
+ System.setProperty(ClientProperties.AMQP_VERSION, "0-10");
+ System.setProperty(ClientProperties.DEST_SYNTAX, "ADDR");
+
+ // Connect to the broker
+ AMQConnectionFactory factory = new AMQConnectionFactory(url);
+ Connection connection = factory.createConnection();
+ connection.start();
+ Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
+
+ System.out.printf("Waiting up to %s milliseconds to receive %s messages\n", MESSAGE_TIMEOUT_MILLIS, MESSAGE_COUNT);
+ try {
+ // Create a producer for the queue
+ Queue destination = session.createQueue(QUEUE);
+ MessageConsumer messageConsumer = session.createConsumer(destination);
+
+ // Try and receive 100 messages
+ for (int n = 0; n < MESSAGE_COUNT; n++) {
+ TextMessage msg = (TextMessage) messageConsumer.receive(MESSAGE_TIMEOUT_MILLIS);
+ if (msg == null) {
+ System.out.printf("No message received in %s milliseconds, exiting", MESSAGE_TIMEOUT_MILLIS);
+ break;
+ }
+ System.out.printf("Got message %d: '%s'\n", n+1, msg.getText());
+ }
+ } catch (Exception e) {
+ System.err.printf("Error while receiving - %s\n", e.getMessage());
+ System.err.printf("Cause: %s\n", Throwables.getStackTraceAsString(e));
+ } finally {
+ session.close();
+ connection.close();
+ }
+ }
+}
[08/12] incubator-brooklyn git commit:
brooklyn-example-simple-web-cluster: add org.apache package prefix
Posted by al...@apache.org.
brooklyn-example-simple-web-cluster: add org.apache package prefix
Project: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/commit/9b8bde02
Tree: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/tree/9b8bde02
Diff: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/diff/9b8bde02
Branch: refs/heads/master
Commit: 9b8bde02dc71d8b7183216d041b0dfc81924cbd3
Parents: 59cc05d
Author: Ciprian Ciubotariu <ch...@gmx.net>
Authored: Wed Jul 15 18:11:11 2015 +0300
Committer: Ciprian Ciubotariu <ch...@gmx.net>
Committed: Wed Jul 15 18:47:01 2015 +0300
----------------------------------------------------------------------
.../src/main/assembly/scripts/start.sh | 2 +-
.../brooklyn/demo/NodeJsTodoApplication.java | 59 ------
.../brooklyn/demo/SingleWebServerExample.java | 67 ------
.../demo/WebClusterDatabaseExample.java | 123 -----------
.../demo/WebClusterDatabaseExampleApp.java | 175 ----------------
.../demo/WebClusterDatabaseExampleGroovy.groovy | 93 ---------
.../java/brooklyn/demo/WebClusterExample.java | 96 ---------
.../brooklyn/demo/NodeJsTodoApplication.java | 59 ++++++
.../brooklyn/demo/SingleWebServerExample.java | 67 ++++++
.../demo/WebClusterDatabaseExample.java | 123 +++++++++++
.../demo/WebClusterDatabaseExampleApp.java | 175 ++++++++++++++++
.../demo/WebClusterDatabaseExampleGroovy.groovy | 93 +++++++++
.../apache/brooklyn/demo/WebClusterExample.java | 96 +++++++++
.../brooklyn/demo/glossy-3d-blue-web-icon.png | Bin 46490 -> 0 bytes
.../brooklyn/demo/nodejs-riak-todo.yaml | 46 -----
.../resources/brooklyn/demo/nodejs-todo.yaml | 53 -----
.../src/main/resources/logback-custom.xml | 2 +-
.../brooklyn/demo/glossy-3d-blue-web-icon.png | Bin 0 -> 46490 bytes
.../apache/brooklyn/demo/nodejs-riak-todo.yaml | 46 +++++
.../org/apache/brooklyn/demo/nodejs-todo.yaml | 53 +++++
...lusterDatabaseExampleAppIntegrationTest.java | 205 ------------------
...lusterDatabaseExampleAppIntegrationTest.java | 206 +++++++++++++++++++
22 files changed, 920 insertions(+), 919 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/9b8bde02/examples/simple-web-cluster/src/main/assembly/scripts/start.sh
----------------------------------------------------------------------
diff --git a/examples/simple-web-cluster/src/main/assembly/scripts/start.sh b/examples/simple-web-cluster/src/main/assembly/scripts/start.sh
index a4cf2d4..ec4f110 100755
--- a/examples/simple-web-cluster/src/main/assembly/scripts/start.sh
+++ b/examples/simple-web-cluster/src/main/assembly/scripts/start.sh
@@ -19,7 +19,7 @@
#
if [ -z "$BROOKLYN_APP_CLASS" ] ; then
- BROOKLYN_APP_CLASS=brooklyn.demo.WebClusterDatabaseExample
+ BROOKLYN_APP_CLASS=org.apache.brooklyn.demo.WebClusterDatabaseExample
fi
if [ -z "$JAVA" ] ; then
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/9b8bde02/examples/simple-web-cluster/src/main/java/brooklyn/demo/NodeJsTodoApplication.java
----------------------------------------------------------------------
diff --git a/examples/simple-web-cluster/src/main/java/brooklyn/demo/NodeJsTodoApplication.java b/examples/simple-web-cluster/src/main/java/brooklyn/demo/NodeJsTodoApplication.java
deleted file mode 100644
index 50d5f74..0000000
--- a/examples/simple-web-cluster/src/main/java/brooklyn/demo/NodeJsTodoApplication.java
+++ /dev/null
@@ -1,59 +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.demo;
-
-import static brooklyn.event.basic.DependentConfiguration.attributeWhenReady;
-import brooklyn.catalog.Catalog;
-import brooklyn.entity.basic.AbstractApplication;
-import brooklyn.entity.basic.Attributes;
-import brooklyn.entity.basic.SoftwareProcess;
-import brooklyn.entity.basic.StartableApplication;
-import brooklyn.entity.nosql.redis.RedisStore;
-import brooklyn.entity.proxying.EntitySpec;
-import brooklyn.entity.trait.Startable;
-import brooklyn.entity.webapp.nodejs.NodeJsWebAppService;
-import brooklyn.event.basic.DependentConfiguration;
-
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableMap;
-
-/**
- * Node.JS Todo Application
- */
-@Catalog(name="NodeJS Todo",
- description="Node.js is a cross-platform runtime environment for server-side and networking applications. Node.js applications are written in JavaScript",
- iconUrl="classpath://nodejs-logo.png")
-public class NodeJsTodoApplication extends AbstractApplication implements StartableApplication {
-
- @Override
- public void initApp() {
- RedisStore redis = addChild(EntitySpec.create(RedisStore.class));
-
- addChild(EntitySpec.create(NodeJsWebAppService.class)
- .configure(NodeJsWebAppService.APP_GIT_REPOSITORY_URL, "https://github.com/grkvlt/nodejs-todo/")
- .configure(NodeJsWebAppService.APP_FILE, "server.js")
- .configure(NodeJsWebAppService.APP_NAME, "nodejs-todo")
- .configure(NodeJsWebAppService.NODE_PACKAGE_LIST, ImmutableList.of("express", "ejs", "jasmine-node", "underscore", "method-override", "cookie-parser", "express-session", "body-parser", "cookie-session", "redis", "redis-url", "connect"))
- .configure(SoftwareProcess.SHELL_ENVIRONMENT, ImmutableMap.<String, Object>of(
- "REDISTOGO_URL", DependentConfiguration.formatString("redis://%s:%d/",
- attributeWhenReady(redis, Attributes.HOSTNAME), attributeWhenReady(redis, RedisStore.REDIS_PORT))))
- .configure(SoftwareProcess.LAUNCH_LATCH, attributeWhenReady(redis, Startable.SERVICE_UP)));
- }
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/9b8bde02/examples/simple-web-cluster/src/main/java/brooklyn/demo/SingleWebServerExample.java
----------------------------------------------------------------------
diff --git a/examples/simple-web-cluster/src/main/java/brooklyn/demo/SingleWebServerExample.java b/examples/simple-web-cluster/src/main/java/brooklyn/demo/SingleWebServerExample.java
deleted file mode 100644
index d974e35..0000000
--- a/examples/simple-web-cluster/src/main/java/brooklyn/demo/SingleWebServerExample.java
+++ /dev/null
@@ -1,67 +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.demo;
-
-import java.util.List;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import brooklyn.entity.basic.AbstractApplication;
-import brooklyn.entity.basic.Attributes;
-import brooklyn.entity.basic.Entities;
-import brooklyn.entity.basic.StartableApplication;
-import brooklyn.entity.proxying.EntitySpec;
-import brooklyn.entity.webapp.JavaWebAppService;
-import brooklyn.entity.webapp.jboss.JBoss7Server;
-import brooklyn.launcher.BrooklynLauncher;
-import brooklyn.location.basic.PortRanges;
-import brooklyn.util.CommandLineUtil;
-
-import com.google.common.collect.Lists;
-
-/** This example starts one web app on 8080, waits for a keypress, then stops it. */
-public class SingleWebServerExample extends AbstractApplication {
-
- public static final Logger LOG = LoggerFactory.getLogger(SingleWebServerExample.class);
-
- private static final String WAR_PATH = "classpath://hello-world-webapp.war";
-
- @Override
- public void initApp() {
- addChild(EntitySpec.create(JBoss7Server.class)
- .configure(JavaWebAppService.ROOT_WAR, WAR_PATH)
- .configure(Attributes.HTTP_PORT, PortRanges.fromString("8080+")));
- }
-
- // Shows how to use ApplicationBuilder without sub-classing, but for CLI usage one should sub-class
- public static void main(String[] argv) throws Exception {
- List<String> args = Lists.newArrayList(argv);
- String port = CommandLineUtil.getCommandLineOption(args, "--port", "8081+");
- String location = CommandLineUtil.getCommandLineOption(args, "--location", "localhost");
-
- BrooklynLauncher launcher = BrooklynLauncher.newInstance()
- .application(EntitySpec.create(StartableApplication.class, SingleWebServerExample.class).displayName("Brooklyn WebApp example"))
- .webconsolePort(port)
- .location(location)
- .start();
-
- Entities.dumpInfo(launcher.getApplications());
- }
-}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/9b8bde02/examples/simple-web-cluster/src/main/java/brooklyn/demo/WebClusterDatabaseExample.java
----------------------------------------------------------------------
diff --git a/examples/simple-web-cluster/src/main/java/brooklyn/demo/WebClusterDatabaseExample.java b/examples/simple-web-cluster/src/main/java/brooklyn/demo/WebClusterDatabaseExample.java
deleted file mode 100644
index fd7c9ae..0000000
--- a/examples/simple-web-cluster/src/main/java/brooklyn/demo/WebClusterDatabaseExample.java
+++ /dev/null
@@ -1,123 +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.demo;
-
-import static brooklyn.entity.java.JavaEntityMethods.javaSysProp;
-import static brooklyn.event.basic.DependentConfiguration.attributeWhenReady;
-import static brooklyn.event.basic.DependentConfiguration.formatString;
-
-import java.util.List;
-import java.util.concurrent.TimeUnit;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import brooklyn.enricher.Enrichers;
-import brooklyn.enricher.HttpLatencyDetector;
-import brooklyn.entity.basic.AbstractApplication;
-import brooklyn.entity.basic.Entities;
-import brooklyn.entity.basic.StartableApplication;
-import brooklyn.entity.database.mysql.MySqlNode;
-import brooklyn.entity.proxying.EntitySpec;
-import brooklyn.entity.webapp.ControlledDynamicWebAppCluster;
-import brooklyn.entity.webapp.DynamicWebAppCluster;
-import brooklyn.entity.webapp.JavaWebAppService;
-import brooklyn.entity.webapp.WebAppService;
-import brooklyn.entity.webapp.WebAppServiceConstants;
-import brooklyn.event.AttributeSensor;
-import brooklyn.event.basic.Sensors;
-import brooklyn.launcher.BrooklynLauncher;
-import brooklyn.location.basic.PortRanges;
-import brooklyn.policy.autoscaling.AutoScalerPolicy;
-import brooklyn.util.CommandLineUtil;
-
-import com.google.common.collect.ImmutableMap;
-import com.google.common.collect.Lists;
-
-/**
- * Launches a 3-tier app with nginx, clustered jboss, and mysql.
- **/
-public class WebClusterDatabaseExample extends AbstractApplication {
-
- public static final Logger LOG = LoggerFactory.getLogger(WebClusterDatabaseExample.class);
-
- public static final String WAR_PATH = "classpath://hello-world-sql-webapp.war";
-
- public static final String DB_SETUP_SQL_URL = "classpath://visitors-creation-script.sql";
-
- public static final String DB_TABLE = "visitors";
- public static final String DB_USERNAME = "brooklyn";
- public static final String DB_PASSWORD = "br00k11n";
-
- public static final AttributeSensor<Integer> APPSERVERS_COUNT = Sensors.newIntegerSensor(
- "appservers.count", "Number of app servers deployed");
-
- @Override
- public void initApp() {
- MySqlNode mysql = addChild(EntitySpec.create(MySqlNode.class)
- .configure("creationScriptUrl", DB_SETUP_SQL_URL));
-
- ControlledDynamicWebAppCluster web = addChild(EntitySpec.create(ControlledDynamicWebAppCluster.class)
- .configure(WebAppService.HTTP_PORT, PortRanges.fromString("8080+"))
- .configure(JavaWebAppService.ROOT_WAR, WAR_PATH)
- .configure(javaSysProp("brooklyn.example.db.url"),
- formatString("jdbc:%s%s?user=%s\\&password=%s",
- attributeWhenReady(mysql, MySqlNode.DATASTORE_URL),
- DB_TABLE, DB_USERNAME, DB_PASSWORD)) );
-
- web.addEnricher(HttpLatencyDetector.builder().
- url(ControlledDynamicWebAppCluster.ROOT_URL).
- rollup(10, TimeUnit.SECONDS).
- build());
-
- // simple scaling policy
- web.getCluster().addPolicy(AutoScalerPolicy.builder().
- metric(DynamicWebAppCluster.REQUESTS_PER_SECOND_IN_WINDOW_PER_NODE).
- metricRange(10, 100).
- sizeRange(1, 5).
- build());
-
- // expose some KPI's
- addEnricher(Enrichers.builder()
- .propagating(WebAppServiceConstants.ROOT_URL,
- DynamicWebAppCluster.REQUESTS_PER_SECOND_IN_WINDOW,
- HttpLatencyDetector.REQUEST_LATENCY_IN_SECONDS_IN_WINDOW)
- .from(web)
- .build());
-
- addEnricher(Enrichers.builder()
- .propagating(ImmutableMap.of(DynamicWebAppCluster.GROUP_SIZE, APPSERVERS_COUNT))
- .from(web)
- .build());
- }
-
- public static void main(String[] argv) {
- List<String> args = Lists.newArrayList(argv);
- String port = CommandLineUtil.getCommandLineOption(args, "--port", "8081+");
- String location = CommandLineUtil.getCommandLineOption(args, "--location", "localhost");
-
- BrooklynLauncher launcher = BrooklynLauncher.newInstance()
- .application(EntitySpec.create(StartableApplication.class, WebClusterDatabaseExample.class).displayName("Brooklyn WebApp Cluster with Database example"))
- .webconsolePort(port)
- .location(location)
- .start();
-
- Entities.dumpInfo(launcher.getApplications());
- }
-}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/9b8bde02/examples/simple-web-cluster/src/main/java/brooklyn/demo/WebClusterDatabaseExampleApp.java
----------------------------------------------------------------------
diff --git a/examples/simple-web-cluster/src/main/java/brooklyn/demo/WebClusterDatabaseExampleApp.java b/examples/simple-web-cluster/src/main/java/brooklyn/demo/WebClusterDatabaseExampleApp.java
deleted file mode 100644
index 44efa0c..0000000
--- a/examples/simple-web-cluster/src/main/java/brooklyn/demo/WebClusterDatabaseExampleApp.java
+++ /dev/null
@@ -1,175 +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.demo;
-
-import static brooklyn.event.basic.DependentConfiguration.attributeWhenReady;
-import static brooklyn.event.basic.DependentConfiguration.formatString;
-
-import java.util.List;
-import java.util.concurrent.TimeUnit;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import brooklyn.catalog.Catalog;
-import brooklyn.catalog.CatalogConfig;
-import brooklyn.config.ConfigKey;
-import brooklyn.enricher.Enrichers;
-import brooklyn.enricher.HttpLatencyDetector;
-import brooklyn.entity.basic.AbstractApplication;
-import brooklyn.entity.basic.ConfigKeys;
-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.proxying.EntitySpec;
-import brooklyn.entity.webapp.ControlledDynamicWebAppCluster;
-import brooklyn.entity.webapp.DynamicWebAppCluster;
-import brooklyn.entity.webapp.JavaWebAppService;
-import brooklyn.entity.webapp.WebAppService;
-import brooklyn.entity.webapp.WebAppServiceConstants;
-import brooklyn.event.AttributeSensor;
-import brooklyn.event.basic.Sensors;
-import brooklyn.launcher.BrooklynLauncher;
-import brooklyn.location.basic.PortRanges;
-import brooklyn.policy.autoscaling.AutoScalerPolicy;
-import brooklyn.util.BrooklynMavenArtifacts;
-import brooklyn.util.CommandLineUtil;
-import brooklyn.util.ResourceUtils;
-
-import com.google.common.collect.ImmutableMap;
-import com.google.common.collect.ImmutableSet;
-import com.google.common.collect.Lists;
-
-/**
- * Launches a 3-tier app with nginx, clustered jboss, and mysql.
- * <p>
- * Includes some advanced features such as KPI / derived sensors,
- * and annotations for use in a catalog.
- * <p>
- * This variant also increases minimum size to 2.
- * Note the policy min size must have the same value,
- * otherwise it fights with cluster set up trying to reduce the cluster size!
- **/
-@Catalog(name="Elastic Java Web + DB",
- description="Deploys a WAR to a load-balanced elastic Java AppServer cluster, " +
- "with an auto-scaling policy, " +
- "wired to a database initialized with the provided SQL; " +
- "defaults to a 'Hello World' chatroom app.",
- iconUrl="classpath://brooklyn/demo/glossy-3d-blue-web-icon.png")
-public class WebClusterDatabaseExampleApp extends AbstractApplication implements StartableApplication {
-
- public static final Logger LOG = LoggerFactory.getLogger(WebClusterDatabaseExampleApp.class);
-
- public static final String DEFAULT_LOCATION = "localhost";
-
- public static final String DEFAULT_WAR_PATH = ResourceUtils.create(WebClusterDatabaseExampleApp.class)
- // take this war, from the classpath, or via maven if not on the classpath
- .firstAvailableUrl(
- "classpath://hello-world-sql-webapp.war",
- BrooklynMavenArtifacts.localUrl("example", "brooklyn-example-hello-world-sql-webapp", "war"))
- .or("classpath://hello-world-sql-webapp.war");
-
- @CatalogConfig(label="WAR (URL)", priority=2)
- public static final ConfigKey<String> WAR_PATH = ConfigKeys.newConfigKey(
- "app.war", "URL to the application archive which should be deployed",
- DEFAULT_WAR_PATH);
-
- // TODO to expose in catalog we need to let the keystore url be specified (not hard)
- // and also confirm that this works for nginx (might be a bit fiddly);
- // booleans in the gui are working (With checkbox)
- @CatalogConfig(label="HTTPS")
- public static final ConfigKey<Boolean> USE_HTTPS = ConfigKeys.newConfigKey(
- "app.https", "Whether the application should use HTTPS only or just HTTP only (default)", false);
-
- public static final String DEFAULT_DB_SETUP_SQL_URL = "classpath://visitors-creation-script.sql";
-
- @CatalogConfig(label="DB Setup SQL (URL)", priority=1)
- public static final ConfigKey<String> DB_SETUP_SQL_URL = ConfigKeys.newConfigKey(
- "app.db_sql", "URL to the SQL script to set up the database",
- DEFAULT_DB_SETUP_SQL_URL);
-
- public static final String DB_TABLE = "visitors";
- public static final String DB_USERNAME = "brooklyn";
- public static final String DB_PASSWORD = "br00k11n";
-
- public static final AttributeSensor<Integer> APPSERVERS_COUNT = Sensors.newIntegerSensor(
- "appservers.count", "Number of app servers deployed");
- public static final AttributeSensor<Double> REQUESTS_PER_SECOND_IN_WINDOW =
- WebAppServiceConstants.REQUESTS_PER_SECOND_IN_WINDOW;
- public static final AttributeSensor<String> ROOT_URL = WebAppServiceConstants.ROOT_URL;
-
- @Override
- public void initApp() {
- MySqlNode mysql = addChild(
- EntitySpec.create(MySqlNode.class)
- .configure(MySqlNode.CREATION_SCRIPT_URL, Entities.getRequiredUrlConfig(this, DB_SETUP_SQL_URL)));
-
- ControlledDynamicWebAppCluster web = addChild(
- EntitySpec.create(ControlledDynamicWebAppCluster.class)
- .configure(WebAppService.HTTP_PORT, PortRanges.fromString("8080+"))
- // to specify a diferrent appserver:
-// .configure(ControlledDynamicWebAppCluster.MEMBER_SPEC, EntitySpec.create(TomcatServer.class))
- .configure(JavaWebAppService.ROOT_WAR, Entities.getRequiredUrlConfig(this, WAR_PATH))
- .configure(JavaEntityMethods.javaSysProp("brooklyn.example.db.url"),
- formatString("jdbc:%s%s?user=%s\\&password=%s",
- attributeWhenReady(mysql, MySqlNode.DATASTORE_URL), DB_TABLE, DB_USERNAME, DB_PASSWORD))
- .configure(DynamicCluster.INITIAL_SIZE, 2)
- .configure(WebAppService.ENABLED_PROTOCOLS, ImmutableSet.of(getConfig(USE_HTTPS) ? "https" : "http")) );
-
- web.addEnricher(HttpLatencyDetector.builder().
- url(ROOT_URL).
- rollup(10, TimeUnit.SECONDS).
- build());
-
- web.getCluster().addPolicy(AutoScalerPolicy.builder().
- metric(DynamicWebAppCluster.REQUESTS_PER_SECOND_IN_WINDOW_PER_NODE).
- metricRange(10, 100).
- sizeRange(2, 5).
- build());
-
- addEnricher(Enrichers.builder()
- .propagating(WebAppServiceConstants.ROOT_URL,
- DynamicWebAppCluster.REQUESTS_PER_SECOND_IN_WINDOW,
- HttpLatencyDetector.REQUEST_LATENCY_IN_SECONDS_IN_WINDOW)
- .from(web)
- .build());
-
- addEnricher(Enrichers.builder()
- .propagating(ImmutableMap.of(DynamicWebAppCluster.GROUP_SIZE, APPSERVERS_COUNT))
- .from(web)
- .build());
- }
-
- public static void main(String[] argv) {
- List<String> args = Lists.newArrayList(argv);
- String port = CommandLineUtil.getCommandLineOption(args, "--port", "8081+");
- String location = CommandLineUtil.getCommandLineOption(args, "--location", DEFAULT_LOCATION);
-
- BrooklynLauncher launcher = BrooklynLauncher.newInstance()
- .application(EntitySpec.create(StartableApplication.class, WebClusterDatabaseExampleApp.class)
- .displayName("Brooklyn WebApp Cluster with Database example"))
- .webconsolePort(port)
- .location(location)
- .start();
-
- Entities.dumpInfo(launcher.getApplications());
- }
-}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/9b8bde02/examples/simple-web-cluster/src/main/java/brooklyn/demo/WebClusterDatabaseExampleGroovy.groovy
----------------------------------------------------------------------
diff --git a/examples/simple-web-cluster/src/main/java/brooklyn/demo/WebClusterDatabaseExampleGroovy.groovy b/examples/simple-web-cluster/src/main/java/brooklyn/demo/WebClusterDatabaseExampleGroovy.groovy
deleted file mode 100644
index c3f6cc7..0000000
--- a/examples/simple-web-cluster/src/main/java/brooklyn/demo/WebClusterDatabaseExampleGroovy.groovy
+++ /dev/null
@@ -1,93 +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.demo;
-
-import static brooklyn.entity.java.JavaEntityMethods.javaSysProp
-import static brooklyn.event.basic.DependentConfiguration.attributeWhenReady
-import static brooklyn.event.basic.DependentConfiguration.formatString
-
-import org.slf4j.Logger
-import org.slf4j.LoggerFactory
-
-import brooklyn.entity.basic.AbstractApplication
-import brooklyn.entity.basic.Entities
-import brooklyn.entity.database.mysql.MySqlNode
-import brooklyn.entity.proxying.EntitySpec
-import brooklyn.entity.webapp.ControlledDynamicWebAppCluster
-import brooklyn.entity.webapp.DynamicWebAppCluster
-import brooklyn.launcher.BrooklynLauncher
-import brooklyn.policy.autoscaling.AutoScalerPolicy
-import brooklyn.util.CommandLineUtil
-
-import com.google.common.collect.Lists
-
-/**
- * Launches a 3-tier app with nginx, clustered jboss, and mysql.
- * <p>
- * This variant of {@link WebClusterDatabaseExample} demonstrates <i>Groovy</i> language conveniences.
- **/
-public class WebClusterDatabaseExampleGroovy extends AbstractApplication {
-
- public static final Logger LOG = LoggerFactory.getLogger(WebClusterDatabaseExampleGroovy.class);
-
- public static final String DEFAULT_LOCATION = "localhost";
-
- public static final String WAR_PATH = "classpath://hello-world-sql-webapp.war";
-
- public static final String DB_SETUP_SQL_URL = "classpath://visitors-creation-script.sql";
-
- public static final String DB_TABLE = "visitors";
- public static final String DB_USERNAME = "brooklyn";
- public static final String DB_PASSWORD = "br00k11n";
-
- @Override
- public void initApp() {
- MySqlNode mysql = addChild(MySqlNode,
- creationScriptUrl: DB_SETUP_SQL_URL);
-
- ControlledDynamicWebAppCluster web = addChild(ControlledDynamicWebAppCluster,
- war: WAR_PATH,
- httpPort: "8080+",
- (javaSysProp("brooklyn.example.db.url")):
- formatString("jdbc:%s%s?user=%s\\&password=%s",
- attributeWhenReady(mysql, MySqlNode.DATASTORE_URL),
- DB_TABLE, DB_USERNAME, DB_PASSWORD));
-
- web.getCluster().addPolicy(AutoScalerPolicy.builder().
- metric(DynamicWebAppCluster.REQUESTS_PER_SECOND_LAST_PER_NODE).
- sizeRange(1, 5).
- metricRange(10, 100).
- build());
- }
-
- public static void main(String[] argv) {
- List<String> args = Lists.newArrayList(argv);
- String port = CommandLineUtil.getCommandLineOption(args, "--port", "8081+");
- String location = CommandLineUtil.getCommandLineOption(args, "--location", DEFAULT_LOCATION);
-
- BrooklynLauncher launcher = BrooklynLauncher.newInstance()
- .application(EntitySpec.create(WebClusterDatabaseExampleGroovy.class).displayName("Brooklyn WebApp Cluster with Database example"))
- .webconsolePort(port)
- .location(location)
- .start();
-
- Entities.dumpInfo(launcher.getApplications());
- }
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/9b8bde02/examples/simple-web-cluster/src/main/java/brooklyn/demo/WebClusterExample.java
----------------------------------------------------------------------
diff --git a/examples/simple-web-cluster/src/main/java/brooklyn/demo/WebClusterExample.java b/examples/simple-web-cluster/src/main/java/brooklyn/demo/WebClusterExample.java
deleted file mode 100644
index 6a5d064..0000000
--- a/examples/simple-web-cluster/src/main/java/brooklyn/demo/WebClusterExample.java
+++ /dev/null
@@ -1,96 +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.demo;
-
-import java.util.List;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import brooklyn.config.BrooklynProperties;
-import brooklyn.entity.basic.AbstractApplication;
-import brooklyn.entity.basic.Entities;
-import brooklyn.entity.proxy.nginx.NginxController;
-import brooklyn.entity.proxying.EntitySpec;
-import brooklyn.entity.webapp.ControlledDynamicWebAppCluster;
-import brooklyn.entity.webapp.DynamicWebAppCluster;
-import brooklyn.entity.webapp.jboss.JBoss7Server;
-import brooklyn.launcher.BrooklynLauncher;
-import brooklyn.policy.autoscaling.AutoScalerPolicy;
-import brooklyn.util.CommandLineUtil;
-
-import com.google.common.collect.Lists;
-
-/**
- * Launches a clustered and load-balanced set of web servers.
- * Demonstrates syntax, so many of the options used here are the defaults.
- * (So the class could be much simpler, as in WebClusterExampleAlt.)
- * <p>
- * Requires:
- * -Xmx512m -Xms128m -XX:MaxPermSize=256m
- * and brooklyn-all jar, and this jar or classes dir, on classpath.
- **/
-public class WebClusterExample extends AbstractApplication {
- public static final Logger LOG = LoggerFactory.getLogger(WebClusterExample.class);
-
- static BrooklynProperties config = BrooklynProperties.Factory.newDefault();
-
- public static final String DEFAULT_LOCATION = "localhost";
-
- public static final String WAR_PATH = "classpath://hello-world-webapp.war";
-
- private NginxController nginxController;
- private ControlledDynamicWebAppCluster web;
-
- @Override
- public void initApp() {
- nginxController = addChild(EntitySpec.create(NginxController.class)
- //.configure("domain", "webclusterexample.brooklyn.local")
- .configure("port", "8000+"));
-
- web = addChild(EntitySpec.create(ControlledDynamicWebAppCluster.class)
- .displayName("WebApp cluster")
- .configure(ControlledDynamicWebAppCluster.CONTROLLER, nginxController)
- .configure(ControlledDynamicWebAppCluster.INITIAL_SIZE, 1)
- .configure(ControlledDynamicWebAppCluster.MEMBER_SPEC, EntitySpec.create(JBoss7Server.class)
- .configure("httpPort", "8080+")
- .configure("war", WAR_PATH)));
-
- web.getCluster().addPolicy(AutoScalerPolicy.builder()
- .metric(DynamicWebAppCluster.REQUESTS_PER_SECOND_IN_WINDOW_PER_NODE)
- .sizeRange(1, 5)
- .metricRange(10, 100)
- .build());
- }
-
- public static void main(String[] argv) {
- List<String> args = Lists.newArrayList(argv);
- String port = CommandLineUtil.getCommandLineOption(args, "--port", "8081+");
- String location = CommandLineUtil.getCommandLineOption(args, "--location", DEFAULT_LOCATION);
-
- // TODO Want to parse, to handle multiple locations
- BrooklynLauncher launcher = BrooklynLauncher.newInstance()
- .application(EntitySpec.create(WebClusterExample.class).displayName("Brooklyn WebApp Cluster example"))
- .webconsolePort(port)
- .location(location)
- .start();
-
- Entities.dumpInfo(launcher.getApplications());
- }
-}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/9b8bde02/examples/simple-web-cluster/src/main/java/org/apache/brooklyn/demo/NodeJsTodoApplication.java
----------------------------------------------------------------------
diff --git a/examples/simple-web-cluster/src/main/java/org/apache/brooklyn/demo/NodeJsTodoApplication.java b/examples/simple-web-cluster/src/main/java/org/apache/brooklyn/demo/NodeJsTodoApplication.java
new file mode 100644
index 0000000..bfae7ce
--- /dev/null
+++ b/examples/simple-web-cluster/src/main/java/org/apache/brooklyn/demo/NodeJsTodoApplication.java
@@ -0,0 +1,59 @@
+/*
+ * 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 static brooklyn.event.basic.DependentConfiguration.attributeWhenReady;
+import brooklyn.catalog.Catalog;
+import brooklyn.entity.basic.AbstractApplication;
+import brooklyn.entity.basic.Attributes;
+import brooklyn.entity.basic.SoftwareProcess;
+import brooklyn.entity.basic.StartableApplication;
+import brooklyn.entity.nosql.redis.RedisStore;
+import brooklyn.entity.proxying.EntitySpec;
+import brooklyn.entity.trait.Startable;
+import brooklyn.entity.webapp.nodejs.NodeJsWebAppService;
+import brooklyn.event.basic.DependentConfiguration;
+
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
+
+/**
+ * Node.JS Todo Application
+ */
+@Catalog(name="NodeJS Todo",
+ description="Node.js is a cross-platform runtime environment for server-side and networking applications. Node.js applications are written in JavaScript",
+ iconUrl="classpath://nodejs-logo.png")
+public class NodeJsTodoApplication extends AbstractApplication implements StartableApplication {
+
+ @Override
+ public void initApp() {
+ RedisStore redis = addChild(EntitySpec.create(RedisStore.class));
+
+ addChild(EntitySpec.create(NodeJsWebAppService.class)
+ .configure(NodeJsWebAppService.APP_GIT_REPOSITORY_URL, "https://github.com/grkvlt/nodejs-todo/")
+ .configure(NodeJsWebAppService.APP_FILE, "server.js")
+ .configure(NodeJsWebAppService.APP_NAME, "nodejs-todo")
+ .configure(NodeJsWebAppService.NODE_PACKAGE_LIST, ImmutableList.of("express", "ejs", "jasmine-node", "underscore", "method-override", "cookie-parser", "express-session", "body-parser", "cookie-session", "redis", "redis-url", "connect"))
+ .configure(SoftwareProcess.SHELL_ENVIRONMENT, ImmutableMap.<String, Object>of(
+ "REDISTOGO_URL", DependentConfiguration.formatString("redis://%s:%d/",
+ attributeWhenReady(redis, Attributes.HOSTNAME), attributeWhenReady(redis, RedisStore.REDIS_PORT))))
+ .configure(SoftwareProcess.LAUNCH_LATCH, attributeWhenReady(redis, Startable.SERVICE_UP)));
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/9b8bde02/examples/simple-web-cluster/src/main/java/org/apache/brooklyn/demo/SingleWebServerExample.java
----------------------------------------------------------------------
diff --git a/examples/simple-web-cluster/src/main/java/org/apache/brooklyn/demo/SingleWebServerExample.java b/examples/simple-web-cluster/src/main/java/org/apache/brooklyn/demo/SingleWebServerExample.java
new file mode 100644
index 0000000..4561e2c
--- /dev/null
+++ b/examples/simple-web-cluster/src/main/java/org/apache/brooklyn/demo/SingleWebServerExample.java
@@ -0,0 +1,67 @@
+/*
+ * 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 java.util.List;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import brooklyn.entity.basic.AbstractApplication;
+import brooklyn.entity.basic.Attributes;
+import brooklyn.entity.basic.Entities;
+import brooklyn.entity.basic.StartableApplication;
+import brooklyn.entity.proxying.EntitySpec;
+import brooklyn.entity.webapp.JavaWebAppService;
+import brooklyn.entity.webapp.jboss.JBoss7Server;
+import brooklyn.launcher.BrooklynLauncher;
+import brooklyn.location.basic.PortRanges;
+import brooklyn.util.CommandLineUtil;
+
+import com.google.common.collect.Lists;
+
+/** This example starts one web app on 8080, waits for a keypress, then stops it. */
+public class SingleWebServerExample extends AbstractApplication {
+
+ public static final Logger LOG = LoggerFactory.getLogger(SingleWebServerExample.class);
+
+ private static final String WAR_PATH = "classpath://hello-world-webapp.war";
+
+ @Override
+ public void initApp() {
+ addChild(EntitySpec.create(JBoss7Server.class)
+ .configure(JavaWebAppService.ROOT_WAR, WAR_PATH)
+ .configure(Attributes.HTTP_PORT, PortRanges.fromString("8080+")));
+ }
+
+ // Shows how to use ApplicationBuilder without sub-classing, but for CLI usage one should sub-class
+ public static void main(String[] argv) throws Exception {
+ List<String> args = Lists.newArrayList(argv);
+ String port = CommandLineUtil.getCommandLineOption(args, "--port", "8081+");
+ String location = CommandLineUtil.getCommandLineOption(args, "--location", "localhost");
+
+ BrooklynLauncher launcher = BrooklynLauncher.newInstance()
+ .application(EntitySpec.create(StartableApplication.class, SingleWebServerExample.class).displayName("Brooklyn WebApp example"))
+ .webconsolePort(port)
+ .location(location)
+ .start();
+
+ Entities.dumpInfo(launcher.getApplications());
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/9b8bde02/examples/simple-web-cluster/src/main/java/org/apache/brooklyn/demo/WebClusterDatabaseExample.java
----------------------------------------------------------------------
diff --git a/examples/simple-web-cluster/src/main/java/org/apache/brooklyn/demo/WebClusterDatabaseExample.java b/examples/simple-web-cluster/src/main/java/org/apache/brooklyn/demo/WebClusterDatabaseExample.java
new file mode 100644
index 0000000..4f10eb1
--- /dev/null
+++ b/examples/simple-web-cluster/src/main/java/org/apache/brooklyn/demo/WebClusterDatabaseExample.java
@@ -0,0 +1,123 @@
+/*
+ * 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 static brooklyn.entity.java.JavaEntityMethods.javaSysProp;
+import static brooklyn.event.basic.DependentConfiguration.attributeWhenReady;
+import static brooklyn.event.basic.DependentConfiguration.formatString;
+
+import java.util.List;
+import java.util.concurrent.TimeUnit;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import brooklyn.enricher.Enrichers;
+import brooklyn.enricher.HttpLatencyDetector;
+import brooklyn.entity.basic.AbstractApplication;
+import brooklyn.entity.basic.Entities;
+import brooklyn.entity.basic.StartableApplication;
+import brooklyn.entity.database.mysql.MySqlNode;
+import brooklyn.entity.proxying.EntitySpec;
+import brooklyn.entity.webapp.ControlledDynamicWebAppCluster;
+import brooklyn.entity.webapp.DynamicWebAppCluster;
+import brooklyn.entity.webapp.JavaWebAppService;
+import brooklyn.entity.webapp.WebAppService;
+import brooklyn.entity.webapp.WebAppServiceConstants;
+import brooklyn.event.AttributeSensor;
+import brooklyn.event.basic.Sensors;
+import brooklyn.launcher.BrooklynLauncher;
+import brooklyn.location.basic.PortRanges;
+import brooklyn.policy.autoscaling.AutoScalerPolicy;
+import brooklyn.util.CommandLineUtil;
+
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.Lists;
+
+/**
+ * Launches a 3-tier app with nginx, clustered jboss, and mysql.
+ **/
+public class WebClusterDatabaseExample extends AbstractApplication {
+
+ public static final Logger LOG = LoggerFactory.getLogger(WebClusterDatabaseExample.class);
+
+ public static final String WAR_PATH = "classpath://hello-world-sql-webapp.war";
+
+ public static final String DB_SETUP_SQL_URL = "classpath://visitors-creation-script.sql";
+
+ public static final String DB_TABLE = "visitors";
+ public static final String DB_USERNAME = "brooklyn";
+ public static final String DB_PASSWORD = "br00k11n";
+
+ public static final AttributeSensor<Integer> APPSERVERS_COUNT = Sensors.newIntegerSensor(
+ "appservers.count", "Number of app servers deployed");
+
+ @Override
+ public void initApp() {
+ MySqlNode mysql = addChild(EntitySpec.create(MySqlNode.class)
+ .configure("creationScriptUrl", DB_SETUP_SQL_URL));
+
+ ControlledDynamicWebAppCluster web = addChild(EntitySpec.create(ControlledDynamicWebAppCluster.class)
+ .configure(WebAppService.HTTP_PORT, PortRanges.fromString("8080+"))
+ .configure(JavaWebAppService.ROOT_WAR, WAR_PATH)
+ .configure(javaSysProp("brooklyn.example.db.url"),
+ formatString("jdbc:%s%s?user=%s\\&password=%s",
+ attributeWhenReady(mysql, MySqlNode.DATASTORE_URL),
+ DB_TABLE, DB_USERNAME, DB_PASSWORD)) );
+
+ web.addEnricher(HttpLatencyDetector.builder().
+ url(ControlledDynamicWebAppCluster.ROOT_URL).
+ rollup(10, TimeUnit.SECONDS).
+ build());
+
+ // simple scaling policy
+ web.getCluster().addPolicy(AutoScalerPolicy.builder().
+ metric(DynamicWebAppCluster.REQUESTS_PER_SECOND_IN_WINDOW_PER_NODE).
+ metricRange(10, 100).
+ sizeRange(1, 5).
+ build());
+
+ // expose some KPI's
+ addEnricher(Enrichers.builder()
+ .propagating(WebAppServiceConstants.ROOT_URL,
+ DynamicWebAppCluster.REQUESTS_PER_SECOND_IN_WINDOW,
+ HttpLatencyDetector.REQUEST_LATENCY_IN_SECONDS_IN_WINDOW)
+ .from(web)
+ .build());
+
+ addEnricher(Enrichers.builder()
+ .propagating(ImmutableMap.of(DynamicWebAppCluster.GROUP_SIZE, APPSERVERS_COUNT))
+ .from(web)
+ .build());
+ }
+
+ public static void main(String[] argv) {
+ List<String> args = Lists.newArrayList(argv);
+ String port = CommandLineUtil.getCommandLineOption(args, "--port", "8081+");
+ String location = CommandLineUtil.getCommandLineOption(args, "--location", "localhost");
+
+ BrooklynLauncher launcher = BrooklynLauncher.newInstance()
+ .application(EntitySpec.create(StartableApplication.class, WebClusterDatabaseExample.class).displayName("Brooklyn WebApp Cluster with Database example"))
+ .webconsolePort(port)
+ .location(location)
+ .start();
+
+ Entities.dumpInfo(launcher.getApplications());
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/9b8bde02/examples/simple-web-cluster/src/main/java/org/apache/brooklyn/demo/WebClusterDatabaseExampleApp.java
----------------------------------------------------------------------
diff --git a/examples/simple-web-cluster/src/main/java/org/apache/brooklyn/demo/WebClusterDatabaseExampleApp.java b/examples/simple-web-cluster/src/main/java/org/apache/brooklyn/demo/WebClusterDatabaseExampleApp.java
new file mode 100644
index 0000000..3a5d54d
--- /dev/null
+++ b/examples/simple-web-cluster/src/main/java/org/apache/brooklyn/demo/WebClusterDatabaseExampleApp.java
@@ -0,0 +1,175 @@
+/*
+ * 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 static brooklyn.event.basic.DependentConfiguration.attributeWhenReady;
+import static brooklyn.event.basic.DependentConfiguration.formatString;
+
+import java.util.List;
+import java.util.concurrent.TimeUnit;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import brooklyn.catalog.Catalog;
+import brooklyn.catalog.CatalogConfig;
+import brooklyn.config.ConfigKey;
+import brooklyn.enricher.Enrichers;
+import brooklyn.enricher.HttpLatencyDetector;
+import brooklyn.entity.basic.AbstractApplication;
+import brooklyn.entity.basic.ConfigKeys;
+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.proxying.EntitySpec;
+import brooklyn.entity.webapp.ControlledDynamicWebAppCluster;
+import brooklyn.entity.webapp.DynamicWebAppCluster;
+import brooklyn.entity.webapp.JavaWebAppService;
+import brooklyn.entity.webapp.WebAppService;
+import brooklyn.entity.webapp.WebAppServiceConstants;
+import brooklyn.event.AttributeSensor;
+import brooklyn.event.basic.Sensors;
+import brooklyn.launcher.BrooklynLauncher;
+import brooklyn.location.basic.PortRanges;
+import brooklyn.policy.autoscaling.AutoScalerPolicy;
+import brooklyn.util.BrooklynMavenArtifacts;
+import brooklyn.util.CommandLineUtil;
+import brooklyn.util.ResourceUtils;
+
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Lists;
+
+/**
+ * Launches a 3-tier app with nginx, clustered jboss, and mysql.
+ * <p>
+ * Includes some advanced features such as KPI / derived sensors,
+ * and annotations for use in a catalog.
+ * <p>
+ * This variant also increases minimum size to 2.
+ * Note the policy min size must have the same value,
+ * otherwise it fights with cluster set up trying to reduce the cluster size!
+ **/
+@Catalog(name="Elastic Java Web + DB",
+ description="Deploys a WAR to a load-balanced elastic Java AppServer cluster, " +
+ "with an auto-scaling policy, " +
+ "wired to a database initialized with the provided SQL; " +
+ "defaults to a 'Hello World' chatroom app.",
+ iconUrl="classpath://brooklyn/demo/glossy-3d-blue-web-icon.png")
+public class WebClusterDatabaseExampleApp extends AbstractApplication implements StartableApplication {
+
+ public static final Logger LOG = LoggerFactory.getLogger(WebClusterDatabaseExampleApp.class);
+
+ public static final String DEFAULT_LOCATION = "localhost";
+
+ public static final String DEFAULT_WAR_PATH = ResourceUtils.create(WebClusterDatabaseExampleApp.class)
+ // take this war, from the classpath, or via maven if not on the classpath
+ .firstAvailableUrl(
+ "classpath://hello-world-sql-webapp.war",
+ BrooklynMavenArtifacts.localUrl("example", "brooklyn-example-hello-world-sql-webapp", "war"))
+ .or("classpath://hello-world-sql-webapp.war");
+
+ @CatalogConfig(label="WAR (URL)", priority=2)
+ public static final ConfigKey<String> WAR_PATH = ConfigKeys.newConfigKey(
+ "app.war", "URL to the application archive which should be deployed",
+ DEFAULT_WAR_PATH);
+
+ // TODO to expose in catalog we need to let the keystore url be specified (not hard)
+ // and also confirm that this works for nginx (might be a bit fiddly);
+ // booleans in the gui are working (With checkbox)
+ @CatalogConfig(label="HTTPS")
+ public static final ConfigKey<Boolean> USE_HTTPS = ConfigKeys.newConfigKey(
+ "app.https", "Whether the application should use HTTPS only or just HTTP only (default)", false);
+
+ public static final String DEFAULT_DB_SETUP_SQL_URL = "classpath://visitors-creation-script.sql";
+
+ @CatalogConfig(label="DB Setup SQL (URL)", priority=1)
+ public static final ConfigKey<String> DB_SETUP_SQL_URL = ConfigKeys.newConfigKey(
+ "app.db_sql", "URL to the SQL script to set up the database",
+ DEFAULT_DB_SETUP_SQL_URL);
+
+ public static final String DB_TABLE = "visitors";
+ public static final String DB_USERNAME = "brooklyn";
+ public static final String DB_PASSWORD = "br00k11n";
+
+ public static final AttributeSensor<Integer> APPSERVERS_COUNT = Sensors.newIntegerSensor(
+ "appservers.count", "Number of app servers deployed");
+ public static final AttributeSensor<Double> REQUESTS_PER_SECOND_IN_WINDOW =
+ WebAppServiceConstants.REQUESTS_PER_SECOND_IN_WINDOW;
+ public static final AttributeSensor<String> ROOT_URL = WebAppServiceConstants.ROOT_URL;
+
+ @Override
+ public void initApp() {
+ MySqlNode mysql = addChild(
+ EntitySpec.create(MySqlNode.class)
+ .configure(MySqlNode.CREATION_SCRIPT_URL, Entities.getRequiredUrlConfig(this, DB_SETUP_SQL_URL)));
+
+ ControlledDynamicWebAppCluster web = addChild(
+ EntitySpec.create(ControlledDynamicWebAppCluster.class)
+ .configure(WebAppService.HTTP_PORT, PortRanges.fromString("8080+"))
+ // to specify a diferrent appserver:
+// .configure(ControlledDynamicWebAppCluster.MEMBER_SPEC, EntitySpec.create(TomcatServer.class))
+ .configure(JavaWebAppService.ROOT_WAR, Entities.getRequiredUrlConfig(this, WAR_PATH))
+ .configure(JavaEntityMethods.javaSysProp("brooklyn.example.db.url"),
+ formatString("jdbc:%s%s?user=%s\\&password=%s",
+ attributeWhenReady(mysql, MySqlNode.DATASTORE_URL), DB_TABLE, DB_USERNAME, DB_PASSWORD))
+ .configure(DynamicCluster.INITIAL_SIZE, 2)
+ .configure(WebAppService.ENABLED_PROTOCOLS, ImmutableSet.of(getConfig(USE_HTTPS) ? "https" : "http")) );
+
+ web.addEnricher(HttpLatencyDetector.builder().
+ url(ROOT_URL).
+ rollup(10, TimeUnit.SECONDS).
+ build());
+
+ web.getCluster().addPolicy(AutoScalerPolicy.builder().
+ metric(DynamicWebAppCluster.REQUESTS_PER_SECOND_IN_WINDOW_PER_NODE).
+ metricRange(10, 100).
+ sizeRange(2, 5).
+ build());
+
+ addEnricher(Enrichers.builder()
+ .propagating(WebAppServiceConstants.ROOT_URL,
+ DynamicWebAppCluster.REQUESTS_PER_SECOND_IN_WINDOW,
+ HttpLatencyDetector.REQUEST_LATENCY_IN_SECONDS_IN_WINDOW)
+ .from(web)
+ .build());
+
+ addEnricher(Enrichers.builder()
+ .propagating(ImmutableMap.of(DynamicWebAppCluster.GROUP_SIZE, APPSERVERS_COUNT))
+ .from(web)
+ .build());
+ }
+
+ public static void main(String[] argv) {
+ List<String> args = Lists.newArrayList(argv);
+ String port = CommandLineUtil.getCommandLineOption(args, "--port", "8081+");
+ String location = CommandLineUtil.getCommandLineOption(args, "--location", DEFAULT_LOCATION);
+
+ BrooklynLauncher launcher = BrooklynLauncher.newInstance()
+ .application(EntitySpec.create(StartableApplication.class, WebClusterDatabaseExampleApp.class)
+ .displayName("Brooklyn WebApp Cluster with Database example"))
+ .webconsolePort(port)
+ .location(location)
+ .start();
+
+ Entities.dumpInfo(launcher.getApplications());
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/9b8bde02/examples/simple-web-cluster/src/main/java/org/apache/brooklyn/demo/WebClusterDatabaseExampleGroovy.groovy
----------------------------------------------------------------------
diff --git a/examples/simple-web-cluster/src/main/java/org/apache/brooklyn/demo/WebClusterDatabaseExampleGroovy.groovy b/examples/simple-web-cluster/src/main/java/org/apache/brooklyn/demo/WebClusterDatabaseExampleGroovy.groovy
new file mode 100644
index 0000000..c3f6cc7
--- /dev/null
+++ b/examples/simple-web-cluster/src/main/java/org/apache/brooklyn/demo/WebClusterDatabaseExampleGroovy.groovy
@@ -0,0 +1,93 @@
+/*
+ * 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.demo;
+
+import static brooklyn.entity.java.JavaEntityMethods.javaSysProp
+import static brooklyn.event.basic.DependentConfiguration.attributeWhenReady
+import static brooklyn.event.basic.DependentConfiguration.formatString
+
+import org.slf4j.Logger
+import org.slf4j.LoggerFactory
+
+import brooklyn.entity.basic.AbstractApplication
+import brooklyn.entity.basic.Entities
+import brooklyn.entity.database.mysql.MySqlNode
+import brooklyn.entity.proxying.EntitySpec
+import brooklyn.entity.webapp.ControlledDynamicWebAppCluster
+import brooklyn.entity.webapp.DynamicWebAppCluster
+import brooklyn.launcher.BrooklynLauncher
+import brooklyn.policy.autoscaling.AutoScalerPolicy
+import brooklyn.util.CommandLineUtil
+
+import com.google.common.collect.Lists
+
+/**
+ * Launches a 3-tier app with nginx, clustered jboss, and mysql.
+ * <p>
+ * This variant of {@link WebClusterDatabaseExample} demonstrates <i>Groovy</i> language conveniences.
+ **/
+public class WebClusterDatabaseExampleGroovy extends AbstractApplication {
+
+ public static final Logger LOG = LoggerFactory.getLogger(WebClusterDatabaseExampleGroovy.class);
+
+ public static final String DEFAULT_LOCATION = "localhost";
+
+ public static final String WAR_PATH = "classpath://hello-world-sql-webapp.war";
+
+ public static final String DB_SETUP_SQL_URL = "classpath://visitors-creation-script.sql";
+
+ public static final String DB_TABLE = "visitors";
+ public static final String DB_USERNAME = "brooklyn";
+ public static final String DB_PASSWORD = "br00k11n";
+
+ @Override
+ public void initApp() {
+ MySqlNode mysql = addChild(MySqlNode,
+ creationScriptUrl: DB_SETUP_SQL_URL);
+
+ ControlledDynamicWebAppCluster web = addChild(ControlledDynamicWebAppCluster,
+ war: WAR_PATH,
+ httpPort: "8080+",
+ (javaSysProp("brooklyn.example.db.url")):
+ formatString("jdbc:%s%s?user=%s\\&password=%s",
+ attributeWhenReady(mysql, MySqlNode.DATASTORE_URL),
+ DB_TABLE, DB_USERNAME, DB_PASSWORD));
+
+ web.getCluster().addPolicy(AutoScalerPolicy.builder().
+ metric(DynamicWebAppCluster.REQUESTS_PER_SECOND_LAST_PER_NODE).
+ sizeRange(1, 5).
+ metricRange(10, 100).
+ build());
+ }
+
+ public static void main(String[] argv) {
+ List<String> args = Lists.newArrayList(argv);
+ String port = CommandLineUtil.getCommandLineOption(args, "--port", "8081+");
+ String location = CommandLineUtil.getCommandLineOption(args, "--location", DEFAULT_LOCATION);
+
+ BrooklynLauncher launcher = BrooklynLauncher.newInstance()
+ .application(EntitySpec.create(WebClusterDatabaseExampleGroovy.class).displayName("Brooklyn WebApp Cluster with Database example"))
+ .webconsolePort(port)
+ .location(location)
+ .start();
+
+ Entities.dumpInfo(launcher.getApplications());
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/9b8bde02/examples/simple-web-cluster/src/main/java/org/apache/brooklyn/demo/WebClusterExample.java
----------------------------------------------------------------------
diff --git a/examples/simple-web-cluster/src/main/java/org/apache/brooklyn/demo/WebClusterExample.java b/examples/simple-web-cluster/src/main/java/org/apache/brooklyn/demo/WebClusterExample.java
new file mode 100644
index 0000000..51642aa
--- /dev/null
+++ b/examples/simple-web-cluster/src/main/java/org/apache/brooklyn/demo/WebClusterExample.java
@@ -0,0 +1,96 @@
+/*
+ * 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 java.util.List;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import brooklyn.config.BrooklynProperties;
+import brooklyn.entity.basic.AbstractApplication;
+import brooklyn.entity.basic.Entities;
+import brooklyn.entity.proxy.nginx.NginxController;
+import brooklyn.entity.proxying.EntitySpec;
+import brooklyn.entity.webapp.ControlledDynamicWebAppCluster;
+import brooklyn.entity.webapp.DynamicWebAppCluster;
+import brooklyn.entity.webapp.jboss.JBoss7Server;
+import brooklyn.launcher.BrooklynLauncher;
+import brooklyn.policy.autoscaling.AutoScalerPolicy;
+import brooklyn.util.CommandLineUtil;
+
+import com.google.common.collect.Lists;
+
+/**
+ * Launches a clustered and load-balanced set of web servers.
+ * Demonstrates syntax, so many of the options used here are the defaults.
+ * (So the class could be much simpler, as in WebClusterExampleAlt.)
+ * <p>
+ * Requires:
+ * -Xmx512m -Xms128m -XX:MaxPermSize=256m
+ * and brooklyn-all jar, and this jar or classes dir, on classpath.
+ **/
+public class WebClusterExample extends AbstractApplication {
+ public static final Logger LOG = LoggerFactory.getLogger(WebClusterExample.class);
+
+ static BrooklynProperties config = BrooklynProperties.Factory.newDefault();
+
+ public static final String DEFAULT_LOCATION = "localhost";
+
+ public static final String WAR_PATH = "classpath://hello-world-webapp.war";
+
+ private NginxController nginxController;
+ private ControlledDynamicWebAppCluster web;
+
+ @Override
+ public void initApp() {
+ nginxController = addChild(EntitySpec.create(NginxController.class)
+ //.configure("domain", "webclusterexample.brooklyn.local")
+ .configure("port", "8000+"));
+
+ web = addChild(EntitySpec.create(ControlledDynamicWebAppCluster.class)
+ .displayName("WebApp cluster")
+ .configure(ControlledDynamicWebAppCluster.CONTROLLER, nginxController)
+ .configure(ControlledDynamicWebAppCluster.INITIAL_SIZE, 1)
+ .configure(ControlledDynamicWebAppCluster.MEMBER_SPEC, EntitySpec.create(JBoss7Server.class)
+ .configure("httpPort", "8080+")
+ .configure("war", WAR_PATH)));
+
+ web.getCluster().addPolicy(AutoScalerPolicy.builder()
+ .metric(DynamicWebAppCluster.REQUESTS_PER_SECOND_IN_WINDOW_PER_NODE)
+ .sizeRange(1, 5)
+ .metricRange(10, 100)
+ .build());
+ }
+
+ public static void main(String[] argv) {
+ List<String> args = Lists.newArrayList(argv);
+ String port = CommandLineUtil.getCommandLineOption(args, "--port", "8081+");
+ String location = CommandLineUtil.getCommandLineOption(args, "--location", DEFAULT_LOCATION);
+
+ // TODO Want to parse, to handle multiple locations
+ BrooklynLauncher launcher = BrooklynLauncher.newInstance()
+ .application(EntitySpec.create(WebClusterExample.class).displayName("Brooklyn WebApp Cluster example"))
+ .webconsolePort(port)
+ .location(location)
+ .start();
+
+ Entities.dumpInfo(launcher.getApplications());
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/9b8bde02/examples/simple-web-cluster/src/main/resources/brooklyn/demo/glossy-3d-blue-web-icon.png
----------------------------------------------------------------------
diff --git a/examples/simple-web-cluster/src/main/resources/brooklyn/demo/glossy-3d-blue-web-icon.png b/examples/simple-web-cluster/src/main/resources/brooklyn/demo/glossy-3d-blue-web-icon.png
deleted file mode 100644
index 542a1de..0000000
Binary files a/examples/simple-web-cluster/src/main/resources/brooklyn/demo/glossy-3d-blue-web-icon.png and /dev/null differ
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/9b8bde02/examples/simple-web-cluster/src/main/resources/brooklyn/demo/nodejs-riak-todo.yaml
----------------------------------------------------------------------
diff --git a/examples/simple-web-cluster/src/main/resources/brooklyn/demo/nodejs-riak-todo.yaml b/examples/simple-web-cluster/src/main/resources/brooklyn/demo/nodejs-riak-todo.yaml
deleted file mode 100644
index d963671..0000000
--- a/examples/simple-web-cluster/src/main/resources/brooklyn/demo/nodejs-riak-todo.yaml
+++ /dev/null
@@ -1,46 +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.
-
-name: "Node.JS Todo Application"
-origin: "https://github.com/amirrajan/nodejs-todo/"
-location:
- jclouds:aws-ec2:us-west-1:
- imageId: us-west-1/ami-c33cdd87
-services:
-- type: brooklyn.entity.nosql.riak.RiakCluster
- initialSize: 2
- id: mycluster
- brooklyn.config:
- provisioning.properties:
- osFamily: centos
- minCores: 4
- minRam: 2048
-- type: brooklyn.entity.webapp.nodejs.NodeJsWebAppService
- id: nodejs-riak1
- name: "Node.JS"
- brooklyn.config:
- gitRepoUrl:
- "https://github.com/bostko/nodejs-todo.git"
- appFileName: server.js
- appName: nodejs-todo
- nodePackages:
- - basho-riak-client
- env:
- NODE_ENV: production
- RIAK_NODES: >
- $brooklyn:component("mycluster").attributeWhenReady("riak.cluster.nodeListPbPort")
- launch.latch: $brooklyn:component("mycluster").attributeWhenReady("service.isUp")
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/9b8bde02/examples/simple-web-cluster/src/main/resources/brooklyn/demo/nodejs-todo.yaml
----------------------------------------------------------------------
diff --git a/examples/simple-web-cluster/src/main/resources/brooklyn/demo/nodejs-todo.yaml b/examples/simple-web-cluster/src/main/resources/brooklyn/demo/nodejs-todo.yaml
deleted file mode 100644
index ea17556..0000000
--- a/examples/simple-web-cluster/src/main/resources/brooklyn/demo/nodejs-todo.yaml
+++ /dev/null
@@ -1,53 +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.
-
-id: nodejs-todo-application
-name: "Node.JS Todo Application"
-origin: "https://github.com/amirrajan/nodejs-todo/"
-locations:
-- jclouds:softlayer:ams01
-services:
-- type: brooklyn.entity.nosql.redis.RedisStore
- id: redis
- name: "Redis"
-- type: brooklyn.entity.webapp.nodejs.NodeJsWebAppService
- id: nodejs
- name: "Node.JS"
- brooklyn.config:
- gitRepoUrl:
- "https://github.com/grkvlt/nodejs-todo/"
- appFileName: server.js
- appName: nodejs-todo
- nodePackages:
- - express
- - ejs
- - jasmine-node
- - underscore
- - method-override
- - cookie-parser
- - express-session
- - body-parser
- - cookie-session
- - redis
- - redis-url
- - connect
- env:
- REDISTOGO_URL: >
- $brooklyn:formatString("redis://%s:%d/",
- component("redis").attributeWhenReady("host.subnet.hostname"),
- component("redis").attributeWhenReady("redis.port"))
- launch.latch: $brooklyn:component("redis").attributeWhenReady("service.isUp")
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/9b8bde02/examples/simple-web-cluster/src/main/resources/logback-custom.xml
----------------------------------------------------------------------
diff --git a/examples/simple-web-cluster/src/main/resources/logback-custom.xml b/examples/simple-web-cluster/src/main/resources/logback-custom.xml
index 0d403dd..02a8a82 100644
--- a/examples/simple-web-cluster/src/main/resources/logback-custom.xml
+++ b/examples/simple-web-cluster/src/main/resources/logback-custom.xml
@@ -27,7 +27,7 @@
-->
<!-- include this category -->
- <logger name="brooklyn.demo" level="DEBUG"/>
+ <logger name="org.apache.brooklyn.demo" level="DEBUG"/>
<!-- log to simple-web-cluster.log -->
<property name="logging.basename" scope="context" value="brooklyn-simple-web-cluster" />
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/9b8bde02/examples/simple-web-cluster/src/main/resources/org/apache/brooklyn/demo/glossy-3d-blue-web-icon.png
----------------------------------------------------------------------
diff --git a/examples/simple-web-cluster/src/main/resources/org/apache/brooklyn/demo/glossy-3d-blue-web-icon.png b/examples/simple-web-cluster/src/main/resources/org/apache/brooklyn/demo/glossy-3d-blue-web-icon.png
new file mode 100644
index 0000000..542a1de
Binary files /dev/null and b/examples/simple-web-cluster/src/main/resources/org/apache/brooklyn/demo/glossy-3d-blue-web-icon.png differ
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/9b8bde02/examples/simple-web-cluster/src/main/resources/org/apache/brooklyn/demo/nodejs-riak-todo.yaml
----------------------------------------------------------------------
diff --git a/examples/simple-web-cluster/src/main/resources/org/apache/brooklyn/demo/nodejs-riak-todo.yaml b/examples/simple-web-cluster/src/main/resources/org/apache/brooklyn/demo/nodejs-riak-todo.yaml
new file mode 100644
index 0000000..d963671
--- /dev/null
+++ b/examples/simple-web-cluster/src/main/resources/org/apache/brooklyn/demo/nodejs-riak-todo.yaml
@@ -0,0 +1,46 @@
+# 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.
+
+name: "Node.JS Todo Application"
+origin: "https://github.com/amirrajan/nodejs-todo/"
+location:
+ jclouds:aws-ec2:us-west-1:
+ imageId: us-west-1/ami-c33cdd87
+services:
+- type: brooklyn.entity.nosql.riak.RiakCluster
+ initialSize: 2
+ id: mycluster
+ brooklyn.config:
+ provisioning.properties:
+ osFamily: centos
+ minCores: 4
+ minRam: 2048
+- type: brooklyn.entity.webapp.nodejs.NodeJsWebAppService
+ id: nodejs-riak1
+ name: "Node.JS"
+ brooklyn.config:
+ gitRepoUrl:
+ "https://github.com/bostko/nodejs-todo.git"
+ appFileName: server.js
+ appName: nodejs-todo
+ nodePackages:
+ - basho-riak-client
+ env:
+ NODE_ENV: production
+ RIAK_NODES: >
+ $brooklyn:component("mycluster").attributeWhenReady("riak.cluster.nodeListPbPort")
+ launch.latch: $brooklyn:component("mycluster").attributeWhenReady("service.isUp")
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/9b8bde02/examples/simple-web-cluster/src/main/resources/org/apache/brooklyn/demo/nodejs-todo.yaml
----------------------------------------------------------------------
diff --git a/examples/simple-web-cluster/src/main/resources/org/apache/brooklyn/demo/nodejs-todo.yaml b/examples/simple-web-cluster/src/main/resources/org/apache/brooklyn/demo/nodejs-todo.yaml
new file mode 100644
index 0000000..ea17556
--- /dev/null
+++ b/examples/simple-web-cluster/src/main/resources/org/apache/brooklyn/demo/nodejs-todo.yaml
@@ -0,0 +1,53 @@
+# 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.
+
+id: nodejs-todo-application
+name: "Node.JS Todo Application"
+origin: "https://github.com/amirrajan/nodejs-todo/"
+locations:
+- jclouds:softlayer:ams01
+services:
+- type: brooklyn.entity.nosql.redis.RedisStore
+ id: redis
+ name: "Redis"
+- type: brooklyn.entity.webapp.nodejs.NodeJsWebAppService
+ id: nodejs
+ name: "Node.JS"
+ brooklyn.config:
+ gitRepoUrl:
+ "https://github.com/grkvlt/nodejs-todo/"
+ appFileName: server.js
+ appName: nodejs-todo
+ nodePackages:
+ - express
+ - ejs
+ - jasmine-node
+ - underscore
+ - method-override
+ - cookie-parser
+ - express-session
+ - body-parser
+ - cookie-session
+ - redis
+ - redis-url
+ - connect
+ env:
+ REDISTOGO_URL: >
+ $brooklyn:formatString("redis://%s:%d/",
+ component("redis").attributeWhenReady("host.subnet.hostname"),
+ component("redis").attributeWhenReady("redis.port"))
+ launch.latch: $brooklyn:component("redis").attributeWhenReady("service.isUp")
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/9b8bde02/examples/simple-web-cluster/src/test/java/brooklyn/demo/RebindWebClusterDatabaseExampleAppIntegrationTest.java
----------------------------------------------------------------------
diff --git a/examples/simple-web-cluster/src/test/java/brooklyn/demo/RebindWebClusterDatabaseExampleAppIntegrationTest.java b/examples/simple-web-cluster/src/test/java/brooklyn/demo/RebindWebClusterDatabaseExampleAppIntegrationTest.java
deleted file mode 100644
index f2c735c..0000000
--- a/examples/simple-web-cluster/src/test/java/brooklyn/demo/RebindWebClusterDatabaseExampleAppIntegrationTest.java
+++ /dev/null
@@ -1,205 +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.demo;
-
-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();
- }
-}
[09/12] incubator-brooklyn git commit:
brooklyn-example-simple-nosql-cluster: add org.apache package prefix
Posted by al...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/44d2dc11/examples/simple-nosql-cluster/src/main/java/org/apache/brooklyn/demo/WideAreaCassandraCluster.java
----------------------------------------------------------------------
diff --git a/examples/simple-nosql-cluster/src/main/java/org/apache/brooklyn/demo/WideAreaCassandraCluster.java b/examples/simple-nosql-cluster/src/main/java/org/apache/brooklyn/demo/WideAreaCassandraCluster.java
new file mode 100644
index 0000000..a19f817
--- /dev/null
+++ b/examples/simple-nosql-cluster/src/main/java/org/apache/brooklyn/demo/WideAreaCassandraCluster.java
@@ -0,0 +1,86 @@
+/*
+ * 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 java.util.Arrays;
+import java.util.List;
+
+import brooklyn.catalog.Catalog;
+import brooklyn.catalog.CatalogConfig;
+import brooklyn.config.ConfigKey;
+import brooklyn.entity.basic.AbstractApplication;
+import brooklyn.entity.basic.ConfigKeys;
+import brooklyn.entity.basic.Entities;
+import brooklyn.entity.basic.StartableApplication;
+import brooklyn.entity.nosql.cassandra.CassandraDatacenter;
+import brooklyn.entity.nosql.cassandra.CassandraFabric;
+import brooklyn.entity.nosql.cassandra.CassandraNode;
+import brooklyn.entity.proxying.EntitySpec;
+import brooklyn.launcher.BrooklynLauncher;
+import brooklyn.policy.EnricherSpec;
+import brooklyn.policy.PolicySpec;
+import brooklyn.policy.ha.ServiceFailureDetector;
+import brooklyn.policy.ha.ServiceReplacer;
+import brooklyn.policy.ha.ServiceRestarter;
+import brooklyn.util.CommandLineUtil;
+
+import com.google.common.collect.Lists;
+
+@Catalog(name="Wide Area Cassandra Cluster Application", description="Deploy a Cassandra cluster across multiple geographies.")
+public class WideAreaCassandraCluster extends AbstractApplication {
+
+ public static final String DEFAULT_LOCATION_SPEC = "aws-ec2:us-east-1,rackspace-cloudservers-uk";
+
+ @CatalogConfig(label="Initial Cluster Size (per location)", priority=2)
+ public static final ConfigKey<Integer> CASSANDRA_CLUSTER_SIZE = ConfigKeys.newConfigKey(
+ "cassandra.cluster.initialSize", "Initial size of the Cassandra clusterss", 2);
+
+
+
+ @Override
+ public void initApp() {
+ addChild(EntitySpec.create(CassandraFabric.class)
+ .configure(CassandraDatacenter.CLUSTER_NAME, "Brooklyn")
+ .configure(CassandraDatacenter.INITIAL_SIZE, getConfig(CASSANDRA_CLUSTER_SIZE)) // per location
+ .configure(CassandraDatacenter.ENDPOINT_SNITCH_NAME, "brooklyn.entity.nosql.cassandra.customsnitch.MultiCloudSnitch")
+ .configure(CassandraNode.CUSTOM_SNITCH_JAR_URL, "classpath://brooklyn/entity/nosql/cassandra/cassandra-multicloud-snitch.jar")
+ .configure(CassandraFabric.MEMBER_SPEC, EntitySpec.create(CassandraDatacenter.class)
+ .configure(CassandraDatacenter.MEMBER_SPEC, EntitySpec.create(CassandraNode.class)
+ .enricher(EnricherSpec.create(ServiceFailureDetector.class))
+ .policy(PolicySpec.create(ServiceRestarter.class)
+ .configure(ServiceRestarter.FAILURE_SENSOR_TO_MONITOR, ServiceFailureDetector.ENTITY_FAILED)))
+ .policy(PolicySpec.create(ServiceReplacer.class)
+ .configure(ServiceReplacer.FAILURE_SENSOR_TO_MONITOR, ServiceRestarter.ENTITY_RESTART_FAILED))));
+ }
+
+ public static void main(String[] argv) {
+ List<String> args = Lists.newArrayList(argv);
+ String port = CommandLineUtil.getCommandLineOption(args, "--port", "8081+");
+ String locations = CommandLineUtil.getCommandLineOption(args, "--location", DEFAULT_LOCATION_SPEC);
+
+ BrooklynLauncher launcher = BrooklynLauncher.newInstance()
+ .application(EntitySpec.create(StartableApplication.class, WideAreaCassandraCluster.class)
+ .displayName("Cassandra"))
+ .webconsolePort(port)
+ .locations(Arrays.asList(locations))
+ .start();
+
+ Entities.dumpInfo(launcher.getApplications());
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/44d2dc11/examples/simple-nosql-cluster/src/main/resources/brooklyn/demo/ha-cassandra-cluster.yaml
----------------------------------------------------------------------
diff --git a/examples/simple-nosql-cluster/src/main/resources/brooklyn/demo/ha-cassandra-cluster.yaml b/examples/simple-nosql-cluster/src/main/resources/brooklyn/demo/ha-cassandra-cluster.yaml
deleted file mode 100644
index 4a9ebc7..0000000
--- a/examples/simple-nosql-cluster/src/main/resources/brooklyn/demo/ha-cassandra-cluster.yaml
+++ /dev/null
@@ -1,45 +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.
-#
-# A YAML version of the HighAvailabilityCassandraCluster application
-#
-name: HA Cassandra cluster
-location: aws-ec2:us-east-1
-
-services:
-- type: brooklyn.entity.nosql.cassandra.CassandraDatacenter
- name: Brooklyn
- brooklyn.config:
- initialSize: 6
- enableAvailabilityZones: true
- # See https://github.com/brooklyncentral/brooklyn/issues/973
- availabilityZoneNames:
- - us-east-1b
- - us-east-1c
- - us-east-1e
- numAvailabilityZones: 3
- snitchName: GossipingPropertyFileSnitch
- memberSpec:
- $brooklyn:entitySpec:
- type: brooklyn.entity.nosql.cassandra.CassandraNode
- brookyn.policies:
- - type: brooklyn.policy.ha.ServiceRestarter
- brooklyn.enrichers:
- - type: brooklyn.policy.ha.ServiceFailureDetector
- brooklyn.policies:
- - type: brooklyn.policy.ha.ServiceReplacer
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/44d2dc11/examples/simple-nosql-cluster/src/main/resources/brooklyn/demo/simple-cassandra-cluster.yaml
----------------------------------------------------------------------
diff --git a/examples/simple-nosql-cluster/src/main/resources/brooklyn/demo/simple-cassandra-cluster.yaml b/examples/simple-nosql-cluster/src/main/resources/brooklyn/demo/simple-cassandra-cluster.yaml
deleted file mode 100644
index ff7b48c..0000000
--- a/examples/simple-nosql-cluster/src/main/resources/brooklyn/demo/simple-cassandra-cluster.yaml
+++ /dev/null
@@ -1,28 +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.
-#
-# A YAML version of the SimpleCassandraCluster application
-#
-name: Simple Cassandra cluster
-location: localhost
-
-services:
-- type: brooklyn.entity.nosql.cassandra.CassandraDatacenter
- name: Brooklyn
- brooklyn.config:
- initialSize: 1
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/44d2dc11/examples/simple-nosql-cluster/src/main/resources/brooklyn/demo/wide-area-cassandra-cluster.yaml
----------------------------------------------------------------------
diff --git a/examples/simple-nosql-cluster/src/main/resources/brooklyn/demo/wide-area-cassandra-cluster.yaml b/examples/simple-nosql-cluster/src/main/resources/brooklyn/demo/wide-area-cassandra-cluster.yaml
deleted file mode 100644
index 3e44e39..0000000
--- a/examples/simple-nosql-cluster/src/main/resources/brooklyn/demo/wide-area-cassandra-cluster.yaml
+++ /dev/null
@@ -1,41 +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.
-#
-# A YAML version of the WideAreaCassandraCluster application
-#
-name: Wide Area Cassandra cluster
-locations:
-- aws-ec2:us-east-1
-- rackspace-cloudservers-uk
-
-services:
-- type: brooklyn.entity.nosql.cassandra.CassandraFabric
- name: Brooklyn
- brooklyn.config:
- initialSize: 2
- snitchName: brooklyn.entity.nosql.cassandra.customsnitch.MultiCloudSnitch
- customSnitchJarUrl: classpath://brooklyn/entity/nosql/cassandra/cassandra-multicloud-snitch.jar
- memberSpec:
- $brooklyn:entitySpec:
- type: brooklyn.entity.nosql.cassandra.CassandraNode
- brookyn.policies:
- - type: brooklyn.policy.ha.ServiceRestarter
- brooklyn.enrichers:
- - type: brooklyn.policy.ha.ServiceFailureDetector
- brooklyn.policies:
- - type: brooklyn.policy.ha.ServiceReplacer
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/44d2dc11/examples/simple-nosql-cluster/src/main/resources/org/apache/brooklyn/demo/ha-cassandra-cluster.yaml
----------------------------------------------------------------------
diff --git a/examples/simple-nosql-cluster/src/main/resources/org/apache/brooklyn/demo/ha-cassandra-cluster.yaml b/examples/simple-nosql-cluster/src/main/resources/org/apache/brooklyn/demo/ha-cassandra-cluster.yaml
new file mode 100644
index 0000000..4a9ebc7
--- /dev/null
+++ b/examples/simple-nosql-cluster/src/main/resources/org/apache/brooklyn/demo/ha-cassandra-cluster.yaml
@@ -0,0 +1,45 @@
+#
+# 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.
+#
+# A YAML version of the HighAvailabilityCassandraCluster application
+#
+name: HA Cassandra cluster
+location: aws-ec2:us-east-1
+
+services:
+- type: brooklyn.entity.nosql.cassandra.CassandraDatacenter
+ name: Brooklyn
+ brooklyn.config:
+ initialSize: 6
+ enableAvailabilityZones: true
+ # See https://github.com/brooklyncentral/brooklyn/issues/973
+ availabilityZoneNames:
+ - us-east-1b
+ - us-east-1c
+ - us-east-1e
+ numAvailabilityZones: 3
+ snitchName: GossipingPropertyFileSnitch
+ memberSpec:
+ $brooklyn:entitySpec:
+ type: brooklyn.entity.nosql.cassandra.CassandraNode
+ brookyn.policies:
+ - type: brooklyn.policy.ha.ServiceRestarter
+ brooklyn.enrichers:
+ - type: brooklyn.policy.ha.ServiceFailureDetector
+ brooklyn.policies:
+ - type: brooklyn.policy.ha.ServiceReplacer
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/44d2dc11/examples/simple-nosql-cluster/src/main/resources/org/apache/brooklyn/demo/simple-cassandra-cluster.yaml
----------------------------------------------------------------------
diff --git a/examples/simple-nosql-cluster/src/main/resources/org/apache/brooklyn/demo/simple-cassandra-cluster.yaml b/examples/simple-nosql-cluster/src/main/resources/org/apache/brooklyn/demo/simple-cassandra-cluster.yaml
new file mode 100644
index 0000000..ff7b48c
--- /dev/null
+++ b/examples/simple-nosql-cluster/src/main/resources/org/apache/brooklyn/demo/simple-cassandra-cluster.yaml
@@ -0,0 +1,28 @@
+#
+# 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.
+#
+# A YAML version of the SimpleCassandraCluster application
+#
+name: Simple Cassandra cluster
+location: localhost
+
+services:
+- type: brooklyn.entity.nosql.cassandra.CassandraDatacenter
+ name: Brooklyn
+ brooklyn.config:
+ initialSize: 1
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/44d2dc11/examples/simple-nosql-cluster/src/main/resources/org/apache/brooklyn/demo/wide-area-cassandra-cluster.yaml
----------------------------------------------------------------------
diff --git a/examples/simple-nosql-cluster/src/main/resources/org/apache/brooklyn/demo/wide-area-cassandra-cluster.yaml b/examples/simple-nosql-cluster/src/main/resources/org/apache/brooklyn/demo/wide-area-cassandra-cluster.yaml
new file mode 100644
index 0000000..3e44e39
--- /dev/null
+++ b/examples/simple-nosql-cluster/src/main/resources/org/apache/brooklyn/demo/wide-area-cassandra-cluster.yaml
@@ -0,0 +1,41 @@
+#
+# 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.
+#
+# A YAML version of the WideAreaCassandraCluster application
+#
+name: Wide Area Cassandra cluster
+locations:
+- aws-ec2:us-east-1
+- rackspace-cloudservers-uk
+
+services:
+- type: brooklyn.entity.nosql.cassandra.CassandraFabric
+ name: Brooklyn
+ brooklyn.config:
+ initialSize: 2
+ snitchName: brooklyn.entity.nosql.cassandra.customsnitch.MultiCloudSnitch
+ customSnitchJarUrl: classpath://brooklyn/entity/nosql/cassandra/cassandra-multicloud-snitch.jar
+ memberSpec:
+ $brooklyn:entitySpec:
+ type: brooklyn.entity.nosql.cassandra.CassandraNode
+ brookyn.policies:
+ - type: brooklyn.policy.ha.ServiceRestarter
+ brooklyn.enrichers:
+ - type: brooklyn.policy.ha.ServiceFailureDetector
+ brooklyn.policies:
+ - type: brooklyn.policy.ha.ServiceReplacer
[03/12] incubator-brooklyn git commit: brooklyn-qa: add org.apache
package prefix
Posted by al...@apache.org.
brooklyn-qa: add org.apache package prefix
Project: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/commit/bd44bb8f
Tree: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/tree/bd44bb8f
Diff: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/diff/bd44bb8f
Branch: refs/heads/master
Commit: bd44bb8f18799d603308d19e98348c949ffa00a1
Parents: 0d7c48c
Author: Ciprian Ciubotariu <ch...@gmx.net>
Authored: Tue Jul 14 18:33:30 2015 +0300
Committer: Ciprian Ciubotariu <ch...@gmx.net>
Committed: Wed Jul 15 16:56:03 2015 +0300
----------------------------------------------------------------------
.../qa/load/SimulatedJBoss7ServerImpl.java | 240 --------------
.../qa/load/SimulatedMySqlNodeImpl.java | 183 -----------
.../qa/load/SimulatedNginxControllerImpl.java | 196 -----------
.../brooklyn/qa/load/SimulatedTheeTierApp.java | 140 --------
.../java/brooklyn/qa/longevity/Monitor.java | 261 ---------------
.../brooklyn/qa/longevity/MonitorListener.java | 35 --
.../brooklyn/qa/longevity/MonitorPrefs.java | 54 ---
.../brooklyn/qa/longevity/MonitorUtils.java | 329 -------------------
.../brooklyn/qa/longevity/StatusRecorder.java | 130 --------
.../qa/load/SimulatedJBoss7ServerImpl.java | 240 ++++++++++++++
.../qa/load/SimulatedMySqlNodeImpl.java | 183 +++++++++++
.../qa/load/SimulatedNginxControllerImpl.java | 196 +++++++++++
.../brooklyn/qa/load/SimulatedTheeTierApp.java | 140 ++++++++
.../apache/brooklyn/qa/longevity/Monitor.java | 261 +++++++++++++++
.../brooklyn/qa/longevity/MonitorListener.java | 35 ++
.../brooklyn/qa/longevity/MonitorPrefs.java | 54 +++
.../brooklyn/qa/longevity/MonitorUtils.java | 329 +++++++++++++++++++
.../brooklyn/qa/longevity/StatusRecorder.java | 130 ++++++++
.../test/java/brooklyn/qa/load/LoadTest.java | 243 --------------
.../brooklyn/qa/longevity/MonitorUtilsTest.java | 165 ----------
.../webcluster/SinusoidalLoadGenerator.java | 90 -----
.../qa/longevity/webcluster/WebClusterApp.java | 101 ------
.../org/apache/brooklyn/qa/load/LoadTest.java | 244 ++++++++++++++
.../brooklyn/qa/longevity/MonitorUtilsTest.java | 166 ++++++++++
.../webcluster/SinusoidalLoadGenerator.java | 90 +++++
.../qa/longevity/webcluster/WebClusterApp.java | 101 ++++++
26 files changed, 2169 insertions(+), 2167 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/bd44bb8f/usage/qa/src/main/java/brooklyn/qa/load/SimulatedJBoss7ServerImpl.java
----------------------------------------------------------------------
diff --git a/usage/qa/src/main/java/brooklyn/qa/load/SimulatedJBoss7ServerImpl.java b/usage/qa/src/main/java/brooklyn/qa/load/SimulatedJBoss7ServerImpl.java
deleted file mode 100644
index 64f7aa5..0000000
--- a/usage/qa/src/main/java/brooklyn/qa/load/SimulatedJBoss7ServerImpl.java
+++ /dev/null
@@ -1,240 +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.qa.load;
-
-import static java.lang.String.format;
-
-import java.util.concurrent.Callable;
-
-import brooklyn.config.ConfigKey;
-import brooklyn.enricher.Enrichers;
-import brooklyn.entity.basic.Attributes;
-import brooklyn.entity.webapp.jboss.JBoss7ServerImpl;
-import brooklyn.entity.webapp.jboss.JBoss7SshDriver;
-import brooklyn.event.feed.function.FunctionFeed;
-import brooklyn.event.feed.function.FunctionPollConfig;
-import brooklyn.event.feed.http.HttpFeed;
-import brooklyn.event.feed.http.HttpPollConfig;
-import brooklyn.event.feed.http.HttpValueFunctions;
-import brooklyn.location.access.BrooklynAccessUtils;
-import brooklyn.location.basic.SshMachineLocation;
-import brooklyn.util.collections.MutableMap;
-import brooklyn.util.guava.Functionals;
-import brooklyn.util.os.Os;
-
-import com.google.common.net.HostAndPort;
-
-/**
- * For simulating various aspects of the JBoss 7 app-server entity.
- *
- * The use-case for this is that the desired configuration is not always available for testing.
- * For example, there may be insufficient resources to run 100s of JBoss app-servers, or one
- * may be experimenting with possible configurations such as use of an external monitoring tool
- * that is not yet available.
- *
- * It is then possible to simulate aspects of the behaviour, for performance and load testing purposes.
- *
- * There is configuration for:
- * <ul>
- * <li>{@code simulateEntity}
- * <ul>
- * <li>if true, no underlying entity will be started. Instead a sleep 100000 job will be run and monitored.
- * <li>if false, the underlying entity (i.e. a JBoss app-server) will be started as normal.
- * </ul>
- * <li>{@code simulateExternalMonitoring}
- * <ul>
- * <li>if true, disables the default monitoring mechanism. Instead, a function will periodically execute
- * to set the entity's sensors (as though the values had been obtained from the external monitoring tool).
- * <li>if false, then:
- * <ul>
- * <li>If {@code simulateEntity==true} it will execute comparable commands (e.g. execute a command of the same
- * size over ssh or do a comparable number of http GET requests).
- * <li>If {@code simulateEntity==false} then normal monitoring will be done.
- * </ul>
- * </ul>
- * <li>{@code skipSshOnStart}
- * <ul>
- * <li>If true (and if {@code simulateEntity==true}), then no ssh commands will be executed at deploy-time.
- * This is useful for speeding up load testing, to get to the desired number of entities.
- * Should not be set to {@code true} if {@code simulateEntity==false}.
- * <li>If false, the ssh commands will be executed (based on the value of {@code simulateEntity}.
- * </ul>
- * </ul>
- */
-public class SimulatedJBoss7ServerImpl extends JBoss7ServerImpl {
-
- public static final ConfigKey<Boolean> SIMULATE_ENTITY = SimulatedTheeTierApp.SIMULATE_ENTITY;
- public static final ConfigKey<Boolean> SIMULATE_EXTERNAL_MONITORING = SimulatedTheeTierApp.SIMULATE_EXTERNAL_MONITORING;
- public static final ConfigKey<Boolean> SKIP_SSH_ON_START = SimulatedTheeTierApp.SKIP_SSH_ON_START;
-
- private HttpFeed httpFeed;
- private FunctionFeed functionFeed;
-
- @Override
- public Class<?> getDriverInterface() {
- return SimulatedJBoss7SshDriver.class;
- }
-
- @Override
- protected void connectSensors() {
- boolean simulateEntity = getConfig(SIMULATE_ENTITY);
- boolean simulateExternalMonitoring = getConfig(SIMULATE_EXTERNAL_MONITORING);
-
- if (!simulateEntity && !simulateExternalMonitoring) {
- super.connectSensors();
- return;
- }
-
- HostAndPort hp = BrooklynAccessUtils.getBrooklynAccessibleAddress(this,
- getAttribute(MANAGEMENT_HTTP_PORT) + getConfig(PORT_INCREMENT));
-
- String managementUri = String.format("http://%s:%s/management/subsystem/web/connector/http/read-resource",
- hp.getHostText(), hp.getPort());
- setAttribute(MANAGEMENT_URL, managementUri);
-
- if (simulateExternalMonitoring) {
- // TODO What would set this normally, if not doing connectServiceUpIsRunning?
- setAttribute(SERVICE_PROCESS_IS_RUNNING, true);
- } else {
- // if simulating entity, then simulate work of periodic HTTP request; TODO but not parsing JSON response
- String uriToPoll = (simulateEntity) ? "http://localhost:8081" : managementUri;
-
- httpFeed = HttpFeed.builder()
- .entity(this)
- .period(200)
- .baseUri(uriToPoll)
- .credentials(getConfig(MANAGEMENT_USER), getConfig(MANAGEMENT_PASSWORD))
- .poll(new HttpPollConfig<Integer>(MANAGEMENT_STATUS)
- .onSuccess(HttpValueFunctions.responseCode()))
- .build();
-
- // Polls over ssh for whether process is running
- connectServiceUpIsRunning();
- }
-
- functionFeed = FunctionFeed.builder()
- .entity(this)
- .period(5000)
- .poll(new FunctionPollConfig<Boolean,Boolean>(MANAGEMENT_URL_UP)
- .callable(new Callable<Boolean>() {
- private int counter = 0;
- public Boolean call() {
- setAttribute(REQUEST_COUNT, (counter++ % 100));
- setAttribute(ERROR_COUNT, (counter++ % 100));
- setAttribute(TOTAL_PROCESSING_TIME, (counter++ % 100));
- setAttribute(MAX_PROCESSING_TIME, (counter++ % 100));
- setAttribute(BYTES_RECEIVED, (long) (counter++ % 100));
- setAttribute(BYTES_SENT, (long) (counter++ % 100));
- return true;
- }}))
- .build();
-
- addEnricher(Enrichers.builder().updatingMap(Attributes.SERVICE_NOT_UP_INDICATORS)
- .from(MANAGEMENT_URL_UP)
- .computing(Functionals.ifNotEquals(true).value("Management URL not reachable") )
- .build());
- }
-
- @Override
- protected void disconnectSensors() {
- super.disconnectSensors();
- if (httpFeed != null) httpFeed.stop();
- if (functionFeed != null) functionFeed.stop();
- }
-
- public static class SimulatedJBoss7SshDriver extends JBoss7SshDriver {
- public SimulatedJBoss7SshDriver(SimulatedJBoss7ServerImpl entity, SshMachineLocation machine) {
- super(entity, machine);
- }
-
- @Override
- public boolean isRunning() {
- if (entity.getConfig(SKIP_SSH_ON_START)) {
- return true;
- } else {
- return super.isRunning();
- }
- }
-
- @Override
- public void install() {
- if (entity.getConfig(SKIP_SSH_ON_START)) {
- // no-op
- } else {
- super.install();
- }
- }
-
- @Override
- public void customize() {
- if (entity.getConfig(SKIP_SSH_ON_START)) {
- // no-op
- } else {
- super.customize();
- }
- }
-
- @Override
- public void launch() {
- if (!entity.getConfig(SIMULATE_ENTITY)) {
- super.launch();
- return;
- }
-
- // We wait for evidence of JBoss running because, using
- // brooklyn.ssh.config.tool.class=brooklyn.util.internal.ssh.cli.SshCliTool,
- // we saw the ssh session return before the JBoss process was fully running
- // so the process failed to start.
- String pidFile = Os.mergePathsUnix(getRunDir(), PID_FILENAME);
-
- if (entity.getConfig(SKIP_SSH_ON_START)) {
- // minimal ssh, so that isRunning will subsequently work
- newScript(MutableMap.of("usePidFile", pidFile), LAUNCHING)
- .body.append(
- format("nohup sleep 100000 > %s/console 2>&1 < /dev/null &", getRunDir()))
- .execute();
- } else {
- newScript(MutableMap.of(USE_PID_FILE, false), LAUNCHING)
- .body.append(
- "export LAUNCH_JBOSS_IN_BACKGROUND=true",
- format("export JBOSS_HOME=%s", getExpandedInstallDir()),
- format("export JBOSS_PIDFILE=%s/%s", getRunDir(), PID_FILENAME),
- format("echo skipping exec of %s/bin/%s.sh ", getExpandedInstallDir(), SERVER_TYPE) +
- format("--server-config %s ", CONFIG_FILE) +
- format("-Djboss.server.base.dir=%s/%s ", getRunDir(), SERVER_TYPE) +
- format("\"-Djboss.server.base.url=file://%s/%s\" ", getRunDir(), SERVER_TYPE) +
- "-Djava.net.preferIPv4Stack=true " +
- "-Djava.net.preferIPv6Addresses=false " +
- format(" >> %s/console 2>&1 </dev/null &", getRunDir()),
- format("nohup sleep 100000 > %s/console 2>&1 < /dev/null &", getRunDir()),
- format("echo $! > "+pidFile),
- format("echo starting > %s/console", getRunDir()),
- "for i in {1..10}\n" +
- "do\n" +
- " grep -i 'starting' "+getRunDir()+"/console && exit\n" +
- " sleep 1\n" +
- "done\n" +
- "echo \"Couldn't determine if process is running (console output does not contain 'starting'); continuing but may subsequently fail\""
-
- )
- .execute();
- }
- }
- }
-}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/bd44bb8f/usage/qa/src/main/java/brooklyn/qa/load/SimulatedMySqlNodeImpl.java
----------------------------------------------------------------------
diff --git a/usage/qa/src/main/java/brooklyn/qa/load/SimulatedMySqlNodeImpl.java b/usage/qa/src/main/java/brooklyn/qa/load/SimulatedMySqlNodeImpl.java
deleted file mode 100644
index bad437a..0000000
--- a/usage/qa/src/main/java/brooklyn/qa/load/SimulatedMySqlNodeImpl.java
+++ /dev/null
@@ -1,183 +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.qa.load;
-
-import static java.lang.String.format;
-
-import java.util.concurrent.Callable;
-
-import brooklyn.config.ConfigKey;
-import brooklyn.entity.basic.AbstractSoftwareProcessSshDriver;
-import brooklyn.entity.database.mysql.MySqlNode;
-import brooklyn.entity.database.mysql.MySqlNodeImpl;
-import brooklyn.entity.database.mysql.MySqlSshDriver;
-import brooklyn.entity.software.SshEffectorTasks;
-import brooklyn.event.feed.function.FunctionFeed;
-import brooklyn.event.feed.function.FunctionPollConfig;
-import brooklyn.location.basic.SshMachineLocation;
-import brooklyn.util.collections.MutableMap;
-import brooklyn.util.task.DynamicTasks;
-import brooklyn.util.task.system.ProcessTaskWrapper;
-import brooklyn.util.time.CountdownTimer;
-import brooklyn.util.time.Duration;
-
-/**
- * @see SimulatedJBoss7ServerImpl for description of purpose and configuration options.
- */
-public class SimulatedMySqlNodeImpl extends MySqlNodeImpl {
-
- public static final ConfigKey<Boolean> SIMULATE_ENTITY = SimulatedTheeTierApp.SIMULATE_ENTITY;
- public static final ConfigKey<Boolean> SIMULATE_EXTERNAL_MONITORING = SimulatedTheeTierApp.SIMULATE_EXTERNAL_MONITORING;
- public static final ConfigKey<Boolean> SKIP_SSH_ON_START = SimulatedTheeTierApp.SKIP_SSH_ON_START;
-
- private FunctionFeed feed;
-
- @Override
- public Class<?> getDriverInterface() {
- return SimulatedMySqlSshDriver.class;
- }
-
- @Override
- protected void connectSensors() {
- boolean simulateExternalMonitoring = getConfig(SIMULATE_EXTERNAL_MONITORING);
- if (simulateExternalMonitoring) {
- setAttribute(DATASTORE_URL, String.format("mysql://%s:%s/", getAttribute(HOSTNAME), getAttribute(MYSQL_PORT)));
-
- feed = FunctionFeed.builder()
- .entity(this)
- .period(Duration.FIVE_SECONDS)
- .poll(new FunctionPollConfig<Boolean, Boolean>(SERVICE_UP)
- .callable(new Callable<Boolean>() {
- private int counter = 0;
- public Boolean call() {
- setAttribute(QUERIES_PER_SECOND_FROM_MYSQL, (double)(counter++ % 100));
- return true;
- }})
- .setOnFailureOrException(false))
- .build();
- } else {
- super.connectSensors();
- }
- }
-
- public static class SimulatedMySqlSshDriver extends MySqlSshDriver {
-
- private int counter = 0;
-
- public SimulatedMySqlSshDriver(SimulatedMySqlNodeImpl entity, SshMachineLocation machine) {
- super(entity, machine);
- }
-
- // simulate metrics, for if using ssh polling
- @Override
- public String getStatusCmd() {
- if (entity.getConfig(SIMULATE_ENTITY)) {
- return "echo Uptime: 2427 Threads: 1 Questions: 581 Slow queries: 0 Opens: 53 Flush tables: 1 Open tables: 35 Queries per second avg: "+(counter++ % 100);
- } else {
- return super.getStatusCmd();
- }
- }
-
- @Override
- public void install() {
- if (entity.getConfig(SKIP_SSH_ON_START)) {
- // no-op
- } else {
- super.install();
- }
- }
-
- // Not applying creation-script etc, as that requires launching msyqld (so would not scale for single-machine testing)
- // This is a copy of super.customize, but with the mysqladmin-exec disabled
- @Override
- public void customize() {
- if (!entity.getConfig(SIMULATE_ENTITY)) {
- super.customize();
- return;
- } else if (entity.getConfig(SKIP_SSH_ON_START)) {
- // no-op
- } else {
- copyDatabaseConfigScript();
-
- newScript(CUSTOMIZING)
- .updateTaskAndFailOnNonZeroResultCode()
- .body.append(
- "chmod 600 "+getConfigFile(),
- getBaseDir()+"/scripts/mysql_install_db "+
- "--basedir="+getBaseDir()+" --datadir="+getDataDir()+" "+
- "--defaults-file="+getConfigFile())
- .execute();
-
- // launch, then we will configure it
- launch();
-
- CountdownTimer timer = Duration.seconds(20).countdownTimer();
- boolean hasCreationScript = copyDatabaseCreationScript();
- timer.waitForExpiryUnchecked();
-
- // DELIBERATELY SKIPPED FOR SCALABILITY TESTING ON SINGLE MACHINE
- DynamicTasks.queue(
- SshEffectorTasks.ssh(
- "cd "+getRunDir(),
- "echo skipping exec of "+getBaseDir()+"/bin/mysqladmin --defaults-file="+getConfigFile()+" --password= password "+getPassword()
- ).summary("setting password"));
-
- if (hasCreationScript)
- executeScriptFromInstalledFileAsync("creation-script.sql");
-
- // not sure necessary to stop then subsequently launch, but seems safest
- // (if skipping, use a flag in launch to indicate we've just launched it)
- stop();
- }
- }
-
- @Override
- public void launch() {
- if (!entity.getConfig(SIMULATE_ENTITY)) {
- super.launch();
- return;
- }
-
- entity.setAttribute(MySqlNode.PID_FILE, getRunDir() + "/" + AbstractSoftwareProcessSshDriver.PID_FILENAME);
-
- if (entity.getConfig(SKIP_SSH_ON_START)) {
- // minimal ssh, so that isRunning will subsequently work
- newScript(MutableMap.of("usePidFile", true), LAUNCHING)
- .body.append(
- format("nohup sleep 100000 > %s 2>&1 < /dev/null &", getLogFile()))
- .execute();
- } else {
- newScript(MutableMap.of("usePidFile", true), LAUNCHING)
- .updateTaskAndFailOnNonZeroResultCode()
- .body.append(format("echo skipping normal exec of nohup %s/bin/mysqld --defaults-file=%s --user=`whoami` > %s 2>&1 < /dev/null &", getBaseDir(), getConfigFile(), getLogFile()))
- .body.append(format("nohup sleep 100000 > %s 2>&1 < /dev/null &", getLogFile()))
- .execute();
- }
- }
-
- @Override
- public ProcessTaskWrapper<Integer> executeScriptFromInstalledFileAsync(String filenameAlreadyInstalledAtServer) {
- return DynamicTasks.queue(
- SshEffectorTasks.ssh(
- "cd "+getRunDir(),
- "echo skipping exec of "+getBaseDir()+"/bin/mysql --defaults-file="+getConfigFile()+" < "+filenameAlreadyInstalledAtServer)
- .summary("executing datastore script "+filenameAlreadyInstalledAtServer));
- }
- }
-}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/bd44bb8f/usage/qa/src/main/java/brooklyn/qa/load/SimulatedNginxControllerImpl.java
----------------------------------------------------------------------
diff --git a/usage/qa/src/main/java/brooklyn/qa/load/SimulatedNginxControllerImpl.java b/usage/qa/src/main/java/brooklyn/qa/load/SimulatedNginxControllerImpl.java
deleted file mode 100644
index e5c40c2..0000000
--- a/usage/qa/src/main/java/brooklyn/qa/load/SimulatedNginxControllerImpl.java
+++ /dev/null
@@ -1,196 +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.qa.load;
-
-import static java.lang.String.format;
-
-import java.net.URI;
-import java.util.Collection;
-import java.util.concurrent.Callable;
-
-import brooklyn.config.ConfigKey;
-import brooklyn.entity.Group;
-import brooklyn.entity.proxy.nginx.NginxControllerImpl;
-import brooklyn.entity.proxy.nginx.NginxSshDriver;
-import brooklyn.entity.proxy.nginx.UrlMapping;
-import brooklyn.event.SensorEvent;
-import brooklyn.event.SensorEventListener;
-import brooklyn.event.feed.ConfigToAttributes;
-import brooklyn.event.feed.function.FunctionFeed;
-import brooklyn.event.feed.function.FunctionPollConfig;
-import brooklyn.event.feed.http.HttpFeed;
-import brooklyn.event.feed.http.HttpPollConfig;
-import brooklyn.location.basic.SshMachineLocation;
-import brooklyn.policy.PolicySpec;
-import brooklyn.util.collections.MutableMap;
-import brooklyn.util.net.Networking;
-
-import com.google.common.base.Functions;
-
-/**
- * @see SimulatedJBoss7ServerImpl for description of purpose and configuration options.
- */
-public class SimulatedNginxControllerImpl extends NginxControllerImpl {
-
- public static final ConfigKey<Boolean> SIMULATE_ENTITY = SimulatedTheeTierApp.SIMULATE_ENTITY;
- public static final ConfigKey<Boolean> SIMULATE_EXTERNAL_MONITORING = SimulatedTheeTierApp.SIMULATE_EXTERNAL_MONITORING;
- public static final ConfigKey<Boolean> SKIP_SSH_ON_START = SimulatedTheeTierApp.SKIP_SSH_ON_START;
-
- private HttpFeed httpFeed;
- private FunctionFeed functionFeed;
-
- @Override
- public Class<?> getDriverInterface() {
- return SimulatedNginxSshDriver.class;
- }
-
- @Override
- public void connectSensors() {
- boolean simulateEntity = getConfig(SIMULATE_ENTITY);
- boolean simulateExternalMonitoring = getConfig(SIMULATE_EXTERNAL_MONITORING);
-
- if (!simulateEntity && !simulateExternalMonitoring) {
- super.connectSensors();
- return;
- }
-
- // From AbstractController.connectSensors
- if (getUrl()==null) {
- setAttribute(MAIN_URI, URI.create(inferUrl()));
- setAttribute(ROOT_URL, inferUrl());
- }
- addServerPoolMemberTrackingPolicy();
-
- // From NginxController.connectSensors
- ConfigToAttributes.apply(this);
-
- if (!simulateExternalMonitoring) {
- // if simulating entity, then simulate work of periodic HTTP request; TODO but not parsing JSON response
- String uriToPoll = (simulateEntity) ? "http://localhost:8081" : getAttribute(MAIN_URI).toString();
-
- httpFeed = HttpFeed.builder()
- .entity(this)
- .period(getConfig(HTTP_POLL_PERIOD))
- .baseUri(uriToPoll)
- .poll(new HttpPollConfig<Boolean>(SERVICE_UP)
- .onSuccess(Functions.constant(true))
- .onFailureOrException(Functions.constant(true)))
- .build();
- }
-
- functionFeed = FunctionFeed.builder()
- .entity(this)
- .period(getConfig(HTTP_POLL_PERIOD))
- .poll(new FunctionPollConfig<Boolean,Boolean>(SERVICE_UP)
- .callable(new Callable<Boolean>() {
- public Boolean call() {
- return true;
- }}))
- .build();
-
- // Can guarantee that parent/managementContext has been set
- Group urlMappings = getConfig(URL_MAPPINGS);
- if (urlMappings != null) {
- // Listen to the targets of each url-mapping changing
- subscribeToMembers(urlMappings, UrlMapping.TARGET_ADDRESSES, new SensorEventListener<Collection<String>>() {
- @Override public void onEvent(SensorEvent<Collection<String>> event) {
- updateNeeded();
- }
- });
-
- // Listen to url-mappings being added and removed
- urlMappingsMemberTrackerPolicy = addPolicy(PolicySpec.create(UrlMappingsMemberTrackerPolicy.class)
- .configure("group", urlMappings));
- }
- }
-
- @Override
- protected void disconnectSensors() {
- super.disconnectSensors();
- if (httpFeed != null) httpFeed.stop();
- if (functionFeed != null) functionFeed.stop();
- }
-
- public static class SimulatedNginxSshDriver extends NginxSshDriver {
- public SimulatedNginxSshDriver(SimulatedNginxControllerImpl entity, SshMachineLocation machine) {
- super(entity, machine);
- }
-
- @Override
- public void install() {
- if (entity.getConfig(SKIP_SSH_ON_START)) {
- // no-op
- } else {
- super.install();
- }
- }
-
- @Override
- public void customize() {
- if (entity.getConfig(SKIP_SSH_ON_START)) {
- // no-op
- } else {
- super.customize();
- }
- }
-
- @Override
- public void launch() {
- if (!entity.getConfig(SIMULATE_ENTITY)) {
- super.launch();
- return;
- }
-
- Networking.checkPortsValid(MutableMap.of("httpPort", getPort()));
-
- if (entity.getConfig(SKIP_SSH_ON_START)) {
- // minimal ssh, so that isRunning will subsequently work
- newScript(MutableMap.of("usePidFile", getPidFile()), LAUNCHING)
- .body.append(
- format("mkdir -p %s/logs", getRunDir()),
- format("nohup sleep 100000 > %s 2>&1 < /dev/null &", getLogFileLocation()))
- .execute();
- } else {
- newScript(MutableMap.of("usePidFile", false), LAUNCHING)
- .body.append(
- format("cd %s", getRunDir()),
- "echo skipping exec of requireExecutable ./sbin/nginx",
- sudoBashCIfPrivilegedPort(getPort(), format(
- "echo skipping exec of nohup ./sbin/nginx -p %s/ -c conf/server.conf > %s 2>&1 &", getRunDir(), getLogFileLocation())),
- format("nohup sleep 100000 > %s 2>&1 < /dev/null &", getLogFileLocation()),
- format("echo $! > "+getPidFile()),
- format("for i in {1..10}\n" +
- "do\n" +
- " test -f %1$s && ps -p `cat %1$s` && exit\n" +
- " sleep 1\n" +
- "done\n" +
- "echo \"No explicit error launching nginx but couldn't find process by pid; continuing but may subsequently fail\"\n" +
- "cat %2$s | tee /dev/stderr",
- getPidFile(), getLogFileLocation()))
- .execute();
- }
- }
-
- // Use pid file, because just simulating the run of nginx
- @Override
- public void stop() {
- newScript(MutableMap.of("usePidFile", getPidFile()), STOPPING).execute();
- }
- }
-}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/bd44bb8f/usage/qa/src/main/java/brooklyn/qa/load/SimulatedTheeTierApp.java
----------------------------------------------------------------------
diff --git a/usage/qa/src/main/java/brooklyn/qa/load/SimulatedTheeTierApp.java b/usage/qa/src/main/java/brooklyn/qa/load/SimulatedTheeTierApp.java
deleted file mode 100644
index 6f95209..0000000
--- a/usage/qa/src/main/java/brooklyn/qa/load/SimulatedTheeTierApp.java
+++ /dev/null
@@ -1,140 +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.qa.load;
-
-import static brooklyn.event.basic.DependentConfiguration.attributeWhenReady;
-import static brooklyn.event.basic.DependentConfiguration.formatString;
-
-import java.util.Collection;
-import java.util.List;
-
-import brooklyn.config.ConfigKey;
-import brooklyn.enricher.Enrichers;
-import brooklyn.enricher.HttpLatencyDetector;
-import brooklyn.entity.basic.AbstractApplication;
-import brooklyn.entity.basic.Attributes;
-import brooklyn.entity.basic.ConfigKeys;
-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.trait.Startable;
-import brooklyn.entity.webapp.ControlledDynamicWebAppCluster;
-import brooklyn.entity.webapp.DynamicWebAppCluster;
-import brooklyn.entity.webapp.JavaWebAppService;
-import brooklyn.entity.webapp.WebAppService;
-import brooklyn.entity.webapp.WebAppServiceConstants;
-import brooklyn.entity.webapp.jboss.JBoss7Server;
-import brooklyn.launcher.BrooklynLauncher;
-import brooklyn.location.basic.PortRanges;
-import brooklyn.policy.autoscaling.AutoScalerPolicy;
-import brooklyn.util.CommandLineUtil;
-import brooklyn.util.collections.MutableSet;
-
-import com.google.common.base.Function;
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableSet;
-import com.google.common.collect.Lists;
-
-/**
- * A 3-tier app where all components are just "simulated" - they don't actually run
- * real app-servers or databases, instead just executing a "sleep" command to simulate
- * the running process.
- *
- * This is useful for load testing, where we want to test the performance of Brooklyn
- * rather than the ability to host many running app-servers.
- *
- * The app is based on WebClusterDatabaseExampleApp
- *
- * @see SimulatedJBoss7ServerImpl for description of purpose and configuration options.
- */
-public class SimulatedTheeTierApp extends AbstractApplication {
-
- public static final ConfigKey<Boolean> SIMULATE_ENTITY = ConfigKeys.newBooleanConfigKey("simulateEntity", "", true);
-
- public static final ConfigKey<Boolean> SIMULATE_EXTERNAL_MONITORING = ConfigKeys.newBooleanConfigKey("simulateExternalMonitoring", "", true);
-
- public static final ConfigKey<Boolean> SKIP_SSH_ON_START = ConfigKeys.newBooleanConfigKey("skipSshOnStart", "", false);
-
- public static final String WAR_PATH = "classpath://hello-world.war";
- public static final String DB_TABLE = "visitors";
- public static final String DB_USERNAME = "brooklyn";
- public static final String DB_PASSWORD = "br00k11n";
- public static final boolean USE_HTTPS = false;
-
- @Override
- public void init() {
- MySqlNode mysql = addChild(
- EntitySpec.create(MySqlNode.class)
- .impl(SimulatedMySqlNodeImpl.class));
-
- ControlledDynamicWebAppCluster web = addChild(
- EntitySpec.create(ControlledDynamicWebAppCluster.class)
- .configure(ControlledDynamicWebAppCluster.MEMBER_SPEC, EntitySpec.create(JBoss7Server.class).impl(SimulatedJBoss7ServerImpl.class))
- .configure(ControlledDynamicWebAppCluster.CONTROLLER_SPEC, EntitySpec.create(NginxController.class).impl(SimulatedNginxControllerImpl.class))
- .configure(WebAppService.HTTP_PORT, PortRanges.fromString("8080+"))
- .configure(JavaWebAppService.ROOT_WAR, WAR_PATH)
- .configure(JavaEntityMethods.javaSysProp("brooklyn.example.db.url"),
- formatString("jdbc:%s%s?user=%s\\&password=%s",
- attributeWhenReady(mysql, MySqlNode.DATASTORE_URL), DB_TABLE, DB_USERNAME, DB_PASSWORD))
- .configure(DynamicCluster.INITIAL_SIZE, 2)
- .configure(WebAppService.ENABLED_PROTOCOLS, ImmutableSet.of(USE_HTTPS ? "https" : "http")) );
-
- web.getCluster().addPolicy(AutoScalerPolicy.builder().
- metric(DynamicWebAppCluster.REQUESTS_PER_SECOND_IN_WINDOW_PER_NODE).
- metricRange(10, 100).
- sizeRange(2, 5).
- build());
-
- addEnricher(Enrichers.builder()
- .propagating(Attributes.MAIN_URI, WebAppServiceConstants.ROOT_URL,
- DynamicWebAppCluster.REQUESTS_PER_SECOND_IN_WINDOW,
- HttpLatencyDetector.REQUEST_LATENCY_IN_SECONDS_IN_WINDOW)
- .from(web)
- .build());
-
- addEnricher(Enrichers.builder()
- .aggregating(Startable.SERVICE_UP)
- .publishing(Startable.SERVICE_UP)
- .fromHardcodedProducers(ImmutableList.of(web, mysql))
- .computing(new Function<Collection<Boolean>, Boolean>() {
- @Override public Boolean apply(Collection<Boolean> input) {
- return input != null && input.size() == 2 && MutableSet.copyOf(input).equals(ImmutableSet.of(true));
- }})
- .build());
- }
-
- public static void main(String[] argv) {
- List<String> args = Lists.newArrayList(argv);
- String port = CommandLineUtil.getCommandLineOption(args, "--port", "8081+");
- String location = CommandLineUtil.getCommandLineOption(args, "--location", "localhost");
-
- BrooklynLauncher launcher = BrooklynLauncher.newInstance()
- .application(EntitySpec.create(StartableApplication.class, SimulatedTheeTierApp.class)
- .displayName("Brooklyn WebApp Cluster with Database example"))
- .webconsolePort(port)
- .location(location)
- .start();
-
- Entities.dumpInfo(launcher.getApplications());
- }
-}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/bd44bb8f/usage/qa/src/main/java/brooklyn/qa/longevity/Monitor.java
----------------------------------------------------------------------
diff --git a/usage/qa/src/main/java/brooklyn/qa/longevity/Monitor.java b/usage/qa/src/main/java/brooklyn/qa/longevity/Monitor.java
deleted file mode 100644
index 36e9f55..0000000
--- a/usage/qa/src/main/java/brooklyn/qa/longevity/Monitor.java
+++ /dev/null
@@ -1,261 +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.qa.longevity;
-
-import static brooklyn.qa.longevity.StatusRecorder.Factory.chain;
-import static brooklyn.qa.longevity.StatusRecorder.Factory.noop;
-import static brooklyn.qa.longevity.StatusRecorder.Factory.toFile;
-import static brooklyn.qa.longevity.StatusRecorder.Factory.toLog;
-import static java.util.concurrent.TimeUnit.SECONDS;
-
-import java.io.File;
-import java.io.IOException;
-import java.net.URL;
-import java.util.Collections;
-import java.util.List;
-import java.util.Set;
-import java.util.concurrent.Executors;
-import java.util.concurrent.ScheduledExecutorService;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.atomic.AtomicReference;
-
-import joptsimple.OptionParser;
-import joptsimple.OptionSet;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import brooklyn.util.collections.TimeWindowedList;
-import brooklyn.util.collections.TimestampedValue;
-import brooklyn.util.time.Duration;
-
-import com.google.common.base.Charsets;
-import com.google.common.base.Throwables;
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableMap;
-import com.google.common.collect.ImmutableSet;
-import com.google.common.collect.Lists;
-import com.google.common.collect.Range;
-import com.google.common.io.Files;
-
-public class Monitor {
-
- private static final Logger LOG = LoggerFactory.getLogger(Monitor.class);
-
- private static final int checkPeriodMs = 1000;
-
- private static final OptionParser parser = new OptionParser() {
- {
- acceptsAll(ImmutableList.of("help", "?", "h"), "show help");
- accepts("webUrl", "Web-app url")
- .withRequiredArg().ofType(URL.class);
- accepts("brooklynPid", "Brooklyn pid")
- .withRequiredArg().ofType(Integer.class);
- accepts("logFile", "Brooklyn log file")
- .withRequiredArg().ofType(File.class);
- accepts("logGrep", "Grep in log file (defaults to 'SEVERE|ERROR|WARN|Exception|Error'")
- .withRequiredArg().ofType(String.class);
- accepts("logGrepExclusionsFile", "File of expressions to be ignored in log file")
- .withRequiredArg().ofType(File.class);
- accepts("webProcesses", "Name (for `ps ax | grep` of web-processes")
- .withRequiredArg().ofType(String.class);
- accepts("numWebProcesses", "Number of web-processes expected (e.g. 1 or 1-3)")
- .withRequiredArg().ofType(String.class);
- accepts("webProcessesCyclingPeriod", "The period (in seconds) for cycling through the range of numWebProcesses")
- .withRequiredArg().ofType(Integer.class);
- accepts("outFile", "File to write monitor status info")
- .withRequiredArg().ofType(File.class);
- accepts("abortOnError", "Exit the JVM on error, with exit code 1")
- .withRequiredArg().ofType(Boolean.class);
- }
- };
-
- public static void main(String[] argv) throws InterruptedException, IOException {
- OptionSet options = parse(argv);
-
- if (options == null || options.has("help")) {
- parser.printHelpOn(System.out);
- System.exit(0);
- }
-
- MonitorPrefs prefs = new MonitorPrefs();
- prefs.webUrl = options.hasArgument("webUrl") ? (URL) options.valueOf("webUrl") : null;
- prefs.brooklynPid = options.hasArgument("brooklynPid") ? (Integer) options.valueOf("brooklynPid") : -1;
- prefs.logFile = options.hasArgument("logFile") ? (File) options.valueOf("logFile") : null;
- prefs.logGrep = options.hasArgument("logGrep") ? (String) options.valueOf("logGrep") : "SEVERE|ERROR|WARN|Exception|Error";
- prefs.logGrepExclusionsFile = options.hasArgument("logGrepExclusionsFile") ? (File) options.valueOf("logGrepExclusionsFile") : null;
- prefs.webProcessesRegex = options.hasArgument("webProcesses") ? (String) options.valueOf("webProcesses") : null;
- prefs.numWebProcesses = options.hasArgument("numWebProcesses") ? parseRange((String) options.valueOf("numWebProcesses")) : null;
- prefs.webProcessesCyclingPeriod = options.hasArgument("webProcessesCyclingPeriod") ? (Integer) options.valueOf("webProcessesCyclingPeriod") : -1;
- prefs.outFile = options.hasArgument("outFile") ? (File) options.valueOf("outFile") : null;
- prefs.abortOnError = options.hasArgument("abortOnError") ? (Boolean) options.valueOf("abortOnError") : false;
- Monitor main = new Monitor(prefs, MonitorListener.NOOP);
- main.start();
- }
-
- private static Range<Integer> parseRange(String range) {
- if (range.contains("-")) {
- String[] parts = range.split("-");
- return Range.closed(Integer.parseInt(parts[0]), Integer.parseInt(parts[1]));
- } else {
- return Range.singleton(Integer.parseInt(range));
- }
- }
-
- private static OptionSet parse(String...argv) {
- try {
- return parser.parse(argv);
- } catch (Exception e) {
- System.out.println("Error in parsing options: " + e.getMessage());
- return null;
- }
- }
-
- private final MonitorPrefs prefs;
- private final StatusRecorder recorder;
- private final MonitorListener listener;
-
- public Monitor(MonitorPrefs prefs, MonitorListener listener) {
- this.prefs = prefs;
- this.listener = listener;
- this.recorder = chain(toLog(LOG), (prefs.outFile != null ? toFile(prefs.outFile) : noop()));
- }
-
- private void start() throws IOException {
- LOG.info("Monitoring: "+prefs);
- ScheduledExecutorService executor = Executors.newSingleThreadScheduledExecutor();
-
- final AtomicReference<List<String>> previousLogLines = new AtomicReference<List<String>>(Collections.<String>emptyList());
- final TimeWindowedList<Integer> numWebProcessesHistory = new TimeWindowedList<Integer>(
- ImmutableMap.of("timePeriod", Duration.seconds(prefs.webProcessesCyclingPeriod), "minExpiredVals", 1));
- final Set<String> logGrepExclusions = ImmutableSet.copyOf(Files.readLines(prefs.logGrepExclusionsFile, Charsets.UTF_8));
-
- executor.scheduleAtFixedRate(new Runnable() {
- @Override public void run() {
- StatusRecorder.Record record = new StatusRecorder.Record();
- StringBuilder failureMsg = new StringBuilder();
- try {
- if (prefs.brooklynPid > 0) {
- boolean pidRunning = MonitorUtils.isPidRunning(prefs.brooklynPid, "java");
- MonitorUtils.MemoryUsage memoryUsage = MonitorUtils.getMemoryUsage(prefs.brooklynPid, ".*brooklyn.*", 1000);
- record.put("pidRunning", pidRunning);
- record.put("totalMemoryBytes", memoryUsage.getTotalMemoryBytes());
- record.put("totalMemoryInstances", memoryUsage.getTotalInstances());
- record.put("instanceCounts", memoryUsage.getInstanceCounts());
-
- if (!pidRunning) {
- failureMsg.append("pid "+prefs.brooklynPid+" is not running"+"\n");
- }
- }
- if (prefs.webUrl != null) {
- boolean webUrlUp = MonitorUtils.isUrlUp(prefs.webUrl);
- record.put("webUrlUp", webUrlUp);
-
- if (!webUrlUp) {
- failureMsg.append("web URL "+prefs.webUrl+" is not available"+"\n");
- }
- }
- if (prefs.logFile != null) {
- List<String> logLines = MonitorUtils.searchLog(prefs.logFile, prefs.logGrep, logGrepExclusions);
- List<String> newLogLines = getAdditions(previousLogLines.get(), logLines);
- previousLogLines.set(logLines);
- record.put("logLines", newLogLines);
-
- if (newLogLines.size() > 0) {
- failureMsg.append("Log contains warnings/errors: "+newLogLines+"\n");
- }
- }
- if (prefs.webProcessesRegex != null) {
- List<Integer> pids = MonitorUtils.getRunningPids(prefs.webProcessesRegex, "--webProcesses");
- pids.remove((Object)MonitorUtils.findOwnPid());
-
- record.put("webPids", pids);
- record.put("numWebPids", pids.size());
- numWebProcessesHistory.add(pids.size());
-
- if (prefs.numWebProcesses != null) {
- boolean numWebPidsInRange = prefs.numWebProcesses.apply(pids.size());
- record.put("numWebPidsInRange", numWebPidsInRange);
-
- if (!numWebPidsInRange) {
- failureMsg.append("num web processes out-of-range: pids="+pids+"; size="+pids.size()+"; expected="+prefs.numWebProcesses);
- }
-
- if (prefs.webProcessesCyclingPeriod > 0) {
- List<TimestampedValue<Integer>> values = numWebProcessesHistory.getValues();
- long valuesTimeRange = (values.get(values.size()-1).getTimestamp() - values.get(0).getTimestamp());
- if (values.size() > 0 && valuesTimeRange > SECONDS.toMillis(prefs.webProcessesCyclingPeriod)) {
- int min = -1;
- int max = -1;
- for (TimestampedValue<Integer> val : values) {
- min = (min < 0) ? val.getValue() : Math.min(val.getValue(), min);
- max = Math.max(val.getValue(), max);
- }
- record.put("minWebSizeInPeriod", min);
- record.put("maxWebSizeInPeriod", max);
-
- if (min > prefs.numWebProcesses.lowerEndpoint() || max < prefs.numWebProcesses.upperEndpoint()) {
- failureMsg.append("num web processes not increasing/decreasing correctly: " +
- "pids="+pids+"; size="+pids.size()+"; cyclePeriod="+prefs.webProcessesCyclingPeriod+
- "; expectedRange="+prefs.numWebProcesses+"; min="+min+"; max="+max+"; history="+values);
- }
- } else {
- int numVals = values.size();
- long startTime = (numVals > 0) ? values.get(0).getTimestamp() : 0;
- long endTime = (numVals > 0) ? values.get(values.size()-1).getTimestamp() : 0;
- LOG.info("Insufficient vals in time-window to determine cycling behaviour over period ("+prefs.webProcessesCyclingPeriod+"secs): "+
- "numVals="+numVals+"; startTime="+startTime+"; endTime="+endTime+"; periodCovered="+(endTime-startTime)/1000);
- }
- }
- }
- }
-
- } catch (Throwable t) {
- LOG.error("Error during periodic checks", t);
- throw Throwables.propagate(t);
- }
-
- try {
- recorder.record(record);
- listener.onRecord(record);
-
- if (failureMsg.length() > 0) {
- listener.onFailure(record, failureMsg.toString());
-
- if (prefs.abortOnError) {
- LOG.error("Aborting on error: "+failureMsg);
- System.exit(1);
- }
- }
-
- } catch (Throwable t) {
- LOG.warn("Error recording monitor info ("+record+")", t);
- throw Throwables.propagate(t);
- }
- }
- }, 0, checkPeriodMs, TimeUnit.MILLISECONDS);
- }
-
- // TODO What is the guava equivalent? Don't want Set.difference, because duplicates/ordered.
- private static List<String> getAdditions(List<String> prev, List<String> next) {
- List<String> result = Lists.newArrayList(next);
- result.removeAll(prev);
- return result;
- }
-}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/bd44bb8f/usage/qa/src/main/java/brooklyn/qa/longevity/MonitorListener.java
----------------------------------------------------------------------
diff --git a/usage/qa/src/main/java/brooklyn/qa/longevity/MonitorListener.java b/usage/qa/src/main/java/brooklyn/qa/longevity/MonitorListener.java
deleted file mode 100644
index b0a0678..0000000
--- a/usage/qa/src/main/java/brooklyn/qa/longevity/MonitorListener.java
+++ /dev/null
@@ -1,35 +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.qa.longevity;
-
-import brooklyn.qa.longevity.StatusRecorder.Record;
-
-public interface MonitorListener {
-
- public static final MonitorListener NOOP = new MonitorListener() {
- @Override public void onRecord(Record record) {
- }
- @Override public void onFailure(Record record, String msg) {
- }
- };
-
- public void onRecord(Record record);
-
- public void onFailure(Record record, String msg);
-}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/bd44bb8f/usage/qa/src/main/java/brooklyn/qa/longevity/MonitorPrefs.java
----------------------------------------------------------------------
diff --git a/usage/qa/src/main/java/brooklyn/qa/longevity/MonitorPrefs.java b/usage/qa/src/main/java/brooklyn/qa/longevity/MonitorPrefs.java
deleted file mode 100644
index 3883e93..0000000
--- a/usage/qa/src/main/java/brooklyn/qa/longevity/MonitorPrefs.java
+++ /dev/null
@@ -1,54 +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.qa.longevity;
-
-import java.io.File;
-import java.net.URL;
-
-import com.google.common.base.Objects;
-import com.google.common.collect.Range;
-
-public class MonitorPrefs {
-
- public URL webUrl;
- public int brooklynPid;
- public File logFile;
- public String logGrep;
- public File logGrepExclusionsFile;
- public String webProcessesRegex;
- public Range<Integer> numWebProcesses;
- public int webProcessesCyclingPeriod;
- public File outFile;
- public boolean abortOnError;
-
- @Override
- public String toString() {
- return Objects.toStringHelper(this)
- .add("webUrl", webUrl)
- .add("brooklynPid", brooklynPid)
- .add("logFile", logFile)
- .add("logGrep", logGrep)
- .add("logGrepExclusionsFile", logGrepExclusionsFile)
- .add("outFile", outFile)
- .add("webProcessesRegex", webProcessesRegex)
- .add("numWebProcesses", numWebProcesses)
- .add("webProcessesCyclingPeriod", webProcessesCyclingPeriod)
- .toString();
- }
-}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/bd44bb8f/usage/qa/src/main/java/brooklyn/qa/longevity/MonitorUtils.java
----------------------------------------------------------------------
diff --git a/usage/qa/src/main/java/brooklyn/qa/longevity/MonitorUtils.java b/usage/qa/src/main/java/brooklyn/qa/longevity/MonitorUtils.java
deleted file mode 100644
index 290a555..0000000
--- a/usage/qa/src/main/java/brooklyn/qa/longevity/MonitorUtils.java
+++ /dev/null
@@ -1,329 +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.qa.longevity;
-
-import static com.google.common.base.Strings.isNullOrEmpty;
-
-import java.io.ByteArrayOutputStream;
-import java.io.File;
-import java.io.IOException;
-import java.io.InputStream;
-import java.net.URI;
-import java.net.URL;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.LinkedHashSet;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.regex.Pattern;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import brooklyn.util.http.HttpTool;
-import brooklyn.util.http.HttpToolResponse;
-import brooklyn.util.stream.StreamGobbler;
-
-import com.google.common.base.Objects;
-import com.google.common.base.Throwables;
-import com.google.common.collect.ImmutableMap;
-import com.google.common.collect.Maps;
-import com.google.common.io.ByteStreams;
-
-public class MonitorUtils {
-
- private static final Logger LOG = LoggerFactory.getLogger(MonitorUtils.class);
-
- private static volatile int ownPid = -1;
-
- /**
- * Confirm can read from URL.
- *
- * @param url
- */
- public static boolean isUrlUp(URL url) {
- try {
- HttpToolResponse result = HttpTool.httpGet(
- HttpTool.httpClientBuilder().trustAll().build(),
- URI.create(url.toString()),
- ImmutableMap.<String,String>of());
- int statuscode = result.getResponseCode();
-
- if (statuscode != 200) {
- LOG.info("Error reading URL {}: {}, {}", new Object[]{url, statuscode, result.getReasonPhrase()});
- return false;
- } else {
- return true;
- }
- } catch (Exception e) {
- LOG.info("Error reading URL {}: {}", url, e);
- return false;
- }
- }
-
- public static boolean isPidRunning(int pid) {
- return isPidRunning(pid, null);
- }
-
- /**
- * Confirm the given pid is running, and that the the process matches the given regex.
- *
- * @param pid
- * @param regex
- */
- public static boolean isPidRunning(int pid, String regex) {
- Process process = exec("ps -p " + pid);
- String out = waitFor(process);
- if (process.exitValue() > 0) {
- String err = toString(process.getErrorStream());
- LOG.info(String.format("pid %s not running: %s", pid, err));
- return false;
- }
-
- if (regex != null) {
- String regex2 = "^\\s*" + pid + ".*" + regex;
- boolean found = false;
- for (String line : out.split("\n")) {
- if (hasAtLeastOneMatch(line, regex2)) {
- found = true;
- break;
- }
- }
-
- if (!found) {
- String txt = toString(process.getInputStream());
- LOG.info("process did not match regular expression: "+txt);
- return false;
- }
- }
-
- return true;
- }
-
- private static boolean hasAtLeastOneMatch(String line, String regex) {
- return Pattern.matches(".*"+regex+".*", line);
- }
-
- private static String toString(InputStream in){
- try {
- byte[] bytes = ByteStreams.toByteArray(in);
- return new String(bytes);
- } catch (IOException e) {
- throw Throwables.propagate(e);
- }
-
- }
-
- public static List<Integer> getRunningPids(String regex) {
- return getRunningPids(regex, null);
- }
-
- /**
- * Confirm the given pid is running, and that the the process matches the given regex.
- *
- * @param regex
- * @param excludingRegex
- */
- public static List<Integer> getRunningPids(String regex, String excludingRegex) {
- Process process = exec("ps ax");
- String out = waitFor(process);
-
- List<Integer> result = new LinkedList<Integer>();
- for (String line : out.split("\n")) {
- if (excludingRegex != null && hasAtLeastOneMatch(line, excludingRegex)) {
- continue;
- }
- if (hasAtLeastOneMatch(line, regex)) {
- String[] linesplit = line.trim().split("\\s+");
- result.add(Integer.parseInt(linesplit[0]));
- }
- }
- return result;
- }
-
- public static MemoryUsage getMemoryUsage(int pid){
- return getMemoryUsage(pid, null,0);
- }
-
- /**
- * @param pid
- */
- public static MemoryUsage getMemoryUsage(int pid, String clazzRegexOfInterest, int minInstancesOfInterest) {
- Process process = exec(String.format("jmap -histo %s", pid));
- String out = waitFor(process);
-
- Map<String, Integer> instanceCounts = Maps.newLinkedHashMap();
- long totalInstances=0;
- long totalMemoryBytes=0;
-
- for (String line : out.split("\n")) {
- if (clazzRegexOfInterest!=null && hasAtLeastOneMatch(line, clazzRegexOfInterest)) {
- // Format is:
- // num #instances #bytes class name
- // 1: 43506 8047096 example.MyClazz
-
- String[] parts = line.trim().split("\\s+");
- String clazz = parts[3];
- int instanceCount = Integer.parseInt(parts[1]);
- if (instanceCount >= minInstancesOfInterest) {
- instanceCounts.put(clazz, instanceCount);
- }
- }
- if (hasAtLeastOneMatch(line, "^Total.*")) {
- String[] parts = line.split("\\s+");
- totalInstances = Long.parseLong(parts[1]);
- totalMemoryBytes = Long.parseLong(parts[2]);
- }
- }
-
- return new MemoryUsage(totalInstances, totalMemoryBytes, instanceCounts);
- }
-
- public static class MemoryUsage {
- final long totalInstances;
- final long totalMemoryBytes;
- final Map<String, Integer> instanceCounts;
-
- MemoryUsage(long totalInstances, long totalMemoryBytes, Map<String, Integer> instanceCounts) {
- this.totalInstances = totalInstances;
- this.totalMemoryBytes = totalMemoryBytes;
- this.instanceCounts = instanceCounts;
- }
-
- public String toString() {
- return Objects.toStringHelper(this)
- .add("totalInstances", totalInstances)
- .add("totalMemoryBytes", totalMemoryBytes)
- .add("instanceCounts", instanceCounts)
- .toString();
- }
-
- public long getTotalInstances() {
- return totalInstances;
- }
-
- public long getTotalMemoryBytes() {
- return totalMemoryBytes;
- }
-
- public Map<String, Integer> getInstanceCounts() {
- return instanceCounts;
- }
- }
-
- public static List<String> searchLog(File file, String grepOfInterest) {
- return searchLog(file, grepOfInterest, new LinkedHashSet<String>());
- }
-
- /**
- * Find lines in the given file that match given given regex.
- *
- * @param file
- * @param grepOfInterest
- */
- public static List<String> searchLog(File file, String grepOfInterest, Set<String> grepExclusions) {
- Process process = exec(String.format("grep -E %s %s", grepOfInterest, file.getAbsoluteFile()));
- String out = waitFor(process);
-
- // TODO Annoying that String.split() returns size 1 when empty string; lookup javadoc when back online...
- if (out.length() == 0) return Collections.<String>emptyList();
-
- List<String> result = new ArrayList<String>();
- for (String line : out.trim().split("\n")) {
- boolean excluded = false;
- for (String exclusion : grepExclusions) {
- if (!isNullOrEmpty(exclusion) && hasAtLeastOneMatch(line, exclusion)) {
- excluded = true;
- }
- }
- if (!excluded) {
- result.add(line);
- }
- }
- return result;
- }
-
- public static Process exec(String cmd) {
- LOG.info("executing cmd: " + cmd);
-
- try {
- return Runtime.getRuntime().exec(cmd);
- } catch (IOException e) {
- throw Throwables.propagate(e);
- }
- }
-
- public static class ProcessHasStderr extends IllegalStateException {
- private static final long serialVersionUID = -937871002993888405L;
-
- byte[] stderrBytes;
- public ProcessHasStderr(byte[] stderrBytes) {
- this("Process printed to stderr: " + new String(stderrBytes), stderrBytes);
- }
- public ProcessHasStderr(String message, byte[] stderrBytes) {
- super(message);
- this.stderrBytes = stderrBytes;
- }
- }
-
- /**
- * Waits for the given process to complete, consuming its stdout and returning it as a string.
- * If there is any output on stderr an exception will be thrown.
- */
- public static String waitFor(Process process) {
- ByteArrayOutputStream bytesOut = new ByteArrayOutputStream();
- @SuppressWarnings("resource") //Closeable doesn't seem appropriate for StreamGobbler since it isn't expected to be called every time
- StreamGobbler gobblerOut = new StreamGobbler(process.getInputStream(), bytesOut, null);
- gobblerOut.start();
-
- ByteArrayOutputStream bytesErr = new ByteArrayOutputStream();
- @SuppressWarnings("resource")
- StreamGobbler gobblerErr = new StreamGobbler(process.getErrorStream(), bytesErr, null);
- gobblerErr.start();
-
- try {
- process.waitFor();
- gobblerOut.blockUntilFinished();
- gobblerErr.blockUntilFinished();
-
- if (bytesErr.size() > 0) {
- throw new ProcessHasStderr(bytesErr.toByteArray());
- }
-
- return new String(bytesOut.toByteArray());
- } catch (Exception e) {
- throw Throwables.propagate(e);
- } finally {
- if (gobblerOut.isAlive()) gobblerOut.interrupt();
- if (gobblerErr.isAlive()) gobblerErr.interrupt();
- }
- }
-
- public static int findOwnPid() throws IOException {
- if (ownPid >= 0) return ownPid;
-
- String[] cmd = new String[]{"bash", "-c", "echo $PPID"};
- Process process = Runtime.getRuntime().exec(cmd);
- String out = MonitorUtils.waitFor(process);
- ownPid = Integer.parseInt(out.trim());
- return ownPid;
- }
-}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/bd44bb8f/usage/qa/src/main/java/brooklyn/qa/longevity/StatusRecorder.java
----------------------------------------------------------------------
diff --git a/usage/qa/src/main/java/brooklyn/qa/longevity/StatusRecorder.java b/usage/qa/src/main/java/brooklyn/qa/longevity/StatusRecorder.java
deleted file mode 100644
index 5664a2d..0000000
--- a/usage/qa/src/main/java/brooklyn/qa/longevity/StatusRecorder.java
+++ /dev/null
@@ -1,130 +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.qa.longevity;
-
-import java.io.File;
-import java.io.IOException;
-import java.util.Map;
-
-import org.slf4j.Logger;
-
-import com.google.common.base.Charsets;
-import com.google.common.collect.Maps;
-import com.google.common.io.Files;
-
-public interface StatusRecorder {
-
- public void record(Record record) throws IOException;
-
- public static class Factory {
- public static final StatusRecorder NOOP = new StatusRecorder() {
- @Override public void record(Record record) {}
- };
-
- public static StatusRecorder noop() {
- return NOOP;
- }
- public static StatusRecorder toFile(File outFile) {
- return new FileBasedStatusRecorder(outFile);
- }
- public static StatusRecorder toSysout() {
- return new SysoutBasedStatusRecorder();
- }
- public static StatusRecorder toLog(Logger log) {
- return new LogBasedStatusRecorder(log);
- }
- public static StatusRecorder chain(StatusRecorder...recorders) {
- return new ChainingStatusRecorder(recorders);
- }
- }
-
- public static class Record {
- private final Map<String,Object> fields = Maps.newLinkedHashMap();
-
- public void putAll(Map<String,?> entries) {
- fields.putAll(entries);
- }
-
- public void putAll(String keyPrefix, Map<String,?> entries) {
- for (Map.Entry<String,?> entry : entries.entrySet()) {
- fields.put(keyPrefix+entry.getKey(), entry.getValue());
- }
- }
-
- public void put(String key, Object val) {
- fields.put(key, val);
- }
-
- @Override
- public String toString() {
- return fields.toString();
- }
- }
-
- public static class FileBasedStatusRecorder implements StatusRecorder {
- private final File outFile;
-
- public FileBasedStatusRecorder(File outFile) {
- this.outFile = outFile;
- }
-
- @Override
- public void record(Record record) throws IOException {
- Files.append(record.fields.toString()+"\n", outFile, Charsets.UTF_8);
- }
- }
-
- public static class SysoutBasedStatusRecorder implements StatusRecorder {
- public SysoutBasedStatusRecorder() {
- }
-
- @Override
- public void record(Record record) {
- System.out.println(record.fields);
- }
- }
-
- public static class LogBasedStatusRecorder implements StatusRecorder {
- private final Logger log;
-
- public LogBasedStatusRecorder(Logger log) {
- this.log = log;
- }
-
- @Override
- public void record(Record record) {
- log.info("{}", record.fields);
- }
- }
-
- public static class ChainingStatusRecorder implements StatusRecorder {
- private final StatusRecorder[] recorders;
-
- public ChainingStatusRecorder(StatusRecorder... recorders) {
- this.recorders = recorders;
- }
-
- @Override
- public void record(Record record) throws IOException {
- for (StatusRecorder recorder : recorders) {
- recorder.record(record);
- }
- }
- }
-}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/bd44bb8f/usage/qa/src/main/java/org/apache/brooklyn/qa/load/SimulatedJBoss7ServerImpl.java
----------------------------------------------------------------------
diff --git a/usage/qa/src/main/java/org/apache/brooklyn/qa/load/SimulatedJBoss7ServerImpl.java b/usage/qa/src/main/java/org/apache/brooklyn/qa/load/SimulatedJBoss7ServerImpl.java
new file mode 100644
index 0000000..762c17b
--- /dev/null
+++ b/usage/qa/src/main/java/org/apache/brooklyn/qa/load/SimulatedJBoss7ServerImpl.java
@@ -0,0 +1,240 @@
+/*
+ * 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.qa.load;
+
+import static java.lang.String.format;
+
+import java.util.concurrent.Callable;
+
+import brooklyn.config.ConfigKey;
+import brooklyn.enricher.Enrichers;
+import brooklyn.entity.basic.Attributes;
+import brooklyn.entity.webapp.jboss.JBoss7ServerImpl;
+import brooklyn.entity.webapp.jboss.JBoss7SshDriver;
+import brooklyn.event.feed.function.FunctionFeed;
+import brooklyn.event.feed.function.FunctionPollConfig;
+import brooklyn.event.feed.http.HttpFeed;
+import brooklyn.event.feed.http.HttpPollConfig;
+import brooklyn.event.feed.http.HttpValueFunctions;
+import brooklyn.location.access.BrooklynAccessUtils;
+import brooklyn.location.basic.SshMachineLocation;
+import brooklyn.util.collections.MutableMap;
+import brooklyn.util.guava.Functionals;
+import brooklyn.util.os.Os;
+
+import com.google.common.net.HostAndPort;
+
+/**
+ * For simulating various aspects of the JBoss 7 app-server entity.
+ *
+ * The use-case for this is that the desired configuration is not always available for testing.
+ * For example, there may be insufficient resources to run 100s of JBoss app-servers, or one
+ * may be experimenting with possible configurations such as use of an external monitoring tool
+ * that is not yet available.
+ *
+ * It is then possible to simulate aspects of the behaviour, for performance and load testing purposes.
+ *
+ * There is configuration for:
+ * <ul>
+ * <li>{@code simulateEntity}
+ * <ul>
+ * <li>if true, no underlying entity will be started. Instead a sleep 100000 job will be run and monitored.
+ * <li>if false, the underlying entity (i.e. a JBoss app-server) will be started as normal.
+ * </ul>
+ * <li>{@code simulateExternalMonitoring}
+ * <ul>
+ * <li>if true, disables the default monitoring mechanism. Instead, a function will periodically execute
+ * to set the entity's sensors (as though the values had been obtained from the external monitoring tool).
+ * <li>if false, then:
+ * <ul>
+ * <li>If {@code simulateEntity==true} it will execute comparable commands (e.g. execute a command of the same
+ * size over ssh or do a comparable number of http GET requests).
+ * <li>If {@code simulateEntity==false} then normal monitoring will be done.
+ * </ul>
+ * </ul>
+ * <li>{@code skipSshOnStart}
+ * <ul>
+ * <li>If true (and if {@code simulateEntity==true}), then no ssh commands will be executed at deploy-time.
+ * This is useful for speeding up load testing, to get to the desired number of entities.
+ * Should not be set to {@code true} if {@code simulateEntity==false}.
+ * <li>If false, the ssh commands will be executed (based on the value of {@code simulateEntity}.
+ * </ul>
+ * </ul>
+ */
+public class SimulatedJBoss7ServerImpl extends JBoss7ServerImpl {
+
+ public static final ConfigKey<Boolean> SIMULATE_ENTITY = SimulatedTheeTierApp.SIMULATE_ENTITY;
+ public static final ConfigKey<Boolean> SIMULATE_EXTERNAL_MONITORING = SimulatedTheeTierApp.SIMULATE_EXTERNAL_MONITORING;
+ public static final ConfigKey<Boolean> SKIP_SSH_ON_START = SimulatedTheeTierApp.SKIP_SSH_ON_START;
+
+ private HttpFeed httpFeed;
+ private FunctionFeed functionFeed;
+
+ @Override
+ public Class<?> getDriverInterface() {
+ return SimulatedJBoss7SshDriver.class;
+ }
+
+ @Override
+ protected void connectSensors() {
+ boolean simulateEntity = getConfig(SIMULATE_ENTITY);
+ boolean simulateExternalMonitoring = getConfig(SIMULATE_EXTERNAL_MONITORING);
+
+ if (!simulateEntity && !simulateExternalMonitoring) {
+ super.connectSensors();
+ return;
+ }
+
+ HostAndPort hp = BrooklynAccessUtils.getBrooklynAccessibleAddress(this,
+ getAttribute(MANAGEMENT_HTTP_PORT) + getConfig(PORT_INCREMENT));
+
+ String managementUri = String.format("http://%s:%s/management/subsystem/web/connector/http/read-resource",
+ hp.getHostText(), hp.getPort());
+ setAttribute(MANAGEMENT_URL, managementUri);
+
+ if (simulateExternalMonitoring) {
+ // TODO What would set this normally, if not doing connectServiceUpIsRunning?
+ setAttribute(SERVICE_PROCESS_IS_RUNNING, true);
+ } else {
+ // if simulating entity, then simulate work of periodic HTTP request; TODO but not parsing JSON response
+ String uriToPoll = (simulateEntity) ? "http://localhost:8081" : managementUri;
+
+ httpFeed = HttpFeed.builder()
+ .entity(this)
+ .period(200)
+ .baseUri(uriToPoll)
+ .credentials(getConfig(MANAGEMENT_USER), getConfig(MANAGEMENT_PASSWORD))
+ .poll(new HttpPollConfig<Integer>(MANAGEMENT_STATUS)
+ .onSuccess(HttpValueFunctions.responseCode()))
+ .build();
+
+ // Polls over ssh for whether process is running
+ connectServiceUpIsRunning();
+ }
+
+ functionFeed = FunctionFeed.builder()
+ .entity(this)
+ .period(5000)
+ .poll(new FunctionPollConfig<Boolean,Boolean>(MANAGEMENT_URL_UP)
+ .callable(new Callable<Boolean>() {
+ private int counter = 0;
+ public Boolean call() {
+ setAttribute(REQUEST_COUNT, (counter++ % 100));
+ setAttribute(ERROR_COUNT, (counter++ % 100));
+ setAttribute(TOTAL_PROCESSING_TIME, (counter++ % 100));
+ setAttribute(MAX_PROCESSING_TIME, (counter++ % 100));
+ setAttribute(BYTES_RECEIVED, (long) (counter++ % 100));
+ setAttribute(BYTES_SENT, (long) (counter++ % 100));
+ return true;
+ }}))
+ .build();
+
+ addEnricher(Enrichers.builder().updatingMap(Attributes.SERVICE_NOT_UP_INDICATORS)
+ .from(MANAGEMENT_URL_UP)
+ .computing(Functionals.ifNotEquals(true).value("Management URL not reachable") )
+ .build());
+ }
+
+ @Override
+ protected void disconnectSensors() {
+ super.disconnectSensors();
+ if (httpFeed != null) httpFeed.stop();
+ if (functionFeed != null) functionFeed.stop();
+ }
+
+ public static class SimulatedJBoss7SshDriver extends JBoss7SshDriver {
+ public SimulatedJBoss7SshDriver(SimulatedJBoss7ServerImpl entity, SshMachineLocation machine) {
+ super(entity, machine);
+ }
+
+ @Override
+ public boolean isRunning() {
+ if (entity.getConfig(SKIP_SSH_ON_START)) {
+ return true;
+ } else {
+ return super.isRunning();
+ }
+ }
+
+ @Override
+ public void install() {
+ if (entity.getConfig(SKIP_SSH_ON_START)) {
+ // no-op
+ } else {
+ super.install();
+ }
+ }
+
+ @Override
+ public void customize() {
+ if (entity.getConfig(SKIP_SSH_ON_START)) {
+ // no-op
+ } else {
+ super.customize();
+ }
+ }
+
+ @Override
+ public void launch() {
+ if (!entity.getConfig(SIMULATE_ENTITY)) {
+ super.launch();
+ return;
+ }
+
+ // We wait for evidence of JBoss running because, using
+ // brooklyn.ssh.config.tool.class=brooklyn.util.internal.ssh.cli.SshCliTool,
+ // we saw the ssh session return before the JBoss process was fully running
+ // so the process failed to start.
+ String pidFile = Os.mergePathsUnix(getRunDir(), PID_FILENAME);
+
+ if (entity.getConfig(SKIP_SSH_ON_START)) {
+ // minimal ssh, so that isRunning will subsequently work
+ newScript(MutableMap.of("usePidFile", pidFile), LAUNCHING)
+ .body.append(
+ format("nohup sleep 100000 > %s/console 2>&1 < /dev/null &", getRunDir()))
+ .execute();
+ } else {
+ newScript(MutableMap.of(USE_PID_FILE, false), LAUNCHING)
+ .body.append(
+ "export LAUNCH_JBOSS_IN_BACKGROUND=true",
+ format("export JBOSS_HOME=%s", getExpandedInstallDir()),
+ format("export JBOSS_PIDFILE=%s/%s", getRunDir(), PID_FILENAME),
+ format("echo skipping exec of %s/bin/%s.sh ", getExpandedInstallDir(), SERVER_TYPE) +
+ format("--server-config %s ", CONFIG_FILE) +
+ format("-Djboss.server.base.dir=%s/%s ", getRunDir(), SERVER_TYPE) +
+ format("\"-Djboss.server.base.url=file://%s/%s\" ", getRunDir(), SERVER_TYPE) +
+ "-Djava.net.preferIPv4Stack=true " +
+ "-Djava.net.preferIPv6Addresses=false " +
+ format(" >> %s/console 2>&1 </dev/null &", getRunDir()),
+ format("nohup sleep 100000 > %s/console 2>&1 < /dev/null &", getRunDir()),
+ format("echo $! > "+pidFile),
+ format("echo starting > %s/console", getRunDir()),
+ "for i in {1..10}\n" +
+ "do\n" +
+ " grep -i 'starting' "+getRunDir()+"/console && exit\n" +
+ " sleep 1\n" +
+ "done\n" +
+ "echo \"Couldn't determine if process is running (console output does not contain 'starting'); continuing but may subsequently fail\""
+
+ )
+ .execute();
+ }
+ }
+ }
+}
[05/12] incubator-brooklyn git commit: brooklyn-qa: add org.apache
package prefix inside hello-world.war
Posted by al...@apache.org.
brooklyn-qa: add org.apache package prefix inside hello-world.war
Project: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/commit/0cdb2ed9
Tree: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/tree/0cdb2ed9
Diff: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/diff/0cdb2ed9
Branch: refs/heads/master
Commit: 0cdb2ed9d511c655f09daa0f72213555bbbe0920
Parents: bd44bb8
Author: Ciprian Ciubotariu <ch...@gmx.net>
Authored: Wed Jul 15 18:46:25 2015 +0300
Committer: Ciprian Ciubotariu <ch...@gmx.net>
Committed: Wed Jul 15 18:47:00 2015 +0300
----------------------------------------------------------------------
usage/qa/src/main/resources/hello-world.war | Bin 14693 -> 15066 bytes
1 file changed, 0 insertions(+), 0 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/0cdb2ed9/usage/qa/src/main/resources/hello-world.war
----------------------------------------------------------------------
diff --git a/usage/qa/src/main/resources/hello-world.war b/usage/qa/src/main/resources/hello-world.war
index c692ca8..0e17460 100644
Binary files a/usage/qa/src/main/resources/hello-world.war and b/usage/qa/src/main/resources/hello-world.war differ