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 <[email protected]> Authored: Wed Jul 15 18:11:11 2015 +0300 Committer: Ciprian Ciubotariu <[email protected]> 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(); - } -}
