Skip to content

Instantly share code, notes, and snippets.

@aledsage
Last active October 7, 2015 06:48
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save aledsage/3122488 to your computer and use it in GitHub Desktop.
Save aledsage/3122488 to your computer and use it in GitHub Desktop.
Application-author example
// Application authors write an "ApplicationBuilder"...
// The advantage is that it separates the Entity API from this builder API,
// allowing each API to be optimised for the appropriate role (i.e. top-level
// methods for the common operations so they are easy to find and use).
//
// e.g. aim of ApplicationBuilder is to make it easy to create + configure +
// wire together pre-existing types of entity, and to associate policies with them.
// It uses the "Recipes" of these pre-existing entity types to configure them,
// without worrying about how that implementation handles its children etc.
public class WebClusterDatabaseExamplePureJava2 extends ApplicationBuilder {
public static final String WAR_PATH = "classpath://hello-world-sql-webapp.war";
public static final String DB_USERNAME = "brooklyn";
public static final String DB_PASSWORD = "br00k11n";
// e.g. "jdbc:mysql://localhost/visitors?user=brooklyn&password=br00k11n"
public static final String DB_URL_FORMAT = "jdbc:%s/visitors?user="+DB_USERNAME+"&password="+DB_PASSWORD;
public static final String DB_SETUP_SQL = "create database visitors; blah blah;";
@Override
protected void doBuild() {
displayName("Brooklyn WebApp Cluster with Database example");
MySqlServer mysql = createEntity(MySqlServer.Recipe().newInstance()
.creationScriptContents(DB_SETUP_SQL));
addChild(mysql);
createChild(new ControlledDynamicWebAppCluster.Recipe()
.controllerRecipe(NginxController.Recipe.newInstance()
.port(8080))
.appServerRecipe(JBoss7Server.Recipe().newInstance()
.httpPort("8000+")
.rootWar(WAR_PATH)
.javaOption("brooklyn.example.db.url", valueWhenAttributeReady(mysql,
MySqlNode.MYSQL_URL, PostProcessors.stringFormat(DB_URL_FORMAT))))
.policy(AutoScalerPolicy.builder()
.trigger(DynamicWebAppCluster.AVERAGE_REQUESTS_PER_SECOND)
.sizeRange(1, 5)
.metricRange(10, 100)
.build()));
// Or could use a generic recipe object if no strongly typed one exists
MySqlNode mysql2 = createChild(new BasicRecipe()
.configure(MySqlNode.CREATION_SCRIPT_CONTENTS, DB_SETUP_SQL)
.configure(ImmutableMap.of("port", 1234)));
}
}
@ahgittin
Copy link

ahgittin commented Jan 8, 2013

is ApplicaitonBuilder worth the weight of an additional concept?

can we make do with just T addChild(Recipe<T>) being in scope on the entity?
(other functions, e.g. createEntity, addChild can be on mgmt context / convenience)

and could we permit these addChild calls to occur in initialization block in the ApplicaitonEntity itself?
(seems like with new Recipe idea we could do this in such a way that rebind works also (ignoring recipes).)

often i have some sensors and effectors in the application, so gets tedious if i need a builder, an interface, an impl, and a recipe!

as an alternative is it worth fleshing out a purely external way of defining apps/entities? as in, you can create them just by using builder methods? or is that too much?

@ahgittin
Copy link

ahgittin commented Jan 8, 2013

Somewhat concerned about the explosion of MyEntity, MyEntity.Recipe, MyEntityImpl (and MyEntityDriver and MyEntityDriverImpl). Really don't like the need for MyEntityBuilder when my entity has children. (Presumably you have ideas on this, just not reflected in the gists.)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment